Back to index

lightning-sunbird  0.9+nobinonly
badapter.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Pierre Phaneuf <pp@ludusdesign.com>
00024  *   Rusty Lynch <rusty.lynch@intel.com>
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either the GNU General Public License Version 2 or later (the "GPL"), or
00028  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00041 // Backward Adapter
00042 // This acts as a adapter layer to allow 5.0 plugins work with the 4.0/3.0 
00043 // browser.
00045 
00047 // SECTION 1 - Includes
00049 
00050 // extern "C" {
00051 #include "npapi.h"
00052 // }
00053 #include "nsIPluginManager.h"
00054 #include "nsIServiceManager.h"
00055 #include "nsIAllocator.h"
00056 #include "nsLiveConnect.h"
00057 #include "nsplugin.h"
00058 #include "nsDebug.h"
00059 
00061 // SECTION 3 - Classes
00063 
00065 //
00066 // CPluginManager
00067 //
00068 // This is the dummy plugin manager that interacts with the 5.0 plugin.
00069 //
00070 class CPluginManager : public nsIPluginManager, public nsIServiceManager, public nsIAllocator {
00071 public:
00072        // Need an operator new for this.
00073        void* operator new(size_t size) { return ::NPN_MemAlloc(size); }
00074        void operator delete(void* ptr) { ::NPN_MemFree(ptr); }
00075 
00076     CPluginManager(void);
00077     virtual ~CPluginManager(void);
00078 
00079     NS_DECL_ISUPPORTS
00080 
00082     // from nsIPluginManager:
00083 
00084     // (Corresponds to NPN_GetValue.)
00085     NS_IMETHOD
00086     GetValue(nsPluginManagerVariable variable, void *value);
00087 
00088     // (Corresponds to NPN_SetValue.)
00089     NS_IMETHOD
00090     SetValue(nsPluginManagerVariable variable, void *value);
00091     
00092     NS_IMETHOD
00093     ReloadPlugins(PRBool reloadPages);
00094 
00095     // (Corresponds to NPN_UserAgent.)
00096     NS_IMETHOD
00097     UserAgent(const char* *result);
00098 
00099     NS_IMETHOD
00100     GetURL(nsISupports* pluginInst, 
00101            const char* url, 
00102            const char* target = NULL,
00103            nsIPluginStreamListener* streamListener = NULL,
00104            const char* altHost = NULL,
00105            const char* referrer = NULL,
00106            PRBool forceJSEnabled = PR_FALSE);
00107 
00108     NS_IMETHOD
00109     PostURL(nsISupports* pluginInst,
00110             const char* url,
00111             PRUint32 postDataLen, 
00112             const char* postData,
00113             PRBool isFile = PR_FALSE,
00114             const char* target = NULL,
00115             nsIPluginStreamListener* streamListener = NULL,
00116             const char* altHost = NULL, 
00117             const char* referrer = NULL,
00118             PRBool forceJSEnabled = PR_FALSE,
00119             PRUint32 postHeadersLength = 0, 
00120             const char* postHeaders = NULL);
00121 
00122     NS_IMETHOD
00123     RegisterPlugin(REFNSIID aCID,
00124                    const char* aPluginName,
00125                    const char* aDescription,
00126                    const char** aMimeTypes,
00127                    const char** aMimeDescriptions,
00128                    const char** aFileExtensions,
00129                    PRInt32 aCount);
00130 
00131     NS_IMETHOD
00132     UnregisterPlugin(REFNSIID aCID);
00133 
00134 
00141     NS_IMETHOD
00142     RegisterService(const nsCID& aClass, nsISupports* aService)
00143     {
00144        return NS_ERROR_NOT_IMPLEMENTED;
00145        }
00146 
00157     NS_IMETHOD
00158     UnregisterService(const nsCID& aClass)
00159     {
00160        return NS_ERROR_NOT_IMPLEMENTED;
00161        }
00162 
00163     NS_IMETHOD
00164     GetService(const nsCID& aClass, const nsIID& aIID,
00165                nsISupports* *result,
00166                nsIShutdownListener* shutdownListener = NULL);
00167 
00168     NS_IMETHOD
00169     ReleaseService(const nsCID& aClass, nsISupports* service,
00170                    nsIShutdownListener* shutdownListener = NULL);
00171 
00172     NS_IMETHOD
00173     GetService(const char* aContractID, const nsIID& aIID,
00174                nsISupports* *result,
00175                nsIShutdownListener* shutdownListener = NULL)
00176     {
00177        return NS_ERROR_NOT_IMPLEMENTED;
00178        }
00179 
00180     NS_IMETHOD
00181     ReleaseService(const char* aContractID, nsISupports* service,
00182                    nsIShutdownListener* shutdownListener = NULL)
00183     {
00184        return NS_ERROR_NOT_IMPLEMENTED;
00185        }
00186 
00193     NS_IMETHOD_(void*)
00194     Alloc(PRUint32 size);
00195 
00203     NS_IMETHOD_(void*)
00204     Realloc(void* ptr, PRUint32 size);
00205 
00211     NS_IMETHOD
00212     Free(void* ptr);
00213 
00217     NS_IMETHOD
00218     HeapMinimize(void);
00219 
00220 private:
00221        nsILiveconnect* mLiveconnect;
00222 };
00223 
00225 //
00226 // CPluginManagerStream
00227 //
00228 // This is the dummy plugin manager stream that interacts with the 5.0 plugin.
00229 //
00230 class CPluginManagerStream : public nsIOutputStream {
00231 
00232 public:
00233 
00234     CPluginManagerStream(NPP npp, NPStream* pstr);
00235     virtual ~CPluginManagerStream(void);
00236 
00237     NS_DECL_ISUPPORTS
00238 
00240     //
00241     // Taken from nsIStream
00242     //
00243     
00250     NS_IMETHOD
00251     Write(const char* aBuf, PRUint32 aCount, PRUint32 *aWriteCount); 
00252 
00253     NS_IMETHOD Flush() {
00254         return NS_OK;
00255     }
00256 
00258     //
00259     // Specific methods to nsIPluginManagerStream.
00260     //
00261     
00262     // Corresponds to NPStream's url field.
00263     NS_IMETHOD
00264     GetURL(const char*  *result);
00265 
00266     // Corresponds to NPStream's end field.
00267     NS_IMETHOD
00268     GetEnd(PRUint32 *result);
00269 
00270     // Corresponds to NPStream's lastmodfied field.
00271     NS_IMETHOD
00272     GetLastModified(PRUint32 *result);
00273 
00274     // Corresponds to NPStream's notifyData field.
00275     NS_IMETHOD
00276     GetNotifyData(void*  *result);
00277 
00278     // Corresponds to NPStream's url field.
00279     NS_IMETHOD Close(void);
00280 
00281 protected:
00282 
00283     // npp
00284     // The plugin instance that the manager stream belongs to.
00285     NPP npp;
00286 
00287     // pstream
00288     // The stream the class is using.
00289     NPStream* pstream;
00290 
00291 };
00292 
00294 //
00295 // CPluginInstancePeer
00296 //
00297 // This is the dummy instance peer that interacts with the 5.0 plugin.
00298 // In order to do LiveConnect, the class subclasses nsILiveConnectPluginInstancePeer.
00299 //
00300 class CPluginInstancePeer : public nsIPluginInstancePeer, public nsIPluginTagInfo {
00301 
00302 public:
00303 
00304     // XXX - I add parameters to the constructor because I wasn't sure if
00305     // XXX - the 4.0 browser had the npp_instance struct implemented.
00306     // XXX - If so, then I can access npp_instance through npp->ndata.
00307     CPluginInstancePeer(nsIPluginInstance* pluginInstance, NPP npp, nsMIMEType typeString, nsPluginMode type,
00308         PRUint16 attribute_cnt, const char** attribute_list, const char** values_list);
00309 
00310     virtual ~CPluginInstancePeer(void);
00311 
00312     NS_DECL_ISUPPORTS
00313 
00314     // (Corresponds to NPN_GetValue.)
00315     NS_IMETHOD
00316     GetValue(nsPluginInstancePeerVariable variable, void *value);
00317 
00318     // (Corresponds to NPN_SetValue.)
00319     NS_IMETHOD
00320     SetValue(nsPluginInstancePeerVariable variable, void *value);
00321 
00322     // Corresponds to NPP_New's MIMEType argument.
00323     NS_IMETHOD
00324     GetMIMEType(nsMIMEType *result);
00325 
00326     // Corresponds to NPP_New's mode argument.
00327     NS_IMETHOD
00328     GetMode(nsPluginMode *result);
00329 
00330     // Get a ptr to the paired list of attribute names and values,
00331     // returns the length of the array.
00332     //
00333     // Each name or value is a null-terminated string.
00334     NS_IMETHOD
00335     GetAttributes(PRUint16& n, const char* const*& names, const char* const*& values);
00336 
00337     // Get the value for the named attribute.  Returns null
00338     // if the attribute was not set.
00339     NS_IMETHOD
00340     GetAttribute(const char* name, const char* *result);
00341 
00342     // Corresponds to NPN_NewStream.
00343     NS_IMETHOD
00344     NewStream(nsMIMEType type, const char* target, nsIOutputStream* *result);
00345 
00346     // Corresponds to NPN_ShowStatus.
00347     NS_IMETHOD
00348     ShowStatus(const char* message);
00349 
00350     NS_IMETHOD
00351     SetWindowSize(PRUint32 width, PRUint32 height);
00352 
00353        nsIPluginInstance* GetInstance(void) { return mInstance; }
00354        NPP GetNPPInstance(void) { return npp; }
00355        
00356        void SetWindow(NPWindow* window) { mWindow = window; }
00357        NPWindow* GetWindow() { return mWindow; }
00358        
00359 protected:
00360 
00361     NPP npp;
00362     // XXX - The next five variables may need to be here since I
00363     // XXX - don't think np_instance is available in 4.0X.
00364     nsIPluginInstance* mInstance;
00365     NPWindow* mWindow;
00366     nsMIMEType typeString;
00367        nsPluginMode type;
00368        PRUint16 attribute_cnt;
00369        char** attribute_list;
00370        char** values_list;
00371 };
00372 
00373 class CPluginStreamInfo : public nsIPluginStreamInfo {
00374 public:
00375     NS_DECL_ISUPPORTS
00376 
00377        CPluginStreamInfo(const char* URL, nsIPluginInputStream* inStr, nsMIMEType type, PRBool seekable)
00378                : mURL(URL), mInputStream(inStr), mMimeType(type), mIsSeekable(seekable) {}
00379 
00380        virtual ~CPluginStreamInfo() {}
00381 
00382        NS_METHOD
00383        GetContentType(nsMIMEType* result)
00384        {
00385               *result = mMimeType;
00386               return NS_OK;
00387        }
00388 
00389        NS_METHOD
00390        IsSeekable(PRBool* result)
00391        {
00392               *result = mIsSeekable;
00393               return NS_OK;
00394        }
00395 
00396        NS_METHOD
00397        GetLength(PRUint32* result)
00398        {
00399               return mInputStream->GetLength(result);
00400        }
00401 
00402        NS_METHOD
00403        GetLastModified(PRUint32* result)
00404        {
00405               return mInputStream->GetLastModified(result);
00406        }
00407 
00408        NS_METHOD
00409        GetURL(const char** result)
00410        {
00411               *result = mURL;
00412               return NS_OK;
00413        }
00414 
00415        NS_METHOD
00416        RequestRead(nsByteRange* rangeList)
00417        {
00418               return mInputStream->RequestRead(rangeList);
00419        }
00420 
00421 private:
00422        const char* mURL;
00423        nsIPluginInputStream* mInputStream;
00424        nsMIMEType mMimeType;
00425        PRBool mIsSeekable;
00426 };
00427 
00428 class CPluginInputStream : public nsIPluginInputStream {
00429 public:
00430 
00431     NS_DECL_ISUPPORTS
00432 
00433     NS_DECL_NSIINPUTSTREAM
00434 
00436     // from nsIPluginInputStream:
00437 
00438     // (Corresponds to NPStream's lastmodified field.)
00439     NS_IMETHOD
00440     GetLastModified(PRUint32 *result);
00441 
00442     NS_IMETHOD
00443     RequestRead(nsByteRange* rangeList);
00444 
00446     // CPluginInputStream specific methods:
00447 
00448     CPluginInputStream(nsIPluginStreamListener* listener);
00449     virtual ~CPluginInputStream(void);
00450 
00451     void SetStreamInfo(NPP npp, NPStream* stream) {
00452         mNPP = npp;
00453         mStream = stream;
00454     }
00455 
00456     nsIPluginStreamListener* GetListener(void) { return mListener; }
00457     nsPluginStreamType GetStreamType(void) { return mStreamType; }
00458 
00459     nsresult SetReadBuffer(PRUint32 len, const char* buffer) {
00460         // XXX this has to be way more sophisticated
00461         mBuffer = dup(len, buffer);
00462         mBufferLength = len;
00463         mAmountRead = 0;
00464         return NS_OK;
00465     }
00466     
00467     char* dup(PRUint32 len, const char* buffer) {
00468        char* result = new char[len];
00469        if (result != NULL) {
00470               const char *src = buffer;
00471               char *dest = result; 
00472               while (len-- > 0)
00473                      *dest++ = *src++;
00474        }
00475        return result;
00476     }
00477 
00478        nsIPluginStreamInfo* CreatePluginStreamInfo(const char* url, nsMIMEType type, PRBool seekable) {
00479               if (mStreamInfo == NULL) {
00480                      mStreamInfo = new CPluginStreamInfo(url, this, type, seekable);
00481                      mStreamInfo->AddRef();
00482               }
00483               return mStreamInfo;
00484        }
00485        
00486        nsIPluginStreamInfo* GetPluginStreamInfo() {
00487               return mStreamInfo;
00488        }
00489 
00490 protected:
00491     const char* mURL;
00492     nsIPluginStreamListener* mListener;
00493     nsPluginStreamType mStreamType;
00494     NPP mNPP;
00495     NPStream* mStream;
00496     char* mBuffer;
00497     PRUint32 mBufferLength;
00498     PRUint32 mAmountRead;
00499     nsIPluginStreamInfo* mStreamInfo;
00500 };
00501 
00503 
00504 #ifdef XP_UNIX
00505 #define TRACE(foo) trace(foo)
00506 #endif
00507 
00508 #ifdef XP_MAC
00509 #undef assert
00510 #define assert(cond)
00511 #endif
00512 
00513 #if defined(__cplusplus)
00514 extern "C" {
00515 #endif
00516 
00518 // SECTION 1 - Includes
00520 
00521 #if defined(XP_UNIX) || defined(XP_MAC)
00522 #include <stdio.h>
00523 #include <stdlib.h>
00524 #include <string.h>
00525 #else
00526 #include <windows.h>
00527 #endif
00528 
00530 // SECTION 2 - Global Variables
00532 
00533 //
00534 // thePlugin and thePluginManager are used in the life of the plugin.
00535 //
00536 // These two will be created on NPP_Initialize and destroyed on NPP_Shutdown.
00537 //
00538 nsIPluginManager* thePluginManager = NULL;
00539 nsIPlugin* thePlugin = NULL;
00540 
00541 //
00542 // nsISupports IDs
00543 //
00544 // Interface IDs for nsISupports
00545 //
00546 NS_DEFINE_IID(kPluginCID, NS_PLUGIN_CID);
00547 static NS_DEFINE_IID(kPluginManagerCID, NS_PLUGINMANAGER_CID);
00548 static NS_DEFINE_IID(kAllocatorCID, NS_ALLOCATOR_CID);
00549 
00550 // mapping from NPError to nsresult
00551 nsresult fromNPError[] = {
00552     NS_OK,                          // NPERR_NO_ERROR,
00553     NS_ERROR_FAILURE,               // NPERR_GENERIC_ERROR,
00554     NS_ERROR_FAILURE,               // NPERR_INVALID_INSTANCE_ERROR,
00555     NS_ERROR_NOT_INITIALIZED,       // NPERR_INVALID_FUNCTABLE_ERROR,
00556     NS_ERROR_FACTORY_NOT_LOADED,    // NPERR_MODULE_LOAD_FAILED_ERROR,
00557     NS_ERROR_OUT_OF_MEMORY,         // NPERR_OUT_OF_MEMORY_ERROR,
00558     NS_NOINTERFACE,                 // NPERR_INVALID_PLUGIN_ERROR,
00559     NS_ERROR_ILLEGAL_VALUE,         // NPERR_INVALID_PLUGIN_DIR_ERROR,
00560     NS_NOINTERFACE,                 // NPERR_INCOMPATIBLE_VERSION_ERROR,
00561     NS_ERROR_ILLEGAL_VALUE,         // NPERR_INVALID_PARAM,
00562     NS_ERROR_ILLEGAL_VALUE,         // NPERR_INVALID_URL,
00563     NS_ERROR_ILLEGAL_VALUE,         // NPERR_FILE_NOT_FOUND,
00564     NS_ERROR_FAILURE,               // NPERR_NO_DATA,
00565     NS_ERROR_FAILURE                // NPERR_STREAM_NOT_SEEKABLE,
00566 };
00567 
00569 // SECTION 4 - API Shim Plugin Implementations
00570 // Glue code to the 5.0x Plugin.
00571 //
00572 // Most of the NPP_* functions that interact with the plug-in will need to get 
00573 // the instance peer from npp->pdata so it can get the plugin instance from the
00574 // peer. Once the plugin instance is available, the appropriate 5.0 plug-in
00575 // function can be called:
00576 //          
00577 //  CPluginInstancePeer* peer = (CPluginInstancePeer* )instance->pdata;
00578 //  nsIPluginInstance* inst = peer->GetUserInstance();
00579 //  inst->NewPluginAPIFunction();
00580 //
00581 // Similar steps takes place with streams.  The stream peer is stored in NPStream's
00582 // pdata.  Get the peer, get the stream, call the function.
00583 //
00584 
00586 // UNIX-only API calls
00588 
00589 #ifdef XP_UNIX
00590 char* NPP_GetMIMEDescription(void)
00591 {
00592     int freeFac = 0;
00593     //fprintf(stderr, "MIME description\n");
00594     if (thePlugin == NULL) {
00595         freeFac = 1;
00596         NSGetFactory(thePluginManager, kPluginCID, NULL, NULL, (nsIFactory** )&thePlugin);
00597     }
00598     //fprintf(stderr, "Allocated Plugin 0x%08x\n", thePlugin);
00599     const char * ret;
00600     nsresult err = thePlugin->GetMIMEDescription(&ret);
00601     if (err) return NULL;
00602     //fprintf(stderr, "Get response %s\n", ret);
00603     if (freeFac) {
00604         //fprintf(stderr, "Freeing plugin...");
00605         thePlugin->Release();
00606         thePlugin = NULL;
00607     }
00608     //fprintf(stderr, "Done\n");
00609     return (char*)ret;
00610 }
00611 
00612 
00613 //------------------------------------------------------------------------------
00614 // Cross-Platform Plug-in API Calls
00615 //------------------------------------------------------------------------------
00616 
00617 //+++++++++++++++++++++++++++++++++++++++++++++++++
00618 // NPP_SetValue:
00619 //+++++++++++++++++++++++++++++++++++++++++++++++++
00620 
00621 NPError
00622 NPP_SetValue(NPP instance, NPNVariable variable, void *value)
00623 {
00624     return NPERR_GENERIC_ERROR; // nothing to set
00625 }
00626 
00627 //+++++++++++++++++++++++++++++++++++++++++++++++++
00628 // NPP_GetValue:
00629 //+++++++++++++++++++++++++++++++++++++++++++++++++
00630 
00631 NPError
00632 NPP_GetValue(NPP instance, NPPVariable variable, void *value) {
00633     int freeFac = 0;
00634     //fprintf(stderr, "MIME description\n");
00635     if (thePlugin == NULL) {
00636         freeFac = 1;
00637         if (NSGetFactory(thePluginManager, kPluginCID, NULL, NULL, (nsIFactory** )&thePlugin) != NS_OK)
00638             return NPERR_GENERIC_ERROR;
00639     }
00640     //fprintf(stderr, "Allocated Plugin 0x%08x\n", thePlugin);
00641     nsresult err = thePlugin->GetValue((nsPluginVariable)variable, value);
00642     if (err) return NPERR_GENERIC_ERROR;
00643     //fprintf(stderr, "Get response %08x\n", ret);
00644     if (freeFac) {
00645         //fprintf(stderr, "Freeing plugin...");
00646         thePlugin->Release();
00647         thePlugin = NULL;
00648     }
00649     //fprintf(stderr, "Done\n");
00650     return NPERR_NO_ERROR;
00651 }
00652 #endif // XP_UNIX
00653 
00654 //+++++++++++++++++++++++++++++++++++++++++++++++++
00655 // NPP_Initialize:
00656 // Provides global initialization for a plug-in, and returns an error value. 
00657 //
00658 // This function is called once when a plug-in is loaded, before the first instance
00659 // is created. thePluginManager and thePlugin are both initialized.
00660 //+++++++++++++++++++++++++++++++++++++++++++++++++
00661 
00662 NPError
00663 NPP_Initialize(void)
00664 {
00665 //    TRACE("NPP_Initialize\n");
00666 
00667     // Only call initialize the plugin if it hasn't been created.
00668     // This could happen if GetJavaClass() is called before
00669     // NPP Initialize.  
00670     if (thePluginManager == NULL) {
00671         // Create the plugin manager and plugin classes.
00672         thePluginManager = new CPluginManager(); 
00673         if ( thePluginManager == NULL ) 
00674             return NPERR_OUT_OF_MEMORY_ERROR;  
00675         thePluginManager->AddRef();
00676     }
00677     nsresult error = NS_OK;  
00678     // On UNIX the plugin might have been created when calling NPP_GetMIMEType.
00679     if (thePlugin == NULL) {
00680         // create nsIPlugin factory
00681         error = (NPError)NSGetFactory(thePluginManager, kPluginCID, NULL, NULL, (nsIFactory** )&thePlugin);
00682 #if 0
00683               // beard: this will leak reference counts.       
00684            if (error == NS_OK) {
00685               thePlugin->AddRef();
00686            }
00687 #endif
00688        }
00689        
00690     return (NPError) error; 
00691 }
00692 
00693 //+++++++++++++++++++++++++++++++++++++++++++++++++
00694 // NPP_GetJavaClass:
00695 // New in Netscape Navigator 3.0. 
00696 // 
00697 // NPP_GetJavaClass is called during initialization to ask your plugin
00698 // what its associated Java class is. If you don't have one, just return
00699 // NULL. Otherwise, use the javah-generated "use_" function to both
00700 // initialize your class and return it. If you can't find your class, an
00701 // error will be signalled by "use_" and will cause the Navigator to
00702 // complain to the user.
00703 //+++++++++++++++++++++++++++++++++++++++++++++++++
00704 
00705 jref
00706 NPP_GetJavaClass(void)
00707 {
00708     // Only call initialize the plugin if it hasn't been `d.
00709 #if 0
00710     if (thePluginManager == NULL) {
00711         // Create the plugin manager and plugin objects.
00712         NPError result = CPluginManager::Create();      
00713         if (result) return NULL;
00714         assert( thePluginManager != NULL );
00715         thePluginManager->AddRef();
00716         NP_CreatePlugin(thePluginManager, (nsIPlugin** )(&thePlugin));
00717         assert( thePlugin != NULL );
00718     }
00719     return thePlugin->GetJavaClass();
00720 #endif
00721     return NULL;
00722 }
00723 
00724 //+++++++++++++++++++++++++++++++++++++++++++++++++
00725 // NPP_Shutdown:
00726 // Provides global deinitialization for a plug-in. 
00727 // 
00728 // This function is called once after the last instance of your plug-in 
00729 // is destroyed.  thePluginManager and thePlugin are delete at this time.
00730 //+++++++++++++++++++++++++++++++++++++++++++++++++
00731 
00732 void
00733 NPP_Shutdown(void)
00734 {
00735 //    TRACE("NPP_Shutdown\n");
00736 
00737     if (thePlugin)
00738     {
00739         thePlugin->Shutdown();
00740         thePlugin->Release();
00741         thePlugin = NULL;
00742     }
00743 
00744     if (thePluginManager)  {
00745         thePluginManager->Release();
00746         thePluginManager = NULL;
00747     }
00748     
00749     return;
00750 }
00751 
00752 //+++++++++++++++++++++++++++++++++++++++++++++++++
00753 // NPP_New:
00754 // Creates a new instance of a plug-in and returns an error value. 
00755 // 
00756 // A plugin instance peer and instance peer is created.  After
00757 // a successful instansiation, the peer is stored in the plugin
00758 // instance's pdata.
00759 //+++++++++++++++++++++++++++++++++++++++++++++++++
00760 
00761 NPError 
00762 NPP_New(NPMIMEType pluginType,
00763        NPP instance,
00764        PRUint16 mode,
00765        int16 argc,
00766        char* argn[],
00767        char* argv[],
00768        NPSavedData* saved)
00769 {
00770 //    TRACE("NPP_New\n");
00771     
00772     if (instance == NULL)
00773         return NPERR_INVALID_INSTANCE_ERROR;
00774 
00775     // Create a new plugin instance and start it.
00776     nsIPluginInstance* pluginInstance = NULL;
00777     thePlugin->CreatePluginInstance(thePluginManager, NS_GET_IID(nsIPluginInstance), pluginType, (void**)&pluginInstance);
00778     if (pluginInstance == NULL) {
00779         return NPERR_OUT_OF_MEMORY_ERROR;
00780     }
00781     
00782     // Create a new plugin instance peer,
00783     // XXX - Since np_instance is not implemented in the 4.0x browser, I
00784     // XXX - had to save the plugin parameter in the peer class.
00785     // XXX - Ask Warren about np_instance.
00786     CPluginInstancePeer* peer = new CPluginInstancePeer(pluginInstance, instance, (nsMIMEType)pluginType, 
00787                                                                           (nsPluginMode)mode, (PRUint16)argc, (const char** )argn, (const char** )argv);
00788     assert( peer != NULL );
00789     if (!peer) return NPERR_OUT_OF_MEMORY_ERROR;
00790     peer->AddRef();
00791     pluginInstance->Initialize(peer);
00792     pluginInstance->Start();
00793     // Set the user instance and store the peer in npp->pdata.
00794     instance->pdata = peer;
00795     peer->Release();
00796 
00797     return NPERR_NO_ERROR;
00798 }
00799 
00800 //+++++++++++++++++++++++++++++++++++++++++++++++++
00801 // NPP_Destroy:
00802 // Deletes a specific instance of a plug-in and returns an error value. 
00803 //
00804 // The plugin instance peer and plugin instance are destroyed.
00805 // The instance's pdata is set to NULL.
00806 //+++++++++++++++++++++++++++++++++++++++++++++++++
00807 
00808 NPError 
00809 NPP_Destroy(NPP instance, NPSavedData** save)
00810 {
00811 //    TRACE("NPP_Destroy\n");
00812     
00813     if (instance == NULL)
00814         return NPERR_INVALID_INSTANCE_ERROR;
00815     
00816     CPluginInstancePeer* peer = (CPluginInstancePeer*) instance->pdata;
00817     nsIPluginInstance* pluginInstance = peer->GetInstance();
00818     pluginInstance->Stop();
00819     pluginInstance->Destroy();
00820     pluginInstance->Release();
00821        // peer->Release();
00822     instance->pdata = NULL;
00823     
00824     return NPERR_NO_ERROR;
00825 }
00826 
00827 //+++++++++++++++++++++++++++++++++++++++++++++++++
00828 // NPP_SetWindow:
00829 // Sets the window in which a plug-in draws, and returns an error value. 
00830 //+++++++++++++++++++++++++++++++++++++++++++++++++
00831 
00832 NPError 
00833 NPP_SetWindow(NPP instance, NPWindow* window)
00834 {
00835 //    TRACE("NPP_SetWindow\n");
00836     
00837     if (instance == NULL)
00838         return NPERR_INVALID_INSTANCE_ERROR;
00839 
00840     CPluginInstancePeer* peer = (CPluginInstancePeer*) instance->pdata;
00841     if ( peer == NULL)
00842         return NPERR_INVALID_PLUGIN_ERROR;
00843 
00844        // record the window in the peer, so we can deliver proper events.
00845        peer->SetWindow(window);
00846 
00847     nsIPluginInstance* pluginInstance = peer->GetInstance();
00848     if( pluginInstance == 0 )
00849         return NPERR_INVALID_PLUGIN_ERROR;
00850 
00851     return (NPError)pluginInstance->SetWindow((nsPluginWindow* ) window );
00852 }
00853 
00854 //+++++++++++++++++++++++++++++++++++++++++++++++++
00855 // NPP_NewStream:
00856 // Notifies an instance of a new data stream and returns an error value. 
00857 //
00858 // Create a stream peer and stream.  If succesful, save
00859 // the stream peer in NPStream's pdata.
00860 //+++++++++++++++++++++++++++++++++++++++++++++++++
00861 
00862 NPError 
00863 NPP_NewStream(NPP instance,
00864               NPMIMEType type,
00865               NPStream *stream, 
00866               NPBool seekable,
00867               PRUint16 *stype)
00868 {
00869     // XXX - How do you set the fields of the peer stream and stream?
00870     // XXX - Looks like these field will have to be created since
00871     // XXX - We are not using np_stream.
00872    
00873 //    TRACE("NPP_NewStream\n");
00874 
00875     if (instance == NULL)
00876         return NPERR_INVALID_INSTANCE_ERROR;
00877                             
00878     CPluginInputStream* inStr = (CPluginInputStream*)stream->notifyData;
00879     if (inStr == NULL)
00880         return NPERR_GENERIC_ERROR;
00881     
00882     nsIPluginStreamInfo* info = inStr->CreatePluginStreamInfo(stream->url, type, seekable);
00883     nsresult err = inStr->GetListener()->OnStartBinding(info);
00884     if (err) return err;
00885 
00886     inStr->SetStreamInfo(instance, stream);
00887     stream->pdata = inStr;
00888     *stype = inStr->GetStreamType();
00889 
00890     return NPERR_NO_ERROR;
00891 }
00892 
00893 //+++++++++++++++++++++++++++++++++++++++++++++++++
00894 // NPP_WriteReady:
00895 // Returns the maximum number of bytes that an instance is prepared to accept
00896 // from the stream. 
00897 //+++++++++++++++++++++++++++++++++++++++++++++++++
00898 
00899 int32 
00900 NPP_WriteReady(NPP instance, NPStream *stream)
00901 {
00902 //    TRACE("NPP_WriteReady\n");
00903 
00904     if (instance == NULL)
00905         return -1;
00906 
00907     CPluginInputStream* inStr = (CPluginInputStream*)stream->pdata;
00908     if (inStr == NULL)
00909         return -1;
00910     return NP_MAXREADY;
00911 }
00912 
00913 
00914 //+++++++++++++++++++++++++++++++++++++++++++++++++
00915 // NPP_Write:
00916 // Delivers data from a stream and returns the number of bytes written. 
00917 //+++++++++++++++++++++++++++++++++++++++++++++++++
00918 
00919 int32 
00920 NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer)
00921 {
00922 //    TRACE("NPP_Write\n");
00923 
00924     if (instance == NULL)
00925         return -1;
00926        
00927     CPluginInputStream* inStr = (CPluginInputStream*)stream->pdata;
00928     if (inStr == NULL)
00929         return -1;
00930     nsresult err = inStr->SetReadBuffer((PRUint32)len, (const char*)buffer);
00931     if (err != NS_OK) return -1;
00932     err = inStr->GetListener()->OnDataAvailable(inStr->GetPluginStreamInfo(), inStr, len);
00933     if (err != NS_OK) return -1;
00934     return len;
00935 }
00936 
00937 //+++++++++++++++++++++++++++++++++++++++++++++++++
00938 // NPP_DestroyStream:
00939 // Indicates the closure and deletion of a stream, and returns an error value. 
00940 //
00941 // The stream peer and stream are destroyed.  NPStream's
00942 // pdata is set to NULL.
00943 //+++++++++++++++++++++++++++++++++++++++++++++++++
00944 
00945 NPError 
00946 NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason)
00947 {
00948 //    TRACE("NPP_DestroyStream\n");
00949 
00950     if (instance == NULL)
00951         return NPERR_INVALID_INSTANCE_ERROR;
00952               
00953     CPluginInputStream* inStr = (CPluginInputStream*)stream->pdata;
00954     if (inStr == NULL)
00955         return NPERR_GENERIC_ERROR;
00956     inStr->GetListener()->OnStopBinding(inStr->GetPluginStreamInfo(), (nsPluginReason)reason);
00957     // inStr->Release();
00958     stream->pdata = NULL;
00959        
00960     return NPERR_NO_ERROR;
00961 }
00962 
00963 //+++++++++++++++++++++++++++++++++++++++++++++++++
00964 // NPP_StreamAsFile:
00965 // Provides a local file name for the data from a stream. 
00966 //+++++++++++++++++++++++++++++++++++++++++++++++++
00967 
00968 void 
00969 NPP_StreamAsFile(NPP instance, NPStream *stream, const char* fname)
00970 {
00971 //    TRACE("NPP_StreamAsFile\n");
00972 
00973     if (instance == NULL)
00974         return;
00975               
00976     CPluginInputStream* inStr = (CPluginInputStream*)stream->pdata;
00977     if (inStr == NULL)
00978         return;
00979     (void)inStr->GetListener()->OnFileAvailable(inStr->GetPluginStreamInfo(), fname);
00980 }
00981 
00982 //+++++++++++++++++++++++++++++++++++++++++++++++++
00983 // NPP_Print:
00984 //+++++++++++++++++++++++++++++++++++++++++++++++++
00985 
00986 void 
00987 NPP_Print(NPP instance, NPPrint* printInfo)
00988 {
00989 //    TRACE("NPP_Print\n");
00990 
00991     if(printInfo == NULL)   // trap invalid parm
00992         return;
00993 
00994     if (instance != NULL)
00995     {
00996         CPluginInstancePeer* peer = (CPluginInstancePeer*) instance->pdata;
00997         nsIPluginInstance* pluginInstance = peer->GetInstance();
00998         pluginInstance->Print((nsPluginPrint* ) printInfo );
00999     }
01000 }
01001 
01002 //+++++++++++++++++++++++++++++++++++++++++++++++++
01003 // NPP_URLNotify:
01004 // Notifies the instance of the completion of a URL request. 
01005 //+++++++++++++++++++++++++++++++++++++++++++++++++
01006 
01007 void
01008 NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData)
01009 {
01010 //    TRACE("NPP_URLNotify\n");
01011 
01012     if (instance != NULL) {
01013         CPluginInputStream* inStr = (CPluginInputStream*)notifyData;
01014         (void)inStr->GetListener()->OnStopBinding(inStr->GetPluginStreamInfo(), (nsPluginReason)reason);
01015         inStr->Release();
01016     }
01017 }
01018 
01019 //+++++++++++++++++++++++++++++++++++++++++++++++++
01020 // NPP_HandleEvent:
01021 // Mac-only, but stub must be present for Windows
01022 // Delivers a platform-specific event to the instance. 
01023 //+++++++++++++++++++++++++++++++++++++++++++++++++
01024 
01025 #ifndef XP_UNIX
01026 int16
01027 NPP_HandleEvent(NPP instance, void* event)
01028 {
01029 //    TRACE("NPP_HandleEvent\n");
01030     int16 eventHandled = FALSE;
01031     if (instance == NULL)
01032         return eventHandled;
01033        
01034     NPEvent* npEvent = (NPEvent*) event;
01035     nsPluginEvent pluginEvent = {
01036 #ifdef XP_MAC
01037         npEvent, NULL
01038 #else
01039         npEvent->event, npEvent->wParam, npEvent->lParam
01040 #endif
01041     };
01042        
01043     CPluginInstancePeer* peer = (CPluginInstancePeer*) instance->pdata;
01044     nsIPluginInstance* pluginInstance = peer->GetInstance();
01045     if (pluginInstance) {
01046         PRBool handled;
01047         nsresult err = pluginInstance->HandleEvent(&pluginEvent, &handled);
01048         if (err) return FALSE;
01049         eventHandled = (handled == PR_TRUE);
01050     }
01051        
01052     return eventHandled;
01053 }
01054 #endif // ndef XP_UNIX 
01055 
01057 // SECTION 5 - API Browser Implementations
01058 //
01059 // Glue code to the 4.0x Browser.
01061 
01063 //
01064 // CPluginManager
01065 //
01066 
01067 //******************************************************************************
01068 //
01069 // Once we moved to the new APIs, we need to implement fJVMMgr.
01070 //
01071 //******************************************************************************
01072 
01073 CPluginManager::CPluginManager(void)
01074 {
01075     mLiveconnect = NULL;
01076 }
01077 
01078 CPluginManager::~CPluginManager(void) 
01079 {
01080        NS_IF_RELEASE(mLiveconnect);
01081 }
01082 
01083 //+++++++++++++++++++++++++++++++++++++++++++++++++
01084 // ReloadPlugins:
01085 //+++++++++++++++++++++++++++++++++++++++++++++++++
01086 
01087 NS_METHOD
01088 CPluginManager::ReloadPlugins(PRBool reloadPages)
01089 {
01090     NPN_ReloadPlugins(reloadPages);
01091     return NS_OK;
01092 }
01093 
01094 NS_METHOD
01095 CPluginManager::GetURL(nsISupports* pluginInst, 
01096                        const char* url, 
01097                        const char* target,
01098                        nsIPluginStreamListener* streamListener,
01099                        const char* altHost,
01100                        const char* referrer,
01101                        PRBool forceJSEnabled)
01102 {
01103     if (altHost != NULL || referrer != NULL || forceJSEnabled != PR_FALSE) {
01104         return NPERR_INVALID_PARAM;
01105     }
01106 
01107     nsIPluginInstance* inst = NULL;
01108     nsresult rslt = pluginInst->QueryInterface(NS_GET_IID(nsIPluginInstance), (void**)&inst);
01109     if (rslt != NS_OK) return rslt;
01110        CPluginInstancePeer* instancePeer = NULL;
01111     rslt = inst->GetPeer((nsIPluginInstancePeer**)&instancePeer);
01112     if (rslt != NS_OK) {
01113         inst->Release();
01114         return rslt;
01115     }
01116     NPP npp = instancePeer->GetNPPInstance();
01117 
01118     NPError err;
01119     if (streamListener) {
01120         CPluginInputStream* inStr = new CPluginInputStream(streamListener);
01121         if (inStr == NULL) {
01122             instancePeer->Release();
01123             inst->Release();
01124             return NS_ERROR_OUT_OF_MEMORY;
01125         }
01126         inStr->AddRef();
01127     
01128         err = NPN_GetURLNotify(npp, url, target, inStr);
01129     }
01130     else {
01131         err = NPN_GetURL(npp, url, target);
01132     }
01133     instancePeer->Release();
01134     inst->Release();
01135     return fromNPError[err];
01136 }
01137 
01138 NS_METHOD
01139 CPluginManager::PostURL(nsISupports* pluginInst,
01140                         const char* url,
01141                         PRUint32 postDataLen, 
01142                         const char* postData,
01143                         PRBool isFile,
01144                         const char* target,
01145                         nsIPluginStreamListener* streamListener,
01146                         const char* altHost, 
01147                         const char* referrer,
01148                         PRBool forceJSEnabled,
01149                         PRUint32 postHeadersLength, 
01150                         const char* postHeaders)
01151 {
01152     if (altHost != NULL || referrer != NULL || forceJSEnabled != PR_FALSE
01153         || postHeadersLength != 0 || postHeaders != NULL) {
01154         return NPERR_INVALID_PARAM;
01155     }
01156 
01157     nsIPluginInstance* inst = NULL;
01158     nsresult rslt = pluginInst->QueryInterface(NS_GET_IID(nsIPluginInstance), (void**)&inst);
01159     if (rslt != NS_OK) return rslt;
01160        CPluginInstancePeer* instancePeer = NULL;
01161     rslt = inst->GetPeer((nsIPluginInstancePeer**)&instancePeer);
01162     if (rslt != NS_OK) {
01163         inst->Release();
01164         return rslt;
01165     }
01166     NPP npp = instancePeer->GetNPPInstance();
01167 
01168     NPError err;
01169     if (streamListener) {
01170         CPluginInputStream* inStr = new CPluginInputStream(streamListener);
01171         if (inStr == NULL) {
01172             instancePeer->Release();
01173             inst->Release();
01174             return NS_ERROR_OUT_OF_MEMORY;
01175         }
01176         inStr->AddRef();
01177     
01178         err = NPN_PostURLNotify(npp, url, target, postDataLen, postData, isFile, inStr);
01179     }
01180     else {
01181         err = NPN_PostURL(npp, url, target, postDataLen, postData, isFile);
01182     }
01183     instancePeer->Release();
01184     inst->Release();
01185     return fromNPError[err];
01186 }
01187 
01188 
01189 NS_IMETHODIMP
01190 CPluginManager::RegisterPlugin(REFNSIID aCID,
01191                                const char* aPluginName,
01192                                const char* aDescription,
01193                                const char** aMimeTypes,
01194                                const char** aMimeDescriptions,
01195                                const char** aFileExtensions,
01196                                PRInt32 aCount)
01197 {
01198     // XXXwaterson I don't think we need to do anything here.
01199     return NS_OK;
01200 }
01201 
01202 
01203 NS_IMETHODIMP
01204 CPluginManager::UnregisterPlugin(REFNSIID aCID)
01205 {
01206     // XXXwaterson I don't think we need to do anything here.
01207     return NS_OK;
01208 }
01209 
01210 NS_METHOD
01211 CPluginManager::GetService(const nsCID& aClass, const nsIID& aIID,
01212                nsISupports* *result,
01213                nsIShutdownListener* shutdownListener)
01214 {
01215        // the only service we support currently is nsIAllocator.
01216        if (aClass.Equals(kPluginManagerCID) || aClass.Equals(kAllocatorCID)) {
01217               return QueryInterface(aIID, (void**) result);
01218        }
01219        if (aClass.Equals(nsILiveconnect::GetCID())) {
01220               if (mLiveconnect == NULL) {
01221                      mLiveconnect = new nsLiveconnect;
01222                      NS_IF_ADDREF(mLiveconnect);
01223               }
01224               return mLiveconnect->QueryInterface(aIID, result);
01225        }
01226        return NS_ERROR_SERVICE_NOT_FOUND;
01227 }
01228 
01229 NS_METHOD
01230 CPluginManager::ReleaseService(const nsCID& aClass, nsISupports* service,
01231                    nsIShutdownListener* shutdownListener)
01232 {
01233        NS_RELEASE(service);
01234        return NS_OK;
01235 }
01236 
01237 NS_METHOD_(void*)
01238 CPluginManager::Alloc(PRUint32 size)
01239 {
01240        return ::NPN_MemAlloc(size);
01241 }
01242 
01243 NS_METHOD_(void*)
01244 CPluginManager::Realloc(void* ptr, PRUint32 size)
01245 {
01246        if (ptr != NULL) {
01247               void* new_ptr = Alloc(size);
01248               if (new_ptr != NULL) {
01249                      ::memcpy(new_ptr, ptr, size);
01250                      Free(ptr);
01251               }
01252               ptr = new_ptr;
01253        }
01254        return ptr;
01255 }
01256 
01257 NS_METHOD
01258 CPluginManager::Free(void* ptr)
01259 {
01260        if (ptr != NULL) {
01261               ::NPN_MemFree(ptr);
01262               return NS_OK;
01263        }
01264        return NS_ERROR_NULL_POINTER;
01265 }
01266 
01267 NS_METHOD
01268 CPluginManager::HeapMinimize()
01269 {
01270 #ifdef XP_MAC
01271        ::NPN_MemFlush(1024);
01272 #endif
01273        return NS_OK;
01274 }
01275 
01276 //+++++++++++++++++++++++++++++++++++++++++++++++++
01277 // UserAgent:
01278 //+++++++++++++++++++++++++++++++++++++++++++++++++
01279 
01280 NS_METHOD
01281 CPluginManager::UserAgent(const char* *result)
01282 {
01283     *result = NPN_UserAgent(NULL);
01284     return NS_OK;
01285 }
01286 
01287 
01288 int varMap[] = {
01289     (int)NPNVxDisplay,                  // nsPluginManagerVariable_XDisplay = 1,
01290     (int)NPNVxtAppContext,              // nsPluginManagerVariable_XtAppContext,
01291     (int)NPNVnetscapeWindow,            // nsPluginManagerVariable_NetscapeWindow,
01292     (int)NPPVpluginWindowBool,          // nsPluginInstancePeerVariable_WindowBool,
01293     (int)NPPVpluginTransparentBool,     // nsPluginInstancePeerVariable_TransparentBool,
01294     (int)NPPVjavaClass,                 // nsPluginInstancePeerVariable_JavaClass,
01295     (int)NPPVpluginWindowSize,          // nsPluginInstancePeerVariable_WindowSize,
01296     (int)NPPVpluginTimerInterval,       // nsPluginInstancePeerVariable_TimerInterval
01297 };
01298 
01299 //+++++++++++++++++++++++++++++++++++++++++++++++++
01300 // GetValue:
01301 //+++++++++++++++++++++++++++++++++++++++++++++++++
01302 
01303 NS_METHOD
01304 CPluginManager::GetValue(nsPluginManagerVariable variable, void *value)
01305 {
01306 #ifdef XP_UNIX
01307     return fromNPError[NPN_GetValue(NULL, (NPNVariable)varMap[(int)variable], value)];
01308 #else
01309     return fromNPError[NPERR_GENERIC_ERROR];
01310 #endif // XP_UNIX
01311 }
01312 
01313 //+++++++++++++++++++++++++++++++++++++++++++++++++
01314 // SetValue:
01315 //+++++++++++++++++++++++++++++++++++++++++++++++++
01316 
01317 NS_METHOD
01318 CPluginManager::SetValue(nsPluginManagerVariable variable, void *value) 
01319 {
01320 #ifdef XP_UNIX
01321     return fromNPError[NPN_SetValue(NULL, (NPPVariable)varMap[(int)variable], value)];
01322 #else
01323     return fromNPError[NPERR_GENERIC_ERROR];
01324 #endif // XP_UNIX
01325 }
01326 
01327 //+++++++++++++++++++++++++++++++++++++++++++++++++
01328 // nsISupports functions
01329 //+++++++++++++++++++++++++++++++++++++++++++++++++
01330 
01331 NS_IMPL_ADDREF(CPluginManager)
01332 NS_IMPL_RELEASE(CPluginManager)
01333 
01334 NS_METHOD
01335 CPluginManager::QueryInterface(const nsIID& iid, void** ptr) 
01336 {                                                                        
01337     if (NULL == ptr) {                                            
01338         return NS_ERROR_NULL_POINTER;                                        
01339     }                                                                      
01340   
01341     if (iid.Equals(NS_GET_IID(nsIServiceManager))) {                                                          
01342         *ptr = (void*) (nsIServiceManager*)this;                                        
01343         AddRef();                                                            
01344         return NS_OK;                                                        
01345     }
01346     if (iid.Equals(NS_GET_IID(nsIAllocator))) {                                                          
01347         *ptr = (void*) (nsIAllocator*)this;                                        
01348         AddRef();                                                            
01349         return NS_OK;                                                        
01350     }
01351     if (iid.Equals(NS_GET_IID(nsIPluginManager)) || iid.Equals(NS_GET_IID(nsISupports))) {
01352         *ptr = (void*) ((nsIPluginManager*)this);                        
01353         AddRef();                                                            
01354         return NS_OK;                                                        
01355     }                                                                      
01356     return NS_NOINTERFACE;                                                 
01357 }
01358 
01360 //
01361 // CPluginInstancePeer
01362 //
01363 
01364 CPluginInstancePeer::CPluginInstancePeer(nsIPluginInstance* pluginInstance,
01365                                          NPP npp,
01366                                          nsMIMEType typeString, 
01367                                          nsPluginMode type,
01368                                          PRUint16 attr_cnt, 
01369                                          const char** attr_list,
01370                                          const char** val_list)
01371     :  mInstance(pluginInstance), mWindow(NULL),
01372               npp(npp), typeString(typeString), type(type), attribute_cnt(attr_cnt),
01373               attribute_list(NULL), values_list(NULL)
01374 {
01375     NS_IF_ADDREF(mInstance);
01376 
01377     attribute_list = (char**) NPN_MemAlloc(attr_cnt * sizeof(const char*));
01378     values_list = (char**) NPN_MemAlloc(attr_cnt * sizeof(const char*));
01379 
01380     if (attribute_list != NULL && values_list != NULL) {
01381         for (int i = 0; i < attribute_cnt; i++)   {
01382             attribute_list[i] = (char*) NPN_MemAlloc(strlen(attr_list[i]) + 1);
01383             if (attribute_list[i] != NULL)
01384                 strcpy(attribute_list[i], attr_list[i]);
01385 
01386             values_list[i] = (char*) NPN_MemAlloc(strlen(val_list[i]) + 1);
01387             if (values_list[i] != NULL)
01388                 strcpy(values_list[i], val_list[i]);
01389         }
01390     }
01391 }
01392 
01393 CPluginInstancePeer::~CPluginInstancePeer(void) 
01394 {
01395     if (attribute_list != NULL && values_list != NULL) {
01396         for (int i = 0; i < attribute_cnt; i++)   {
01397             NPN_MemFree(attribute_list[i]);
01398             NPN_MemFree(values_list[i]);
01399         }
01400 
01401         NPN_MemFree(attribute_list);
01402         NPN_MemFree(values_list);
01403     }
01404     
01405     NS_IF_RELEASE(mInstance);
01406 }
01407 
01408 
01409 //+++++++++++++++++++++++++++++++++++++++++++++++++
01410 // GetValue:
01411 //+++++++++++++++++++++++++++++++++++++++++++++++++
01412 
01413 NS_METHOD
01414 CPluginInstancePeer::GetValue(nsPluginInstancePeerVariable variable, void *value)
01415 {
01416 #ifdef XP_UNIX
01417     return fromNPError[NPN_GetValue(NULL, (NPNVariable)varMap[(int)variable], value)];
01418 #else
01419     return fromNPError[NPERR_GENERIC_ERROR];
01420 #endif // XP_UNIX
01421 }
01422 
01423 //+++++++++++++++++++++++++++++++++++++++++++++++++
01424 // SetValue:
01425 //+++++++++++++++++++++++++++++++++++++++++++++++++
01426 
01427 NS_METHOD
01428 CPluginInstancePeer::SetValue(nsPluginInstancePeerVariable variable, void *value) 
01429 {
01430 #ifdef XP_UNIX
01431     return fromNPError[NPN_SetValue(NULL, (NPPVariable)varMap[(int)variable], value)];
01432 #else
01433     return fromNPError[NPERR_GENERIC_ERROR];
01434 #endif // XP_UNIX
01435 }
01436 
01437 //+++++++++++++++++++++++++++++++++++++++++++++++++
01438 // GetMIMEType:
01439 // Corresponds to NPP_New's MIMEType argument.
01440 //+++++++++++++++++++++++++++++++++++++++++++++++++
01441 
01442 NS_METHOD
01443 CPluginInstancePeer::GetMIMEType(nsMIMEType *result) 
01444 {
01445     *result = typeString;
01446     return NS_OK;
01447 }
01448 
01449 //+++++++++++++++++++++++++++++++++++++++++++++++++
01450 // GetMode:
01451 // Corresponds to NPP_New's mode argument.
01452 //+++++++++++++++++++++++++++++++++++++++++++++++++
01453 
01454 NS_METHOD
01455 CPluginInstancePeer::GetMode(nsPluginMode *result)
01456 {
01457     *result = type;
01458     return NS_OK;
01459 }
01460 
01461 
01462 // Get a ptr to the paired list of attribute names and values,
01463 // returns the length of the array.
01464 //
01465 // Each name or value is a null-terminated string.
01466 NS_METHOD
01467 CPluginInstancePeer::GetAttributes(PRUint16& n, const char* const*& names, const char* const*& values)  
01468 {
01469     n = attribute_cnt;
01470     names = attribute_list;
01471     values = values_list;
01472 
01473     return NS_OK;
01474 }
01475 
01476 #if defined(XP_MAC)
01477 
01478 inline unsigned char toupper(unsigned char c)
01479 {
01480     return (c >= 'a' && c <= 'z') ? (c - ('a' - 'A')) : c;
01481 }
01482 
01483 static int strcasecmp(const char * str1, const char * str2)
01484 {
01485 #if __POWERPC__
01486        
01487     const     unsigned char * p1 = (unsigned char *) str1 - 1;
01488     const     unsigned char * p2 = (unsigned char *) str2 - 1;
01489     unsigned long           c1, c2;
01490               
01491     while (toupper(c1 = *++p1) == toupper(c2 = *++p2))
01492         if (!c1)
01493             return(0);
01494 
01495 #else
01496        
01497     const     unsigned char * p1 = (unsigned char *) str1;
01498     const     unsigned char * p2 = (unsigned char *) str2;
01499     unsigned char           c1, c2;
01500        
01501     while (toupper(c1 = *p1++) == toupper(c2 = *p2++))
01502         if (!c1)
01503             return(0);
01504 
01505 #endif
01506        
01507     return(toupper(c1) - toupper(c2));
01508 }
01509 
01510 #endif /* XP_MAC */
01511 
01512 // Get the value for the named attribute.  Returns null
01513 // if the attribute was not set.
01514 NS_METHOD
01515 CPluginInstancePeer::GetAttribute(const char* name, const char* *result) 
01516 {
01517     for (int i=0; i < attribute_cnt; i++)  {
01518 #if defined(XP_UNIX) || defined(XP_MAC)
01519         if (strcasecmp(name, attribute_list[i]) == 0)
01520 #else
01521             if (stricmp(name, attribute_list[i]) == 0) 
01522 #endif
01523             {
01524                 *result = values_list[i];
01525                 return NS_OK;
01526             }
01527     }
01528 
01529     return NS_ERROR_FAILURE;
01530 }
01531 
01532 //+++++++++++++++++++++++++++++++++++++++++++++++++
01533 // NewStream:
01534 //+++++++++++++++++++++++++++++++++++++++++++++++++
01535 NS_METHOD
01536 CPluginInstancePeer::NewStream(nsMIMEType type, const char* target, 
01537                                nsIOutputStream* *result)
01538 {
01539     assert( npp != NULL );
01540     
01541     // Create a new NPStream.
01542     NPStream* stream = NULL;
01543     NPError error = NPN_NewStream(npp, (NPMIMEType)type, target, &stream);
01544     if (error != NPERR_NO_ERROR)
01545         return fromNPError[error];
01546     
01547     // Create a new Plugin Manager Stream.
01548     // XXX - Do we have to Release() the manager stream before doing this?
01549     // XXX - See the BAM doc for more info.
01550     CPluginManagerStream* mstream = new CPluginManagerStream(npp, stream);
01551     if (mstream == NULL)
01552         return NS_ERROR_OUT_OF_MEMORY;
01553     mstream->AddRef();
01554     *result = (nsIOutputStream* )mstream;
01555 
01556     return NS_OK;
01557 }
01558 
01559 //+++++++++++++++++++++++++++++++++++++++++++++++++
01560 // ShowStatus:
01561 //+++++++++++++++++++++++++++++++++++++++++++++++++
01562 
01563 NS_METHOD
01564 CPluginInstancePeer::ShowStatus(const char* message)
01565 {
01566     assert( message != NULL );
01567 
01568     NPN_Status(npp, message);
01569        return NS_OK;
01570 }
01571 
01572 NS_METHOD
01573 CPluginInstancePeer::SetWindowSize(PRUint32 width, PRUint32 height)
01574 {
01575     NPError err;
01576     NPSize size;
01577     size.width = width;
01578     size.height = height;
01579     err = NPN_SetValue(npp, NPPVpluginWindowSize, &size);
01580     return fromNPError[err];
01581 }
01582 
01583 //+++++++++++++++++++++++++++++++++++++++++++++++++
01584 // nsISupports functions
01585 //+++++++++++++++++++++++++++++++++++++++++++++++++
01586 
01587 NS_IMPL_ADDREF(CPluginInstancePeer)
01588 NS_IMPL_RELEASE(CPluginInstancePeer)
01589 
01590 NS_METHOD
01591 CPluginInstancePeer::QueryInterface(const nsIID& iid, void** ptr) 
01592 {                                                                        
01593     if (NULL == ptr) {                                            
01594         return NS_ERROR_NULL_POINTER;                                        
01595     }                                                                      
01596   
01597     if (iid.Equals(NS_GET_IID(nsIPluginInstancePeer))) {
01598         *ptr = (void*) this;                                        
01599         AddRef();                                                            
01600         return NS_OK;                                                        
01601     }                                                                      
01602     if (iid.Equals(NS_GET_IID(nsIPluginTagInfo)) || iid.Equals(NS_GET_IID(nsISupports))) {                                      
01603         *ptr = (void*) ((nsIPluginTagInfo*)this);                        
01604         AddRef();                                                            
01605         return NS_OK;                                                        
01606     }                                                                      
01607     return NS_NOINTERFACE;                                                 
01608 }
01609 
01611 //
01612 // CPluginManagerStream
01613 //
01614 
01615 CPluginManagerStream::CPluginManagerStream(NPP npp, NPStream* pstr)
01616     : npp(npp), pstream(pstr)
01617 {
01618 }
01619 
01620 CPluginManagerStream::~CPluginManagerStream(void)
01621 {
01622     //pstream = NULL;
01623     NPN_DestroyStream(npp, pstream, NPRES_DONE);
01624 }
01625 
01626 
01627 //+++++++++++++++++++++++++++++++++++++++++++++++++
01628 // Write:
01629 //+++++++++++++++++++++++++++++++++++++++++++++++++
01630 
01631 NS_METHOD
01632 CPluginManagerStream::Write(const char* buffer, PRUint32 len, PRUint32 *aWriteCount)
01633 {
01634     assert( npp != NULL );
01635     assert( pstream != NULL );
01636 
01637     *aWriteCount = NPN_Write(npp, pstream, len, (void* )buffer);
01638     return *aWriteCount >= 0 ? NS_OK : NS_ERROR_FAILURE;
01639 }
01640 
01641 //+++++++++++++++++++++++++++++++++++++++++++++++++
01642 // GetURL:
01643 //+++++++++++++++++++++++++++++++++++++++++++++++++
01644 
01645 NS_METHOD
01646 CPluginManagerStream::GetURL(const char* *result)
01647 {
01648     assert( pstream != NULL );
01649 
01650     *result = pstream->url;
01651        return NS_OK;
01652 }
01653 
01654 //+++++++++++++++++++++++++++++++++++++++++++++++++
01655 // GetEnd:
01656 //+++++++++++++++++++++++++++++++++++++++++++++++++
01657 
01658 NS_METHOD
01659 CPluginManagerStream::GetEnd(PRUint32 *result)
01660 {
01661     assert( pstream != NULL );
01662 
01663     *result = pstream->end;
01664        return NS_OK;
01665 }
01666 
01667 //+++++++++++++++++++++++++++++++++++++++++++++++++
01668 // GetLastModified:
01669 //+++++++++++++++++++++++++++++++++++++++++++++++++
01670 
01671 NS_METHOD
01672 CPluginManagerStream::GetLastModified(PRUint32 *result)
01673 {
01674     assert( pstream != NULL );
01675 
01676     *result = pstream->lastmodified;
01677        return NS_OK;
01678 }
01679 
01680 //+++++++++++++++++++++++++++++++++++++++++++++++++
01681 // GetNotifyData:
01682 //+++++++++++++++++++++++++++++++++++++++++++++++++
01683 
01684 NS_METHOD
01685 CPluginManagerStream::GetNotifyData(void* *result)
01686 {
01687     assert( pstream != NULL );
01688 
01689     *result = pstream->notifyData;
01690        return NS_OK;
01691 }
01692 
01693 //+++++++++++++++++++++++++++++++++++++++++++++++++
01694 // GetNotifyData:
01695 //+++++++++++++++++++++++++++++++++++++++++++++++++
01696 
01697 NS_METHOD
01698 CPluginManagerStream::Close(void)
01699 {
01700     assert( pstream != NULL );
01701 
01702     return NS_OK;
01703 }
01704 
01705 
01706 //+++++++++++++++++++++++++++++++++++++++++++++++++
01707 // nsISupports functions
01708 //+++++++++++++++++++++++++++++++++++++++++++++++++
01709 
01710 NS_IMPL_ISUPPORTS1(CPluginManagerStream, nsIOutputStream)
01711 
01712 
01713 
01714 NS_IMPL_ISUPPORTS1(CPluginStreamInfo, nsIPluginStreamInfo)
01715 
01716 CPluginInputStream::CPluginInputStream(nsIPluginStreamListener* listener)
01717     : mListener(listener), mStreamType(nsPluginStreamType_Normal),
01718       mNPP(NULL), mStream(NULL),
01719       mBuffer(NULL), mBufferLength(0), mAmountRead(0),
01720       mStreamInfo(NULL)
01721 {
01722     if (mListener != NULL) {
01723         mListener->AddRef();
01724         mListener->GetStreamType(&mStreamType);
01725     }
01726 }
01727 
01728 CPluginInputStream::~CPluginInputStream(void)
01729 {
01730        NS_IF_RELEASE(mListener);
01731 
01732     delete mBuffer;
01733     
01734     NS_IF_RELEASE(mStreamInfo);
01735 }
01736 
01737 NS_IMPL_ISUPPORTS1(CPluginInputStream, nsIPluginInputStream)
01738 
01739 NS_METHOD
01740 CPluginInputStream::Close(void)
01741 {
01742     if (mNPP == NULL || mStream == NULL)
01743         return NS_ERROR_FAILURE;
01744     NPError err = NPN_DestroyStream(mNPP, mStream, NPRES_USER_BREAK);
01745     return fromNPError[err];
01746 }
01747 
01748 NS_METHOD
01749 CPluginInputStream::GetLength(PRUint32 *aLength)
01750 {
01751     *aLength = mStream->end;
01752     return NS_OK;
01753 }
01754 
01755 NS_METHOD
01756 CPluginInputStream::Read(char* aBuf, PRUint32 aCount, PRUint32 *aReadCount)
01757 {
01758     PRUint32 cnt = PR_MIN(aCount, mBufferLength);
01759     memcpy(aBuf, mBuffer + mAmountRead, cnt);
01760     *aReadCount = cnt;
01761     mAmountRead += cnt;
01762     mBufferLength -= cnt;
01763     return NS_OK;
01764 }
01765 
01766 NS_METHOD
01767 CPluginInputStream::GetLastModified(PRUint32 *result)
01768 {
01769     *result = mStream->lastmodified;
01770     return NS_OK;
01771 }
01772 
01773 NS_METHOD
01774 CPluginInputStream::RequestRead(nsByteRange* rangeList)
01775 {
01776     NPError err = NPN_RequestRead(mStream, (NPByteRange*)rangeList);
01777     return fromNPError[err];
01778 }
01779 
01780 
01782 
01783 #if defined(__cplusplus)
01784 } /* extern "C" */
01785 #endif
01786