Back to index

lightning-sunbird  0.9+nobinonly
BackwardAdapter.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  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00039 // Backward Adapter
00040 // This acts as a adapter layer to allow 5.0 plugins work with the 4.0/3.0 
00041 // browser.
00043 
00045 // SECTION 1 - Includes
00047 
00048 #include "npapi.h"
00049 #include "nsIPluginManager2.h"
00050 #include "nsIServiceManager.h"
00051 #include "nsMemory.h"
00052 #include "nsLiveConnect.h"
00053 #include "nsIEventHandler.h"
00054 #include "nsplugin.h"
00055 #include "nsDebug.h"
00056 #include "nsIJRILiveConnectPlugin.h"
00057 #include "nsIJRILiveConnectPIPeer.h"
00058 #include "nsIPluginInputStream.h"
00059 #include "nsObsoleteModuleLoading.h"
00060 
00061 #ifdef XP_MAC
00062 #include "EventFilter.h"
00063 #include <MacWindows.h>
00064 #endif
00065 
00067 // SECTION 3 - Classes
00069 
00071 //
00072 // CPluginManager
00073 //
00074 // This is the dummy plugin manager that interacts with the 5.0 plugin.
00075 //
00076 
00077 #pragma mark CPluginManager
00078 
00079 class CPluginManager : public nsIPluginManager2, public nsIServiceManager, public nsIMemory {
00080 public:
00081        // Need an operator new for this.
00082        void* operator new(size_t size) { return ::NPN_MemAlloc(size); }
00083        void operator delete(void* ptr) { ::NPN_MemFree(ptr); }
00084 
00085     CPluginManager(void);
00086     virtual ~CPluginManager(void);
00087 
00088     NS_DECL_ISUPPORTS
00089 
00091     // from nsIPluginManager:
00092 
00102     NS_IMETHOD
00103     GetValue(nsPluginManagerVariable variable, void *value);
00104 
00115     NS_IMETHOD
00116     ReloadPlugins(PRBool reloadPages);
00117 
00126     NS_IMETHOD
00127     UserAgent(const char* *resultingAgentString);
00128 
00151     NS_IMETHOD
00152     GetURL(nsISupports* pluginInst, 
00153            const char* url, 
00154            const char* target = NULL,
00155            nsIPluginStreamListener* streamListener = NULL,
00156            const char* altHost = NULL,
00157            const char* referrer = NULL,
00158            PRBool forceJSEnabled = PR_FALSE);
00159 
00190     NS_IMETHOD
00191     PostURL(nsISupports* pluginInst,
00192             const char* url,
00193             PRUint32 postDataLen, 
00194             const char* postData,
00195             PRBool isFile = PR_FALSE,
00196             const char* target = NULL,
00197             nsIPluginStreamListener* streamListener = NULL,
00198             const char* altHost = NULL, 
00199             const char* referrer = NULL,
00200             PRBool forceJSEnabled = PR_FALSE,
00201             PRUint32 postHeadersLength = 0, 
00202             const char* postHeaders = NULL);
00203             
00204     NS_IMETHOD
00205     RegisterPlugin(REFNSIID aCID,
00206                    const char* aPluginName,
00207                    const char* aDescription,
00208                    const char** aMimeTypes,
00209                    const char** aMimeDescriptions,
00210                    const char** aFileExtensions,
00211                    PRInt32 aCount);
00212 
00213     NS_IMETHOD
00214     UnregisterPlugin(REFNSIID aCID);
00215 
00216     NS_IMETHOD
00217     GetURLWithHeaders(nsISupports* pluginInst, 
00218                       const char* url, 
00219                       const char* target = NULL,
00220                       nsIPluginStreamListener* streamListener = NULL,
00221                       const char* altHost = NULL,
00222                       const char* referrer = NULL,
00223                       PRBool forceJSEnabled = PR_FALSE,
00224                       PRUint32 getHeadersLength = 0, 
00225                       const char* getHeaders = NULL);
00226     
00227 
00229     // from nsIPluginManager2:
00230 
00236     NS_IMETHOD
00237     BeginWaitCursor(void)
00238     {
00239        return NS_ERROR_NOT_IMPLEMENTED;
00240        }
00241 
00247     NS_IMETHOD
00248     EndWaitCursor(void)
00249     {
00250        return NS_ERROR_NOT_IMPLEMENTED;
00251        }
00252 
00260     NS_IMETHOD
00261     SupportsURLProtocol(const char* protocol, PRBool *result)
00262     {
00263        return NS_ERROR_NOT_IMPLEMENTED;
00264        }
00265 
00276     NS_IMETHOD
00277     NotifyStatusChange(nsIPlugin* plugin, nsresult errorStatus)
00278     {
00279        return NS_ERROR_NOT_IMPLEMENTED;
00280        }
00281     
00295     NS_IMETHOD
00296     FindProxyForURL(const char* url, char* *result)
00297     {
00298        return NS_ERROR_NOT_IMPLEMENTED;
00299        }
00300 
00302     // New top-level window handling calls for Mac:
00303     
00312     NS_IMETHOD
00313     RegisterWindow(nsIEventHandler* handler, nsPluginPlatformWindowRef window);
00314     
00323     NS_IMETHOD
00324     UnregisterWindow(nsIEventHandler* handler, nsPluginPlatformWindowRef window);
00325 
00334     NS_IMETHOD
00335        AllocateMenuID(nsIEventHandler* handler, PRBool isSubmenu, PRInt16 *result);
00336 
00344     NS_IMETHOD
00345        DeallocateMenuID(nsIEventHandler* handler, PRInt16 menuID)
00346     {
00347        return NS_ERROR_NOT_IMPLEMENTED;
00348        }
00349 
00358     NS_IMETHOD
00359     HasAllocatedMenuID(nsIEventHandler* handler, PRInt16 menuID, PRBool *result)
00360     {
00361        return NS_ERROR_NOT_IMPLEMENTED;
00362        }
00363 
00365     // from nsIServiceManager:
00366 
00367     NS_IMETHOD
00368     GetService(const nsCID& aClass, const nsIID& aIID, void* *result);
00369 
00370     NS_IMETHOD
00371     GetServiceByContractID(const char *aContractID, const nsIID & aIID, void * *result)
00372     {
00373        return NS_ERROR_NOT_IMPLEMENTED;
00374        }
00375 
00376     NS_IMETHOD
00377     IsServiceInstantiated(const nsCID & aClass, const nsIID & aIID, PRBool *_retval)
00378     {
00379        return NS_ERROR_NOT_IMPLEMENTED;
00380        }
00381 
00382     NS_IMETHOD
00383     IsServiceInstantiatedByContractID(const char *aContractID, const nsIID & aIID, PRBool *_retval)
00384     {
00385        return NS_ERROR_NOT_IMPLEMENTED;
00386        }
00387 
00394     NS_IMETHOD_(void*)
00395     Alloc(size_t size);
00396 
00404     NS_IMETHOD_(void*)
00405     Realloc(void* ptr, size_t size);
00406 
00412     NS_IMETHOD_(void)
00413     Free(void* ptr);
00414 
00415     NS_IMETHOD
00416     IsLowMemory(PRBool *_retval)
00417     {
00418        return NS_ERROR_NOT_IMPLEMENTED;
00419     }
00420 
00424     NS_IMETHOD
00425     HeapMinimize(PRBool aImmediate);
00426 
00427 private:
00428        nsILiveconnect* mLiveconnect;
00429 
00430        struct RegisteredWindow {
00431               RegisteredWindow* mNext;
00432               nsIEventHandler* mHandler;
00433               nsPluginPlatformWindowRef mWindow;
00434 
00435               RegisteredWindow(RegisteredWindow* next, nsIEventHandler* handler, nsPluginPlatformWindowRef window)
00436                      : mNext(next), mHandler(handler), mWindow(window)
00437               {
00438                      NS_ADDREF(mHandler);
00439               }
00440               
00441               ~RegisteredWindow()
00442               {
00443                      NS_RELEASE(mHandler);
00444               }
00445        };
00446 
00447        static RegisteredWindow* theRegisteredWindows;
00448        static RegisteredWindow* theActiveWindow;
00449        
00450        static RegisteredWindow** GetRegisteredWindow(nsPluginPlatformWindowRef window);
00451        static RegisteredWindow* FindRegisteredWindow(nsPluginPlatformWindowRef window);
00452 
00453 #ifdef XP_MAC
00454        Boolean mEventFiltersInstalled;
00455 
00456        static Boolean EventFilter(EventRecord* event);
00457        static Boolean MenuFilter(long menuSelection);
00458 #endif
00459 };
00460 
00462 //
00463 // CPluginManagerStream
00464 //
00465 // This is the dummy plugin manager stream that interacts with the 5.0 plugin.
00466 //
00467 
00468 #pragma mark CPluginManagerStream
00469 
00470 class CPluginManagerStream : public nsIOutputStream {
00471 public:
00472 
00473     CPluginManagerStream(NPP npp, NPStream* pstr);
00474     virtual ~CPluginManagerStream(void);
00475 
00476     NS_DECL_ISUPPORTS
00477 
00479     //
00480     // Taken from nsIStream
00481     //
00482     
00489     NS_IMETHOD
00490     Write(const char* aBuf, PRUint32 aCount, PRUint32 *aWriteCount); 
00491 
00505     NS_IMETHOD
00506     Write(nsIInputStream* fromStream, PRUint32 *aWriteCount);
00507 
00511     NS_IMETHOD
00512     Flush(void);
00513 
00514     NS_IMETHOD
00515     WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval) {
00516         NS_NOTREACHED("WriteFrom");
00517         return NS_ERROR_NOT_IMPLEMENTED;
00518     }
00519 
00520     NS_IMETHOD
00521     WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval) {
00522         NS_NOTREACHED("WriteSegments");
00523         return NS_ERROR_NOT_IMPLEMENTED;
00524     }
00525 
00526     NS_IMETHOD
00527     IsNonBlocking(PRBool *aNonBlocking) {
00528         NS_NOTREACHED("IsNonBlocking");
00529         return NS_ERROR_NOT_IMPLEMENTED;
00530     }
00531 
00533     //
00534     // Specific methods to nsIPluginManagerStream.
00535     //
00536     
00537     // Corresponds to NPStream's url field.
00538     NS_IMETHOD
00539     GetURL(const char*  *result);
00540 
00541     // Corresponds to NPStream's end field.
00542     NS_IMETHOD
00543     GetEnd(PRUint32 *result);
00544 
00545     // Corresponds to NPStream's lastmodfied field.
00546     NS_IMETHOD
00547     GetLastModified(PRUint32 *result);
00548 
00549     // Corresponds to NPStream's notifyData field.
00550     NS_IMETHOD
00551     GetNotifyData(void*  *result);
00552 
00553     // Corresponds to NPStream's url field.
00554     NS_IMETHOD Close(void);
00555 
00556 protected:
00557 
00558     // npp
00559     // The plugin instance that the manager stream belongs to.
00560     NPP npp;
00561 
00562     // pstream
00563     // The stream the class is using.
00564     NPStream* pstream;
00565 
00566 };
00567 
00569 //
00570 // CPluginInstancePeer
00571 //
00572 // This is the dummy instance peer that interacts with the 5.0 plugin.
00573 // In order to do LiveConnect, the class subclasses nsILiveConnectPluginInstancePeer.
00574 //
00575 
00576 #pragma mark CPluginInstancePeer
00577 
00578 class CPluginInstancePeer : public nsIPluginInstancePeer, public nsIPluginTagInfo, public nsIJRILiveConnectPluginInstancePeer {
00579 public:
00580 
00581     // XXX - I add parameters to the constructor because I wasn't sure if
00582     // XXX - the 4.0 browser had the npp_instance struct implemented.
00583     // XXX - If so, then I can access npp_instance through npp->ndata.
00584     CPluginInstancePeer(nsIPluginInstance* pluginInstance, NPP npp, nsMIMEType typeString, nsPluginMode type,
00585         PRUint16 attribute_cnt, const char** attribute_list, const char** values_list);
00586 
00587     virtual ~CPluginInstancePeer(void);
00588 
00589     NS_DECL_ISUPPORTS
00590 
00600     NS_IMETHOD
00601     GetValue(nsPluginInstancePeerVariable variable, void *value);
00602 
00603     // (Corresponds to NPN_SetValue.)
00604     NS_IMETHOD
00605     SetValue(nsPluginInstancePeerVariable variable, void *value);
00606 
00615     NS_IMETHOD
00616     GetMIMEType(nsMIMEType *result);
00617 
00627     NS_IMETHOD
00628     GetMode(nsPluginMode *result);
00629 
00643     NS_IMETHOD
00644     NewStream(nsMIMEType type, const char* target, nsIOutputStream* *result);
00645 
00655     NS_IMETHOD
00656     ShowStatus(const char* message);
00657 
00665     NS_IMETHOD
00666     SetWindowSize(PRUint32 width, PRUint32 height);
00667 
00668     // Get a ptr to the paired list of attribute names and values,
00669     // returns the length of the array.
00670     //
00671     // Each name or value is a null-terminated string.
00672     NS_IMETHOD
00673     GetAttributes(PRUint16& n, const char* const*& names, const char* const*& values);
00674 
00675     // Get the value for the named attribute.  Returns null
00676     // if the attribute was not set.
00677     NS_IMETHOD
00678     GetAttribute(const char* name, const char* *result);
00679 
00690     NS_IMETHOD
00691     GetDOMElement(nsIDOMElement* *result);
00692 
00701        NS_IMETHOD
00702        GetJavaEnv(JRIEnv* *resultingEnv);
00703 
00714     NS_IMETHOD
00715     GetJavaPeer(jref *resultingJavaPeer);
00716 
00717        nsIPluginInstance* GetInstance(void) { return mInstance; }
00718        NPP GetNPPInstance(void) { return npp; }
00719        
00720        void SetWindow(NPWindow* window) { mWindow = window; }
00721        NPWindow* GetWindow() { return mWindow; }
00722        
00723 protected:
00724 
00725     NPP npp;
00726     // XXX - The next five variables may need to be here since I
00727     // XXX - don't think np_instance is available in 4.0X.
00728     nsIPluginInstance* mInstance;
00729     NPWindow* mWindow;
00730     nsMIMEType typeString;
00731        nsPluginMode type;
00732        PRUint16 attribute_cnt;
00733        char** attribute_list;
00734        char** values_list;
00735 };
00736 
00737 #pragma mark CPluginStreamInfo
00738 
00739 class CPluginStreamInfo : public nsIPluginStreamInfo {
00740 public:
00741 
00742        CPluginStreamInfo(const char* URL, nsIPluginInputStream* inStr, nsMIMEType type, PRBool seekable)
00743                : mURL(URL), mInputStream(inStr), mMimeType(type), mIsSeekable(seekable)
00744        {
00745        }
00746 
00747        virtual ~CPluginStreamInfo() {}
00748 
00749     NS_DECL_ISUPPORTS
00750     
00751        NS_METHOD
00752        GetContentType(nsMIMEType* result)
00753        {
00754               *result = mMimeType;
00755               return NS_OK;
00756        }
00757 
00758        NS_METHOD
00759        IsSeekable(PRBool* result)
00760        {
00761               *result = mIsSeekable;
00762               return NS_OK;
00763        }
00764 
00765        NS_METHOD
00766        GetLength(PRUint32* result)
00767        {
00768               return mInputStream->Available(result);
00769        }
00770 
00771        NS_METHOD
00772        GetLastModified(PRUint32* result)
00773        {
00774               return mInputStream->GetLastModified(result);
00775        }
00776 
00777        NS_METHOD
00778        GetURL(const char** result)
00779        {
00780               *result = mURL;
00781               return NS_OK;
00782        }
00783 
00784        NS_METHOD
00785        RequestRead(nsByteRange* rangeList)
00786        {
00787               return mInputStream->RequestRead(rangeList);
00788        }
00789 
00790        NS_METHOD
00791        GetStreamOffset(PRInt32 *result)
00792        {
00793               *result = mStreamOffset;
00794               return NS_OK;
00795        }
00796 
00797 
00798        NS_METHOD
00799        SetStreamOffset(PRInt32 offset)
00800        {
00801               mStreamOffset = offset;
00802               return NS_OK;
00803        }
00804 
00805 private:
00806        const char* mURL;
00807        nsIPluginInputStream* mInputStream;
00808        nsMIMEType mMimeType;
00809        PRBool mIsSeekable;
00810        PRInt32 mStreamOffset;
00811 };
00812 
00813 #pragma mark CPluginInputStream
00814 
00815 class CPluginInputStream : public nsIPluginInputStream {
00816 public:
00817 
00818     NS_DECL_ISUPPORTS
00819 
00821     // from nsIInputStream:
00822 
00824     NS_IMETHOD
00825     Close(void);
00826 
00833     NS_IMETHOD
00834     Available(PRUint32 *aLength);
00835 
00845     NS_IMETHOD
00846     Read(char* aBuf, PRUint32 aCount, PRUint32 *aReadCount); 
00847 
00848     NS_IMETHOD ReadSegments(nsWriteSegmentFun writer, void * closure, PRUint32 count, PRUint32 *_retval) {
00849         NS_NOTREACHED("ReadSegments");
00850         return NS_ERROR_NOT_IMPLEMENTED;
00851     }
00852 
00853     NS_IMETHOD IsNonBlocking(PRBool *aNonBlocking) {
00854         NS_NOTREACHED("IsNonBlocking");
00855         return NS_ERROR_NOT_IMPLEMENTED;
00856     }
00857 
00859     // from nsIPluginInputStream:
00860 
00861     // (Corresponds to NPStream's lastmodified field.)
00862     NS_IMETHOD
00863     GetLastModified(PRUint32 *result);
00864 
00865     NS_IMETHOD
00866     RequestRead(nsByteRange* rangeList);
00867 
00869     // CPluginInputStream specific methods:
00870 
00871     CPluginInputStream(nsIPluginStreamListener* listener);
00872     virtual ~CPluginInputStream(void);
00873 
00874     void SetStreamInfo(NPP npp, NPStream* stream) {
00875         mNPP = npp;
00876         mStream = stream;
00877     }
00878 
00879     nsIPluginStreamListener* GetListener(void) { return mListener; }
00880     nsPluginStreamType GetStreamType(void) { return mStreamType; }
00881 
00882     nsresult SetReadBuffer(PRUint32 len, const char* buffer) {
00883         // XXX this has to be way more sophisticated
00884         if (mBuffer != NULL) delete[] mBuffer;
00885         mBuffer = dup(len, buffer);
00886         mBufferLength = len;
00887         mAmountRead = 0;
00888         return NS_OK;
00889     }
00890     
00891     static char* dup(PRUint32 len, const char* buffer) {
00892        char* result = new char[len];
00893        if (result != NULL)
00894            memcpy(result, buffer, len);
00895        return result;
00896     }
00897 
00898        nsIPluginStreamInfo* CreatePluginStreamInfo(const char* url, nsMIMEType type, PRBool seekable) {
00899               if (mStreamInfo == NULL) {
00900                      mStreamInfo = new CPluginStreamInfo(url, this, type, seekable);
00901                      NS_IF_ADDREF(mStreamInfo);
00902               }
00903               return mStreamInfo;
00904        }
00905        
00906        nsIPluginStreamInfo* GetPluginStreamInfo() {
00907               return mStreamInfo;
00908        }
00909 
00910 protected:
00911     const char* mURL;
00912     nsIPluginStreamListener* mListener;
00913     nsPluginStreamType mStreamType;
00914     NPP mNPP;
00915     NPStream* mStream;
00916     char* mBuffer;
00917     PRUint32 mBufferLength;
00918     PRUint32 mAmountRead;
00919     nsIPluginStreamInfo* mStreamInfo;
00920 };
00921 
00923 
00924 #ifdef XP_UNIX
00925 #define TRACE(foo) trace(foo)
00926 #endif
00927 
00928 #ifdef XP_MAC
00929 #undef assert
00930 #define assert(cond)
00931 #endif
00932 
00933 //#if defined(__cplusplus)
00934 //extern "C" {
00935 //#endif
00936 
00938 // SECTION 1 - Includes
00940 
00941 #if defined(XP_UNIX) || defined(XP_MAC)
00942 #include <stdio.h>
00943 #include <stdlib.h>
00944 #include <string.h>
00945 #else
00946 #include <windows.h>
00947 #endif
00948 
00950 // SECTION 2 - Global Variables
00952 #pragma mark Globals
00953 
00954 //
00955 // thePlugin and thePluginManager are used in the life of the plugin.
00956 //
00957 // These two will be created on NPP_Initialize and destroyed on NPP_Shutdown.
00958 //
00959 #pragma export on
00960 nsIPluginManager* thePluginManager = NULL;
00961 nsIPlugin* thePlugin = NULL;
00962 #pragma export off
00963 
00964 //
00965 // Interface IDs
00966 //
00967 #pragma mark IIDs
00968 
00969 static NS_DEFINE_CID(kPluginCID, NS_PLUGIN_CID);
00970 static NS_DEFINE_CID(kPluginManagerCID, NS_PLUGINMANAGER_CID);
00971 static NS_DEFINE_CID(kMemoryCID, NS_MEMORY_CID);
00972 
00973 // mapping from NPError to nsresult
00974 nsresult fromNPError[] = {
00975     NS_OK,                          // NPERR_NO_ERROR,
00976     NS_ERROR_FAILURE,               // NPERR_GENERIC_ERROR,
00977     NS_ERROR_FAILURE,               // NPERR_INVALID_INSTANCE_ERROR,
00978     NS_ERROR_NOT_INITIALIZED,       // NPERR_INVALID_FUNCTABLE_ERROR,
00979     NS_ERROR_FACTORY_NOT_LOADED,    // NPERR_MODULE_LOAD_FAILED_ERROR,
00980     NS_ERROR_OUT_OF_MEMORY,         // NPERR_OUT_OF_MEMORY_ERROR,
00981     NS_NOINTERFACE,                 // NPERR_INVALID_PLUGIN_ERROR,
00982     NS_ERROR_ILLEGAL_VALUE,         // NPERR_INVALID_PLUGIN_DIR_ERROR,
00983     NS_NOINTERFACE,                 // NPERR_INCOMPATIBLE_VERSION_ERROR,
00984     NS_ERROR_ILLEGAL_VALUE,         // NPERR_INVALID_PARAM,
00985     NS_ERROR_ILLEGAL_VALUE,         // NPERR_INVALID_URL,
00986     NS_ERROR_ILLEGAL_VALUE,         // NPERR_FILE_NOT_FOUND,
00987     NS_ERROR_FAILURE,               // NPERR_NO_DATA,
00988     NS_ERROR_FAILURE                // NPERR_STREAM_NOT_SEEKABLE,
00989 };
00990 
00992 // SECTION 4 - API Shim Plugin Implementations
00993 // Glue code to the 5.0x Plugin.
00994 //
00995 // Most of the NPP_* functions that interact with the plug-in will need to get 
00996 // the instance peer from npp->pdata so it can get the plugin instance from the
00997 // peer. Once the plugin instance is available, the appropriate 5.0 plug-in
00998 // function can be called:
00999 //          
01000 //  CPluginInstancePeer* peer = (CPluginInstancePeer* )instance->pdata;
01001 //  nsIPluginInstance* inst = peer->GetUserInstance();
01002 //  inst->NewPluginAPIFunction();
01003 //
01004 // Similar steps takes place with streams.  The stream peer is stored in NPStream's
01005 // pdata.  Get the peer, get the stream, call the function.
01006 //
01007 
01009 // UNIX-only API calls
01011 
01012 #ifdef XP_UNIX
01013 char* NPP_GetMIMEDescription(void)
01014 {
01015     int freeFac = 0;
01016     //fprintf(stderr, "MIME description\n");
01017     if (thePlugin == NULL) {
01018         freeFac = 1;
01019         NSGetFactory(thePluginManager, kPluginCID, NULL, NULL, (nsIFactory** )&thePlugin);
01020     }
01021     //fprintf(stderr, "Allocated Plugin 0x%08x\n", thePlugin);
01022     const char * ret;
01023     nsresult err = thePlugin->GetMIMEDescription(&ret);
01024     if (err) return NULL;
01025     //fprintf(stderr, "Get response %s\n", ret);
01026     if (freeFac) {
01027         //fprintf(stderr, "Freeing plugin...");
01028         thePlugin->Release();
01029         thePlugin = NULL;
01030     }
01031     //fprintf(stderr, "Done\n");
01032     return (char*)ret;
01033 }
01034 
01035 
01036 //------------------------------------------------------------------------------
01037 // Cross-Platform Plug-in API Calls
01038 //------------------------------------------------------------------------------
01039 
01040 //+++++++++++++++++++++++++++++++++++++++++++++++++
01041 // NPP_SetValue:
01042 //+++++++++++++++++++++++++++++++++++++++++++++++++
01043 
01044 NPError
01045 NPP_SetValue(NPP instance, NPNVariable variable, void *value)
01046 {
01047     return NPERR_GENERIC_ERROR; // nothing to set
01048 }
01049 
01050 //+++++++++++++++++++++++++++++++++++++++++++++++++
01051 // NPP_GetValue:
01052 //+++++++++++++++++++++++++++++++++++++++++++++++++
01053 
01054 NPError
01055 NPP_GetValue(NPP instance, NPPVariable variable, void *value) {
01056     int freeFac = 0;
01057     //fprintf(stderr, "MIME description\n");
01058     if (thePlugin == NULL) {
01059         freeFac = 1;
01060         if (NSGetFactory(thePluginManager, kPluginCID, NULL, NULL, (nsIFactory** )&thePlugin) != NS_OK)
01061             return NPERR_GENERIC_ERROR;
01062     }
01063     //fprintf(stderr, "Allocated Plugin 0x%08x\n", thePlugin);
01064     nsresult err = thePlugin->GetValue((nsPluginVariable)variable, value);
01065     if (err) return NPERR_GENERIC_ERROR;
01066     //fprintf(stderr, "Get response %08x\n", ret);
01067     if (freeFac) {
01068         //fprintf(stderr, "Freeing plugin...");
01069         thePlugin->Release();
01070         thePlugin = NULL;
01071     }
01072     //fprintf(stderr, "Done\n");
01073     return NPERR_NO_ERROR;
01074 }
01075 #endif // XP_UNIX
01076 
01077 //+++++++++++++++++++++++++++++++++++++++++++++++++
01078 // NPP_Initialize:
01079 // Provides global initialization for a plug-in, and returns an error value. 
01080 //
01081 // This function is called once when a plug-in is loaded, before the first instance
01082 // is created. thePluginManager and thePlugin are both initialized.
01083 //+++++++++++++++++++++++++++++++++++++++++++++++++
01084 
01085 NPError
01086 NPP_Initialize(void)
01087 {
01088 //    TRACE("NPP_Initialize\n");
01089 
01090     // Only call initialize the plugin if it hasn't been created.
01091     // This could happen if GetJavaClass() is called before
01092     // NPP Initialize.  
01093     if (thePluginManager == NULL) {
01094         // Create the plugin manager and plugin classes.
01095         thePluginManager = new CPluginManager(); 
01096         if ( thePluginManager == NULL ) 
01097             return NPERR_OUT_OF_MEMORY_ERROR;  
01098         thePluginManager->AddRef();
01099     }
01100     NPError error = NPERR_INVALID_PLUGIN_ERROR;  
01101     // On UNIX the plugin might have been created when calling NPP_GetMIMEType.
01102     if (thePlugin == NULL) {
01103         // create nsIPlugin factory
01104         nsresult result = NSGetFactory(thePluginManager, kPluginCID, NULL, NULL, (nsIFactory**)&thePlugin);
01105         if (result == NS_OK && thePlugin->Initialize() == NS_OK)
01106               error = NPERR_NO_ERROR;
01107       
01108        }
01109        
01110     return error;
01111 }
01112 
01113 //+++++++++++++++++++++++++++++++++++++++++++++++++
01114 // NPP_GetJavaClass:
01115 // New in Netscape Navigator 3.0. 
01116 // 
01117 // NPP_GetJavaClass is called during initialization to ask your plugin
01118 // what its associated Java class is. If you don't have one, just return
01119 // NULL. Otherwise, use the javah-generated "use_" function to both
01120 // initialize your class and return it. If you can't find your class, an
01121 // error will be signalled by "use_" and will cause the Navigator to
01122 // complain to the user.
01123 //+++++++++++++++++++++++++++++++++++++++++++++++++
01124 
01125 jref
01126 NPP_GetJavaClass(void)
01127 {
01128        jref pluginClass = NULL;
01129        if (thePlugin != NULL) {
01130               nsIJRILiveConnectPlugin* jriPlugin = NULL;
01131               if (thePlugin->QueryInterface(NS_GET_IID(nsIJRILiveConnectPlugin), (void**)&jriPlugin) == NS_OK) {
01132                      jriPlugin->GetJavaClass(NPN_GetJavaEnv(), &pluginClass);
01133                      NS_RELEASE(jriPlugin);
01134               }
01135        }
01136        return pluginClass;
01137 }
01138 
01139 //+++++++++++++++++++++++++++++++++++++++++++++++++
01140 // NPP_Shutdown:
01141 // Provides global deinitialization for a plug-in. 
01142 // 
01143 // This function is called once after the last instance of your plug-in 
01144 // is destroyed.  thePluginManager and thePlugin are delete at this time.
01145 //+++++++++++++++++++++++++++++++++++++++++++++++++
01146 
01147 void
01148 NPP_Shutdown(void)
01149 {
01150 //    TRACE("NPP_Shutdown\n");
01151 
01152     if (thePlugin)
01153     {
01154         thePlugin->Shutdown();
01155         thePlugin->Release();
01156         thePlugin = NULL;
01157     }
01158 
01159     if (thePluginManager)  {
01160         thePluginManager->Release();
01161         thePluginManager = NULL;
01162     }
01163     
01164     return;
01165 }
01166 
01167 //+++++++++++++++++++++++++++++++++++++++++++++++++
01168 // NPP_New:
01169 // Creates a new instance of a plug-in and returns an error value. 
01170 // 
01171 // A plugin instance peer and instance peer is created.  After
01172 // a successful instansiation, the peer is stored in the plugin
01173 // instance's pdata.
01174 //+++++++++++++++++++++++++++++++++++++++++++++++++
01175 
01176 NPError 
01177 NPP_New(NPMIMEType pluginType,
01178        NPP instance,
01179        PRUint16 mode,
01180        int16 argc,
01181        char* argn[],
01182        char* argv[],
01183        NPSavedData* saved)
01184 {
01185 //    TRACE("NPP_New\n");
01186     
01187     if (instance == NULL)
01188         return NPERR_INVALID_INSTANCE_ERROR;
01189 
01190     // Create a new plugin instance and start it.
01191     nsIPluginInstance* pluginInstance = NULL;
01192     thePlugin->CreatePluginInstance(thePluginManager, NS_GET_IID(nsIPluginInstance), pluginType, (void**)&pluginInstance);
01193     if (pluginInstance == NULL) {
01194         return NPERR_OUT_OF_MEMORY_ERROR;
01195     }
01196     
01197     // Create a new plugin instance peer,
01198     // XXX - Since np_instance is not implemented in the 4.0x browser, I
01199     // XXX - had to save the plugin parameter in the peer class.
01200     // XXX - Ask Warren about np_instance.
01201     CPluginInstancePeer* peer = new CPluginInstancePeer(pluginInstance, instance,
01202                                                                                            (nsMIMEType)pluginType, 
01203                                                                           (nsPluginMode)mode, (PRUint16)argc,
01204                                                                           (const char** )argn, (const char** )argv);
01205     assert( peer != NULL );
01206     if (!peer) return NPERR_OUT_OF_MEMORY_ERROR;
01207     peer->AddRef();
01208     pluginInstance->Initialize(peer);
01209     pluginInstance->Start();
01210     // Set the user instance and store the peer in npp->pdata.
01211     instance->pdata = peer;
01212     peer->Release();
01213 
01214     return NPERR_NO_ERROR;
01215 }
01216 
01217 //+++++++++++++++++++++++++++++++++++++++++++++++++
01218 // NPP_Destroy:
01219 // Deletes a specific instance of a plug-in and returns an error value. 
01220 //
01221 // The plugin instance peer and plugin instance are destroyed.
01222 // The instance's pdata is set to NULL.
01223 //+++++++++++++++++++++++++++++++++++++++++++++++++
01224 
01225 NPError 
01226 NPP_Destroy(NPP instance, NPSavedData** save)
01227 {
01228 //    TRACE("NPP_Destroy\n");
01229     
01230     if (instance == NULL)
01231         return NPERR_INVALID_INSTANCE_ERROR;
01232     
01233     CPluginInstancePeer* peer = (CPluginInstancePeer*) instance->pdata;
01234     nsIPluginInstance* pluginInstance = peer->GetInstance();
01235     pluginInstance->Stop();
01236     pluginInstance->Destroy();
01237     pluginInstance->Release();
01238        // peer->Release();
01239     instance->pdata = NULL;
01240     
01241     return NPERR_NO_ERROR;
01242 }
01243 
01244 //+++++++++++++++++++++++++++++++++++++++++++++++++
01245 // NPP_SetWindow:
01246 // Sets the window in which a plug-in draws, and returns an error value. 
01247 //+++++++++++++++++++++++++++++++++++++++++++++++++
01248 
01249 NPError 
01250 NPP_SetWindow(NPP instance, NPWindow* window)
01251 {
01252 //    TRACE("NPP_SetWindow\n");
01253     
01254     if (instance == NULL)
01255         return NPERR_INVALID_INSTANCE_ERROR;
01256 
01257     CPluginInstancePeer* peer = (CPluginInstancePeer*) instance->pdata;
01258     if ( peer == NULL)
01259         return NPERR_INVALID_PLUGIN_ERROR;
01260 
01261        // record the window in the peer, so we can deliver proper events.
01262        peer->SetWindow(window);
01263 
01264     nsIPluginInstance* pluginInstance = peer->GetInstance();
01265     if( pluginInstance == 0 )
01266         return NPERR_INVALID_PLUGIN_ERROR;
01267 
01268     return (NPError)pluginInstance->SetWindow((nsPluginWindow* ) window );
01269 }
01270 
01271 //+++++++++++++++++++++++++++++++++++++++++++++++++
01272 // NPP_NewStream:
01273 // Notifies an instance of a new data stream and returns an error value. 
01274 //
01275 // Create a stream peer and stream.  If succesful, save
01276 // the stream peer in NPStream's pdata.
01277 //+++++++++++++++++++++++++++++++++++++++++++++++++
01278 
01279 NPError 
01280 NPP_NewStream(NPP instance,
01281               NPMIMEType type,
01282               NPStream *stream, 
01283               NPBool seekable,
01284               PRUint16 *stype)
01285 {
01286     // XXX - How do you set the fields of the peer stream and stream?
01287     // XXX - Looks like these field will have to be created since
01288     // XXX - We are not using np_stream.
01289    
01290 //    TRACE("NPP_NewStream\n");
01291 
01292     if (instance == NULL)
01293         return NPERR_INVALID_INSTANCE_ERROR;
01294                             
01295     CPluginInputStream* inStr = (CPluginInputStream*)stream->notifyData;
01296     if (inStr == NULL)
01297         return NPERR_GENERIC_ERROR;
01298     
01299     nsIPluginStreamInfo* info = inStr->CreatePluginStreamInfo(stream->url, type, seekable);
01300     nsresult err = inStr->GetListener()->OnStartBinding(info);
01301     if (err) return err;
01302 
01303     inStr->SetStreamInfo(instance, stream);
01304     stream->pdata = inStr;
01305     *stype = inStr->GetStreamType();
01306 
01307     return NPERR_NO_ERROR;
01308 }
01309 
01310 //+++++++++++++++++++++++++++++++++++++++++++++++++
01311 // NPP_WriteReady:
01312 // Returns the maximum number of bytes that an instance is prepared to accept
01313 // from the stream. 
01314 //+++++++++++++++++++++++++++++++++++++++++++++++++
01315 
01316 int32 
01317 NPP_WriteReady(NPP instance, NPStream *stream)
01318 {
01319 //    TRACE("NPP_WriteReady\n");
01320 
01321     if (instance == NULL)
01322         return -1;
01323 
01324     CPluginInputStream* inStr = (CPluginInputStream*)stream->pdata;
01325     if (inStr == NULL)
01326         return -1;
01327     return NP_MAXREADY;
01328 }
01329 
01330 
01331 //+++++++++++++++++++++++++++++++++++++++++++++++++
01332 // NPP_Write:
01333 // Delivers data from a stream and returns the number of bytes written. 
01334 //+++++++++++++++++++++++++++++++++++++++++++++++++
01335 
01336 int32 
01337 NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer)
01338 {
01339 //    TRACE("NPP_Write\n");
01340 
01341     if (instance == NULL)
01342         return -1;
01343        
01344     CPluginInputStream* inStr = (CPluginInputStream*)stream->pdata;
01345     if (inStr == NULL)
01346         return -1;
01347     nsresult err = inStr->SetReadBuffer((PRUint32)len, (const char*)buffer);
01348     if (err != NS_OK) return -1;
01349     err = inStr->GetListener()->OnDataAvailable(inStr->GetPluginStreamInfo(), inStr, len);
01350     if (err != NS_OK) return -1;
01351     return len;
01352 }
01353 
01354 //+++++++++++++++++++++++++++++++++++++++++++++++++
01355 // NPP_DestroyStream:
01356 // Indicates the closure and deletion of a stream, and returns an error value. 
01357 //
01358 // The stream peer and stream are destroyed.  NPStream's
01359 // pdata is set to NULL.
01360 //+++++++++++++++++++++++++++++++++++++++++++++++++
01361 
01362 NPError 
01363 NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason)
01364 {
01365 //    TRACE("NPP_DestroyStream\n");
01366 
01367     if (instance == NULL)
01368         return NPERR_INVALID_INSTANCE_ERROR;
01369               
01370     CPluginInputStream* inStr = (CPluginInputStream*)stream->pdata;
01371     if (inStr == NULL)
01372         return NPERR_GENERIC_ERROR;
01373     inStr->GetListener()->OnStopBinding(inStr->GetPluginStreamInfo(), (nsPluginReason)reason);
01374     // inStr->Release();
01375     stream->pdata = NULL;
01376        
01377     return NPERR_NO_ERROR;
01378 }
01379 
01380 //+++++++++++++++++++++++++++++++++++++++++++++++++
01381 // NPP_StreamAsFile:
01382 // Provides a local file name for the data from a stream. 
01383 //+++++++++++++++++++++++++++++++++++++++++++++++++
01384 
01385 void 
01386 NPP_StreamAsFile(NPP instance, NPStream *stream, const char* fname)
01387 {
01388 //    TRACE("NPP_StreamAsFile\n");
01389 
01390     if (instance == NULL)
01391         return;
01392               
01393     CPluginInputStream* inStr = (CPluginInputStream*)stream->pdata;
01394     if (inStr == NULL)
01395         return;
01396     (void)inStr->GetListener()->OnFileAvailable(inStr->GetPluginStreamInfo(), fname);
01397 }
01398 
01399 //+++++++++++++++++++++++++++++++++++++++++++++++++
01400 // NPP_Print:
01401 //+++++++++++++++++++++++++++++++++++++++++++++++++
01402 
01403 void 
01404 NPP_Print(NPP instance, NPPrint* printInfo)
01405 {
01406 //    TRACE("NPP_Print\n");
01407 
01408     if(printInfo == NULL)   // trap invalid parm
01409         return;
01410 
01411     if (instance != NULL)
01412     {
01413         CPluginInstancePeer* peer = (CPluginInstancePeer*) instance->pdata;
01414         nsIPluginInstance* pluginInstance = peer->GetInstance();
01415         pluginInstance->Print((nsPluginPrint* ) printInfo );
01416     }
01417 }
01418 
01419 //+++++++++++++++++++++++++++++++++++++++++++++++++
01420 // NPP_URLNotify:
01421 // Notifies the instance of the completion of a URL request. 
01422 //+++++++++++++++++++++++++++++++++++++++++++++++++
01423 
01424 void
01425 NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData)
01426 {
01427 //    TRACE("NPP_URLNotify\n");
01428 
01429     if (instance != NULL) {
01430         CPluginInputStream* inStr = (CPluginInputStream*)notifyData;
01431         (void)inStr->GetListener()->OnStopBinding(inStr->GetPluginStreamInfo(), (nsPluginReason)reason);
01432         inStr->Release();
01433     }
01434 }
01435 
01436 //+++++++++++++++++++++++++++++++++++++++++++++++++
01437 // NPP_HandleEvent:
01438 // Mac-only, but stub must be present for Windows
01439 // Delivers a platform-specific event to the instance. 
01440 //+++++++++++++++++++++++++++++++++++++++++++++++++
01441 
01442 #ifndef XP_UNIX
01443 int16
01444 NPP_HandleEvent(NPP instance, void* event)
01445 {
01446 //    TRACE("NPP_HandleEvent\n");
01447     int16 eventHandled = FALSE;
01448     if (instance == NULL)
01449         return eventHandled;
01450        
01451     NPEvent* npEvent = (NPEvent*) event;
01452     nsPluginEvent pluginEvent = {
01453 #ifdef XP_MAC
01454         npEvent, NULL
01455 #else
01456         npEvent->event, npEvent->wParam, npEvent->lParam
01457 #endif
01458     };
01459        
01460     CPluginInstancePeer* peer = (CPluginInstancePeer*) instance->pdata;
01461     nsIPluginInstance* pluginInstance = peer->GetInstance();
01462     if (pluginInstance) {
01463         PRBool handled;
01464         nsresult err = pluginInstance->HandleEvent(&pluginEvent, &handled);
01465         if (err) return FALSE;
01466         eventHandled = (handled == PR_TRUE);
01467     }
01468        
01469     return eventHandled;
01470 }
01471 #endif // ndef XP_UNIX 
01472 
01474 // SECTION 5 - API Browser Implementations
01475 //
01476 // Glue code to the 4.0x Browser.
01478 
01480 //
01481 // CPluginManager
01482 //
01483 
01484 //******************************************************************************
01485 //
01486 // Once we moved to the new APIs, we need to implement fJVMMgr.
01487 //
01488 //******************************************************************************
01489 
01490 CPluginManager::CPluginManager(void)
01491 {
01492     mLiveconnect = NULL;
01493 
01494 #ifdef XP_MAC
01495     mEventFiltersInstalled = false;
01496 #endif
01497 }
01498 
01499 CPluginManager::~CPluginManager(void) 
01500 {
01501        NS_IF_RELEASE(mLiveconnect);
01502 
01503 #ifdef XP_MAC 
01504        if (mEventFiltersInstalled)
01505               RemoveEventFilters();
01506 #endif
01507 }
01508 
01509 //+++++++++++++++++++++++++++++++++++++++++++++++++
01510 // ReloadPlugins:
01511 //+++++++++++++++++++++++++++++++++++++++++++++++++
01512 
01513 NS_METHOD
01514 CPluginManager::ReloadPlugins(PRBool reloadPages)
01515 {
01516     NPN_ReloadPlugins(reloadPages);
01517     return NS_OK;
01518 }
01519 
01520 NS_METHOD
01521 CPluginManager::GetURL(nsISupports* pluginInst, 
01522                        const char* url, 
01523                        const char* target,
01524                        nsIPluginStreamListener* streamListener,
01525                        const char* altHost,
01526                        const char* referrer,
01527                        PRBool forceJSEnabled)
01528 {
01529     if (altHost != NULL || referrer != NULL || forceJSEnabled != PR_FALSE) {
01530         return NPERR_INVALID_PARAM;
01531     }
01532 
01533     nsIPluginInstance* inst = NULL;
01534     nsresult rslt = pluginInst->QueryInterface(NS_GET_IID(nsIPluginInstance), (void**)&inst);
01535     if (rslt != NS_OK) return rslt;
01536        CPluginInstancePeer* instancePeer = NULL;
01537     rslt = inst->GetPeer((nsIPluginInstancePeer**)&instancePeer);
01538     if (rslt != NS_OK) {
01539         inst->Release();
01540         return rslt;
01541     }
01542     NPP npp = instancePeer->GetNPPInstance();
01543 
01544     NPError err;
01545     if (streamListener) {
01546         CPluginInputStream* inStr = new CPluginInputStream(streamListener);
01547         if (inStr == NULL) {
01548             instancePeer->Release();
01549             inst->Release();
01550             return NS_ERROR_OUT_OF_MEMORY;
01551         }
01552         inStr->AddRef();
01553     
01554         err = NPN_GetURLNotify(npp, url, target, inStr);
01555     }
01556     else {
01557         err = NPN_GetURL(npp, url, target);
01558     }
01559     instancePeer->Release();
01560     inst->Release();
01561     return fromNPError[err];
01562 }
01563 
01564 NS_METHOD
01565 CPluginManager::PostURL(nsISupports* pluginInst,
01566                         const char* url,
01567                         PRUint32 postDataLen, 
01568                         const char* postData,
01569                         PRBool isFile,
01570                         const char* target,
01571                         nsIPluginStreamListener* streamListener,
01572                         const char* altHost, 
01573                         const char* referrer,
01574                         PRBool forceJSEnabled,
01575                         PRUint32 postHeadersLength, 
01576                         const char* postHeaders)
01577 {
01578     if (altHost != NULL || referrer != NULL || forceJSEnabled != PR_FALSE
01579         || postHeadersLength != 0 || postHeaders != NULL) {
01580         return NPERR_INVALID_PARAM;
01581     }
01582 
01583     nsIPluginInstance* inst = NULL;
01584     nsresult rslt = pluginInst->QueryInterface(NS_GET_IID(nsIPluginInstance), (void**)&inst);
01585     if (rslt != NS_OK) return rslt;
01586        CPluginInstancePeer* instancePeer = NULL;
01587     rslt = inst->GetPeer((nsIPluginInstancePeer**)&instancePeer);
01588     if (rslt != NS_OK) {
01589         inst->Release();
01590         return rslt;
01591     }
01592     NPP npp = instancePeer->GetNPPInstance();
01593 
01594     NPError err;
01595     if (streamListener) {
01596         CPluginInputStream* inStr = new CPluginInputStream(streamListener);
01597         if (inStr == NULL) {
01598             instancePeer->Release();
01599             inst->Release();
01600             return NS_ERROR_OUT_OF_MEMORY;
01601         }
01602         inStr->AddRef();
01603     
01604         err = NPN_PostURLNotify(npp, url, target, postDataLen, postData, isFile, inStr);
01605     }
01606     else {
01607         err = NPN_PostURL(npp, url, target, postDataLen, postData, isFile);
01608     }
01609     instancePeer->Release();
01610     inst->Release();
01611     return fromNPError[err];
01612 }
01613 
01614 NS_IMETHODIMP
01615 CPluginManager::RegisterPlugin(REFNSIID aCID,
01616                                const char* aPluginName,
01617                                const char* aDescription,
01618                                const char** aMimeTypes,
01619                                const char** aMimeDescriptions,
01620                                const char** aFileExtensions,
01621                                PRInt32 aCount)
01622 {
01623     // XXXwaterson I don't think we need to do anything here.
01624     return NS_OK;
01625 }
01626 
01627 NS_IMETHODIMP
01628 CPluginManager::UnregisterPlugin(REFNSIID aCID)
01629 {
01630     // XXXwaterson I don't think we need to do anything here.
01631     return NS_OK;
01632 }
01633 
01634 NS_IMETHODIMP
01635 CPluginManager::GetURLWithHeaders(nsISupports* pluginInst, 
01636                                   const char* url, 
01637                                   const char* target,
01638                                   nsIPluginStreamListener* streamListener,
01639                                   const char* altHost,
01640                                   const char* referrer,
01641                                   PRBool forceJSEnabled,
01642                                   PRUint32 getHeadersLength, 
01643                                   const char* getHeaders)
01644 {
01645     return NS_ERROR_NOT_IMPLEMENTED;
01646 }
01647 
01649 // nsIPluginManager2 methods.
01650 
01651 
01652 
01653 //+++++++++++++++++++++++++++++++++++++++++++++++++
01654 // UserAgent:
01655 //+++++++++++++++++++++++++++++++++++++++++++++++++
01656 
01657 NS_METHOD
01658 CPluginManager::UserAgent(const char* *result)
01659 {
01660     *result = NPN_UserAgent(NULL);
01661     return NS_OK;
01662 }
01663 
01664 
01665 int varMap[] = {
01666     (int)NPNVxDisplay,                  // nsPluginManagerVariable_XDisplay = 1,
01667     (int)NPNVxtAppContext,              // nsPluginManagerVariable_XtAppContext,
01668     (int)NPNVnetscapeWindow,            // nsPluginManagerVariable_NetscapeWindow,
01669     (int)NPPVpluginWindowBool,          // nsPluginInstancePeerVariable_WindowBool,
01670     (int)NPPVpluginTransparentBool,     // nsPluginInstancePeerVariable_TransparentBool,
01671     (int)NPPVjavaClass,                 // nsPluginInstancePeerVariable_JavaClass,
01672     (int)NPPVpluginWindowSize,          // nsPluginInstancePeerVariable_WindowSize,
01673     (int)NPPVpluginTimerInterval,       // nsPluginInstancePeerVariable_TimerInterval
01674 };
01675 
01676 //+++++++++++++++++++++++++++++++++++++++++++++++++
01677 // GetValue:
01678 //+++++++++++++++++++++++++++++++++++++++++++++++++
01679 
01680 NS_METHOD
01681 CPluginManager::GetValue(nsPluginManagerVariable variable, void *value)
01682 {
01683 #ifdef XP_UNIX
01684     return fromNPError[NPN_GetValue(NULL, (NPNVariable)varMap[(int)variable], value)];
01685 #else
01686     return fromNPError[NPERR_GENERIC_ERROR];
01687 #endif // XP_UNIX
01688 }
01689 
01691 // nsIPluginManager2 methods.
01693 
01694 CPluginManager::RegisteredWindow* CPluginManager::theRegisteredWindows = NULL;
01695 CPluginManager::RegisteredWindow* CPluginManager::theActiveWindow = NULL;
01696 
01697 CPluginManager::RegisteredWindow** CPluginManager::GetRegisteredWindow(nsPluginPlatformWindowRef window)
01698 {
01699        RegisteredWindow** link = &theRegisteredWindows;
01700        RegisteredWindow* registeredWindow = *link;
01701        while (registeredWindow != NULL) {
01702               if (registeredWindow->mWindow == window)
01703                      return link;
01704               link = &registeredWindow->mNext;
01705               registeredWindow = *link;
01706        }
01707        return NULL;
01708 }
01709 
01710 CPluginManager::RegisteredWindow* CPluginManager::FindRegisteredWindow(nsPluginPlatformWindowRef window)
01711 {
01712        RegisteredWindow** link = GetRegisteredWindow(window);
01713        return (link != NULL ? *link : NULL);
01714 }
01715 
01716 
01717 NS_METHOD
01718 CPluginManager::RegisterWindow(nsIEventHandler* handler, nsPluginPlatformWindowRef window)
01719 {
01720        theRegisteredWindows = new RegisteredWindow(theRegisteredWindows, handler, window);
01721        
01722 #ifdef XP_MAC
01723        // use jGNE to obtain events for registered windows.
01724        if (!mEventFiltersInstalled) {
01725               ::InstallEventFilters(&EventFilter, &MenuFilter);
01726               mEventFiltersInstalled = true;
01727        }
01728 
01729        // plugin expects the window to be shown and selected at this point.
01730        
01731        SInt16 variant = ::GetWVariant(window);
01732        if (variant == plainDBox) {
01733               ::ShowHide(window, true);
01734               ::BringToFront(window);
01735        } else {
01736               ::ShowWindow(window);
01737               ::SelectWindow(window);
01738        }
01739 #endif
01740 
01741        return NS_OK;
01742 }
01743 
01744 NS_METHOD
01745 CPluginManager::UnregisterWindow(nsIEventHandler* handler, nsPluginPlatformWindowRef window)
01746 {
01747        RegisteredWindow** link = GetRegisteredWindow(window);
01748        if (link != NULL) {
01749               RegisteredWindow* registeredWindow = *link;
01750               if (registeredWindow == theActiveWindow)
01751                      theActiveWindow = NULL;
01752               *link = registeredWindow->mNext;
01753               delete registeredWindow;
01754        }
01755 
01756 #ifdef XP_MAC
01757        ::HideWindow(window);
01758 
01759        // if no windows registered, remove the filter.
01760        if (theRegisteredWindows == NULL) {
01761               ::RemoveEventFilters();
01762               mEventFiltersInstalled = false;
01763        }
01764 #endif
01765 
01766        return NS_OK;
01767 }
01768 
01769 #ifdef XP_MAC
01770 
01771 static void sendActivateEvent(nsIEventHandler* handler, WindowRef window, Boolean active)
01772 {
01773        EventRecord event;
01774        ::OSEventAvail(0, &event);
01775        event.what = activateEvt;
01776        event.message = UInt32(window);
01777        if (active)
01778               event.modifiers |= activeFlag;
01779        else
01780               event.modifiers &= ~activeFlag;
01781 
01782        nsPluginEvent pluginEvent = { &event, window };
01783        PRBool handled = PR_FALSE;
01784 
01785        handler->HandleEvent(&pluginEvent, &handled);
01786 }
01787 
01795 Boolean CPluginManager::EventFilter(EventRecord* event)
01796 {
01797        Boolean filteredEvent = false;
01798 
01799        WindowRef window = WindowRef(event->message);
01800     nsPluginEvent pluginEvent = { event, window };
01801     EventRecord simulatedEvent;
01802 
01803     RegisteredWindow* registeredWindow;
01804        PRBool handled = PR_FALSE;
01805     
01806        // see if this event is for one of our registered windows.
01807        switch (event->what) {
01808        case nullEvent:
01809               // See if the frontmost window is one of our registered windows.
01810               // we want to somehow deliver mouse enter/leave events.
01811               window = ::FrontWindow();
01812               registeredWindow = FindRegisteredWindow(window);
01813               if (registeredWindow != NULL) {
01814                      simulatedEvent = *event;
01815                      simulatedEvent.what = nsPluginEventType_AdjustCursorEvent;
01816                      pluginEvent.event = &simulatedEvent;
01817                      pluginEvent.window = registeredWindow->mWindow;
01818                      registeredWindow->mHandler->HandleEvent(&pluginEvent, &handled);
01819               }
01820               break;
01821        case keyDown:
01822        case keyUp:
01823        case autoKey:
01824               // See if the frontmost window is one of our registered windows.
01825               window = ::FrontWindow();
01826               registeredWindow = FindRegisteredWindow(window);
01827               if (registeredWindow != NULL) {
01828                      pluginEvent.window = window;
01829                      registeredWindow->mHandler->HandleEvent(&pluginEvent, &handled);
01830                      filteredEvent = true;
01831               }
01832               break;
01833        case mouseDown:
01834               // use FindWindow to see if the click was in one our registered windows.
01835               short partCode = FindWindow(event->where, &window);
01836               switch (partCode) {
01837               case inContent:
01838               case inDrag:
01839               case inGrow:
01840               case inGoAway:
01841               case inZoomIn:
01842               case inZoomOut:
01843               case inCollapseBox:
01844               case inProxyIcon:
01845                      registeredWindow = FindRegisteredWindow(window);
01846                      if (registeredWindow != NULL) {
01847                             // make sure this window has been activated before passing it the click.
01848                             if (theActiveWindow == NULL) {
01849                                    sendActivateEvent(registeredWindow->mHandler, window, true);
01850                                    theActiveWindow = registeredWindow;
01851                             }
01852                             pluginEvent.window = window;
01853                             registeredWindow->mHandler->HandleEvent(&pluginEvent, &handled);
01854                             filteredEvent = true;
01855                      } else if (theActiveWindow != NULL) {
01856                             // a click is going into an unregistered window, if we are active,
01857                             // the browser doesn't seem to be generating a deactivate event.
01858                             // I think this is because PowerPlant is managing the windows, dang it.
01859                             window = theActiveWindow->mWindow;
01860                             sendActivateEvent(theActiveWindow->mHandler, window, false);
01861                             ::HiliteWindow(window, false);
01862                             theActiveWindow = NULL;
01863                      }
01864                      break;
01865               }
01866               break;
01867        case activateEvt:
01868               registeredWindow = FindRegisteredWindow(window);
01869               if (registeredWindow != NULL) {
01870                      registeredWindow->mHandler->HandleEvent(&pluginEvent, &handled);
01871                      filteredEvent = true;
01872                      theActiveWindow = registeredWindow;
01873               }
01874               break;
01875        case updateEvt:
01876               registeredWindow = FindRegisteredWindow(window);
01877               if (registeredWindow != NULL) {
01878                      GrafPtr port; GetPort(&port); SetPort(window); BeginUpdate(window);
01879                             registeredWindow->mHandler->HandleEvent(&pluginEvent, &handled);
01880                      EndUpdate(window); SetPort(port);
01881                      filteredEvent = true;
01882               }
01883               break;
01884        case osEvt:
01885               if ((event->message & osEvtMessageMask) == (suspendResumeMessage << 24)) {
01886                      registeredWindow = theActiveWindow;
01887                      if (registeredWindow != NULL) {
01888                             window = registeredWindow->mWindow;
01889                             Boolean active = (event->message & resumeFlag) != 0;
01890                             sendActivateEvent(registeredWindow->mHandler, window, active);
01891                             pluginEvent.window = window;
01892                             registeredWindow->mHandler->HandleEvent(&pluginEvent, &handled);
01893                             ::HiliteWindow(window, active);
01894                      }
01895               }
01896               break;
01897        }
01898        
01899        return filteredEvent;
01900 }
01901 
01902 // TODO:  find out what range of menus Communicator et. al. uses.
01903 enum {
01904        kBaseMenuID = 20000,
01905        kBaseSubMenuID = 200
01906 };
01907 
01908 static PRInt16 nextMenuID = kBaseMenuID;
01909 static PRInt16 nextSubMenuID = kBaseSubMenuID;
01910 
01911 Boolean CPluginManager::MenuFilter(long menuSelection)
01912 {
01913        if (theActiveWindow != NULL) {
01914               UInt16 menuID = (menuSelection >> 16);
01915               if ((menuID >= kBaseMenuID && menuID < nextMenuID) || (menuID >= kBaseSubMenuID && menuID < nextSubMenuID)) {
01916                      EventRecord menuEvent;
01917                      ::OSEventAvail(0, &menuEvent);
01918                      menuEvent.what = nsPluginEventType_MenuCommandEvent;
01919                      menuEvent.message = menuSelection;
01920 
01921                      WindowRef window = theActiveWindow->mWindow;
01922               nsPluginEvent pluginEvent = { &menuEvent, window };
01923                      PRBool handled = PR_FALSE;
01924                      theActiveWindow->mHandler->HandleEvent(&pluginEvent, &handled);
01925                      
01926                      return handled;
01927               }
01928        }
01929        return false;
01930 }
01931 
01932 NS_METHOD
01933 CPluginManager::AllocateMenuID(nsIEventHandler* handler, PRBool isSubmenu, PRInt16 *result)
01934 {
01935        *result = (isSubmenu ? nextSubMenuID++ : nextMenuID++);
01936 
01937        return NS_OK;
01938 }
01939 
01940 #else /* !XP_MAC */
01941 
01942 NS_METHOD
01943 CPluginManager::AllocateMenuID(nsIEventHandler* handler, PRBool isSubmenu, PRInt16 *result)
01944 {
01945        return NS_ERROR_NOT_IMPLEMENTED;
01946 }
01947 
01948 #endif /* XP_MAC */
01949 
01951 // nsIServiceManager methods.
01953 
01954 NS_METHOD
01955 CPluginManager::GetService(const nsCID& aClass, const nsIID& aIID, void* *result)
01956 {
01957     // the only service we support currently is nsIMemory.
01958     if (aClass.Equals(kPluginManagerCID) || aClass.Equals(kMemoryCID)) {
01959         return QueryInterface(aIID, result);
01960     }
01961     if (!aClass.Equals(nsILiveconnect::GetCID())) {
01962         return NS_ERROR_SERVICE_NOT_FOUND;
01963     }
01964     if (mLiveconnect == NULL) {
01965         mLiveconnect = new nsLiveconnect;
01966         if (!mLiveconnect)
01967             return NS_ERROR_OUT_OF_MEMORY;
01968         NS_ADDREF(mLiveconnect);
01969     }
01970     return mLiveconnect->QueryInterface(aIID, result);
01971 }
01972 
01974 // nsIMemory methods.
01976 
01977 NS_METHOD_(void*)
01978 CPluginManager::Alloc(size_t size)
01979 {
01980        return ::NPN_MemAlloc(size);
01981 }
01982 
01983 NS_METHOD_(void*)
01984 CPluginManager::Realloc(void* ptr, size_t size)
01985 {
01986        if (ptr != NULL) {
01987               void* new_ptr = Alloc(size);
01988               if (new_ptr != NULL) {
01989                      ::memcpy(new_ptr, ptr, size);
01990                      Free(ptr);
01991               }
01992               ptr = new_ptr;
01993        }
01994        return ptr;
01995 }
01996 
01997 NS_METHOD_(void)
01998 CPluginManager::Free(void* ptr)
01999 {
02000        if (ptr != NULL) {
02001               ::NPN_MemFree(ptr);
02002        }
02003 }
02004 
02005 NS_METHOD
02006 CPluginManager::HeapMinimize(PRBool aImmediate)
02007 {
02008 #ifdef XP_MAC
02009        ::NPN_MemFlush(1024);
02010 #endif
02011        return NS_OK;
02012 }
02013 
02014 //+++++++++++++++++++++++++++++++++++++++++++++++++
02015 // nsISupports methods
02016 //+++++++++++++++++++++++++++++++++++++++++++++++++
02017 
02018 NS_METHOD
02019 CPluginManager::QueryInterface(const nsIID& iid, void** ptr) 
02020 {                                                                        
02021     if (NULL == ptr) {                                            
02022         return NS_ERROR_NULL_POINTER;                                        
02023     }
02024     
02025     if (iid.Equals(NS_GET_IID(nsIPluginManager)) || iid.Equals(NS_GET_IID(nsIPluginManager2))) {
02026         *ptr = (void*) ((nsIPluginManager2*)this);                        
02027         AddRef();                                                            
02028         return NS_OK;                                                        
02029     }                                                                      
02030     if (iid.Equals(NS_GET_IID(nsIServiceManager))) {                                                          
02031         *ptr = (void*) (nsIServiceManager*)this;                                        
02032         AddRef();                                                            
02033         return NS_OK;                                                        
02034     }
02035     if (iid.Equals(NS_GET_IID(nsIMemory))) {                                                          
02036         *ptr = (void*) (nsIMemory*)this;                                        
02037         AddRef();                                                            
02038         return NS_OK;                                                        
02039     }
02040     if (iid.Equals(NS_GET_IID(nsISupports))) {
02041         *ptr = (void*) this;                        
02042         AddRef();                                                            
02043         return NS_OK;                                                        
02044     }                                                                      
02045     return NS_NOINTERFACE;                                                 
02046 }
02047 
02048 NS_IMPL_ADDREF(CPluginManager)
02049 NS_IMPL_RELEASE(CPluginManager)
02050 
02052 //
02053 // CPluginInstancePeer
02054 //
02055 
02056 CPluginInstancePeer::CPluginInstancePeer(nsIPluginInstance* pluginInstance,
02057                                          NPP npp,
02058                                          nsMIMEType typeString, 
02059                                          nsPluginMode type,
02060                                          PRUint16 attr_cnt, 
02061                                          const char** attr_list,
02062                                          const char** val_list)
02063     :  mInstance(pluginInstance), mWindow(NULL),
02064               npp(npp), typeString(typeString), type(type), attribute_cnt(attr_cnt),
02065               attribute_list(NULL), values_list(NULL)
02066 {
02067     NS_IF_ADDREF(mInstance);
02068 
02069     attribute_list = (char**) NPN_MemAlloc(attr_cnt * sizeof(const char*));
02070     values_list = (char**) NPN_MemAlloc(attr_cnt * sizeof(const char*));
02071 
02072     if (attribute_list != NULL && values_list != NULL) {
02073         for (int i = 0; i < attribute_cnt; i++)   {
02074             attribute_list[i] = (char*) NPN_MemAlloc(strlen(attr_list[i]) + 1);
02075             if (attribute_list[i] != NULL)
02076                 strcpy(attribute_list[i], attr_list[i]);
02077 
02078             values_list[i] = (char*) NPN_MemAlloc(strlen(val_list[i]) + 1);
02079             if (values_list[i] != NULL)
02080                 strcpy(values_list[i], val_list[i]);
02081         }
02082     }
02083 }
02084 
02085 CPluginInstancePeer::~CPluginInstancePeer(void) 
02086 {
02087     if (attribute_list != NULL && values_list != NULL) {
02088         for (int i = 0; i < attribute_cnt; i++)   {
02089             NPN_MemFree(attribute_list[i]);
02090             NPN_MemFree(values_list[i]);
02091         }
02092 
02093         NPN_MemFree(attribute_list);
02094         NPN_MemFree(values_list);
02095     }
02096     
02097     NS_IF_RELEASE(mInstance);
02098 }
02099 
02100 
02101 //+++++++++++++++++++++++++++++++++++++++++++++++++
02102 // GetValue:
02103 //+++++++++++++++++++++++++++++++++++++++++++++++++
02104 
02105 NS_METHOD
02106 CPluginInstancePeer::GetValue(nsPluginInstancePeerVariable variable, void *value)
02107 {
02108 #ifdef XP_UNIX
02109     return fromNPError[NPN_GetValue(NULL, (NPNVariable)varMap[(int)variable], value)];
02110 #else
02111     return fromNPError[NPERR_GENERIC_ERROR];
02112 #endif // XP_UNIX
02113 }
02114 
02115 //+++++++++++++++++++++++++++++++++++++++++++++++++
02116 // SetValue:
02117 //+++++++++++++++++++++++++++++++++++++++++++++++++
02118 
02119 NS_METHOD
02120 CPluginInstancePeer::SetValue(nsPluginInstancePeerVariable variable, void *value) 
02121 {
02122 #ifdef XP_UNIX
02123     return fromNPError[NPN_SetValue(NULL, (NPPVariable)varMap[(int)variable], value)];
02124 #else
02125     return fromNPError[NPERR_GENERIC_ERROR];
02126 #endif // XP_UNIX
02127 }
02128 
02129 //+++++++++++++++++++++++++++++++++++++++++++++++++
02130 // GetMIMEType:
02131 // Corresponds to NPP_New's MIMEType argument.
02132 //+++++++++++++++++++++++++++++++++++++++++++++++++
02133 
02134 NS_METHOD
02135 CPluginInstancePeer::GetMIMEType(nsMIMEType *result) 
02136 {
02137     *result = typeString;
02138     return NS_OK;
02139 }
02140 
02141 //+++++++++++++++++++++++++++++++++++++++++++++++++
02142 // GetMode:
02143 // Corresponds to NPP_New's mode argument.
02144 //+++++++++++++++++++++++++++++++++++++++++++++++++
02145 
02146 NS_METHOD
02147 CPluginInstancePeer::GetMode(nsPluginMode *result)
02148 {
02149     *result = type;
02150     return NS_OK;
02151 }
02152 
02153 
02154 // Get a ptr to the paired list of attribute names and values,
02155 // returns the length of the array.
02156 //
02157 // Each name or value is a null-terminated string.
02158 NS_METHOD
02159 CPluginInstancePeer::GetAttributes(PRUint16& n, const char* const*& names, const char* const*& values)  
02160 {
02161     n = attribute_cnt;
02162     names = attribute_list;
02163     values = values_list;
02164 
02165     return NS_OK;
02166 }
02167 
02176 NS_METHOD
02177 CPluginInstancePeer::GetJavaEnv(JRIEnv* *resultingEnv)
02178 {
02179        *resultingEnv = NPN_GetJavaEnv();
02180        return NS_OK;
02181 }
02182 
02193 NS_METHOD
02194 CPluginInstancePeer::GetJavaPeer(jref *resultingJavaPeer)
02195 {
02196        *resultingJavaPeer = NPN_GetJavaPeer(npp);
02197        return NS_OK;
02198 }
02199 
02200 #if defined(XP_MAC)
02201 
02202 inline unsigned char toupper(unsigned char c)
02203 {
02204     return (c >= 'a' && c <= 'z') ? (c - ('a' - 'A')) : c;
02205 }
02206 
02207 static int strcasecmp(const char * str1, const char * str2)
02208 {
02209 #if __POWERPC__
02210        
02211     const     unsigned char * p1 = (unsigned char *) str1 - 1;
02212     const     unsigned char * p2 = (unsigned char *) str2 - 1;
02213     unsigned long           c1, c2;
02214               
02215     while (toupper(c1 = *++p1) == toupper(c2 = *++p2))
02216         if (!c1)
02217             return(0);
02218 
02219 #else
02220        
02221     const     unsigned char * p1 = (unsigned char *) str1;
02222     const     unsigned char * p2 = (unsigned char *) str2;
02223     unsigned char           c1, c2;
02224        
02225     while (toupper(c1 = *p1++) == toupper(c2 = *p2++))
02226         if (!c1)
02227             return(0);
02228 
02229 #endif
02230        
02231     return(toupper(c1) - toupper(c2));
02232 }
02233 
02234 #endif /* XP_MAC */
02235 
02236 // Get the value for the named attribute.  Returns null
02237 // if the attribute was not set.
02238 NS_METHOD
02239 CPluginInstancePeer::GetAttribute(const char* name, const char* *result) 
02240 {
02241     for (int i=0; i < attribute_cnt; i++)  {
02242 #if defined(XP_UNIX) || defined(XP_MAC)
02243         if (strcasecmp(name, attribute_list[i]) == 0)
02244 #else
02245             if (stricmp(name, attribute_list[i]) == 0) 
02246 #endif
02247             {
02248                 *result = values_list[i];
02249                 return NS_OK;
02250             }
02251     }
02252 
02253     return NS_ERROR_FAILURE;
02254 }
02255 
02266 NS_METHOD
02267 CPluginInstancePeer::GetDOMElement(nsIDOMElement* *result)
02268 {
02271        return NS_OK;
02272 }
02273 
02274 //+++++++++++++++++++++++++++++++++++++++++++++++++
02275 // NewStream:
02276 //+++++++++++++++++++++++++++++++++++++++++++++++++
02277 NS_METHOD
02278 CPluginInstancePeer::NewStream(nsMIMEType type, const char* target, 
02279                                nsIOutputStream* *result)
02280 {
02281     assert( npp != NULL );
02282     
02283     // Create a new NPStream.
02284     NPStream* ptr = NULL;
02285     NPError error = NPN_NewStream(npp, (NPMIMEType)type, target, &ptr);
02286   if (error != NPERR_NO_ERROR)
02287         return fromNPError[error];
02288     
02289     // Create a new Plugin Manager Stream.
02290     // XXX - Do we have to Release() the manager stream before doing this?
02291     // XXX - See the BAM doc for more info.
02292     CPluginManagerStream* mstream = new CPluginManagerStream(npp, ptr);
02293     if (mstream == NULL) 
02294         return NS_ERROR_OUT_OF_MEMORY;
02295     mstream->AddRef();
02296     *result = (nsIOutputStream* )mstream;
02297 
02298     return NS_OK;
02299 }
02300 
02301 //+++++++++++++++++++++++++++++++++++++++++++++++++
02302 // ShowStatus:
02303 //+++++++++++++++++++++++++++++++++++++++++++++++++
02304 
02305 NS_METHOD
02306 CPluginInstancePeer::ShowStatus(const char* message)
02307 {
02308     assert( message != NULL );
02309 
02310     NPN_Status(npp, message);
02311        return NS_OK;
02312 }
02313 
02314 NS_METHOD
02315 CPluginInstancePeer::SetWindowSize(PRUint32 width, PRUint32 height)
02316 {
02317     NPError err;
02318     NPSize size;
02319     size.width = width;
02320     size.height = height;
02321     err = NPN_SetValue(npp, NPPVpluginWindowSize, &size);
02322     return fromNPError[err];
02323 }
02324 
02325 //+++++++++++++++++++++++++++++++++++++++++++++++++
02326 // nsISupports functions
02327 //+++++++++++++++++++++++++++++++++++++++++++++++++
02328 
02329 NS_IMPL_ADDREF(CPluginInstancePeer)
02330 NS_IMPL_RELEASE(CPluginInstancePeer)
02331 
02332 NS_METHOD
02333 CPluginInstancePeer::QueryInterface(const nsIID& iid, void** ptr) 
02334 {                                                                        
02335     if (NULL == ptr) {                                            
02336         return NS_ERROR_NULL_POINTER;                                        
02337     }                                                                      
02338   
02339     if (iid.Equals(NS_GET_IID(nsIPluginInstancePeer))) {
02340         *ptr = (void*) this;                                        
02341         AddRef();                                                            
02342         return NS_OK;                                                        
02343     }                                                                      
02344     if (iid.Equals(NS_GET_IID(nsIPluginTagInfo)) || iid.Equals(NS_GET_IID(nsISupports))) {                                      
02345         *ptr = (void*) ((nsIPluginTagInfo*)this);                        
02346         AddRef();                                                            
02347         return NS_OK;                                                        
02348     }                                                                      
02349     return NS_NOINTERFACE;                                                 
02350 }
02351 
02353 //
02354 // CPluginManagerStream
02355 //
02356 
02357 CPluginManagerStream::CPluginManagerStream(NPP npp, NPStream* pstr)
02358     : npp(npp), pstream(pstr)
02359 {
02360 }
02361 
02362 CPluginManagerStream::~CPluginManagerStream(void)
02363 {
02364     //pstream = NULL;
02365     NPN_DestroyStream(npp, pstream, NPRES_DONE);
02366 }
02367 
02368 
02369 //+++++++++++++++++++++++++++++++++++++++++++++++++
02370 // Write:
02371 //+++++++++++++++++++++++++++++++++++++++++++++++++
02372 
02373 NS_METHOD
02374 CPluginManagerStream::Write(const char* buffer, PRUint32 len, PRUint32 *aWriteCount)
02375 {
02376     assert( npp != NULL );
02377     assert( pstream != NULL );
02378 
02379     *aWriteCount = NPN_Write(npp, pstream, len, (void* )buffer);
02380     return *aWriteCount >= 0 ? NS_OK : NS_ERROR_FAILURE;
02381 }
02382 
02383 NS_METHOD
02384 CPluginManagerStream::Write(nsIInputStream* fromStream, PRUint32 *aWriteCount)
02385 {
02386        nsresult rv = fromStream->Available(aWriteCount);
02387        if (rv == NS_OK) {
02388               char buffer[1024];
02389               PRUint32 len = *aWriteCount;
02390               while (len > 0) {           
02391                      PRUint32 count = (len < sizeof(buffer) ? len : sizeof(buffer));
02392                      rv = fromStream->Read(buffer, count, &count);
02393                      if (rv == NS_OK)
02394                             rv = Write(buffer, count, &count);
02395                      if (rv != NS_OK) {
02396                             *aWriteCount -= len;
02397                             break;
02398                      }
02399                      len -= count;
02400               }
02401        }
02402        return rv;
02403 }
02404 
02405 NS_METHOD
02406 CPluginManagerStream::Flush()
02407 {
02408        return NS_OK;
02409 }
02410 
02411 //+++++++++++++++++++++++++++++++++++++++++++++++++
02412 // GetURL:
02413 //+++++++++++++++++++++++++++++++++++++++++++++++++
02414 
02415 NS_METHOD
02416 CPluginManagerStream::GetURL(const char* *result)
02417 {
02418     assert( pstream != NULL );
02419 
02420     *result = pstream->url;
02421        return NS_OK;
02422 }
02423 
02424 //+++++++++++++++++++++++++++++++++++++++++++++++++
02425 // GetEnd:
02426 //+++++++++++++++++++++++++++++++++++++++++++++++++
02427 
02428 NS_METHOD
02429 CPluginManagerStream::GetEnd(PRUint32 *result)
02430 {
02431     assert( pstream != NULL );
02432 
02433     *result = pstream->end;
02434        return NS_OK;
02435 }
02436 
02437 //+++++++++++++++++++++++++++++++++++++++++++++++++
02438 // GetLastModified:
02439 //+++++++++++++++++++++++++++++++++++++++++++++++++
02440 
02441 NS_METHOD
02442 CPluginManagerStream::GetLastModified(PRUint32 *result)
02443 {
02444     assert( pstream != NULL );
02445 
02446     *result = pstream->lastmodified;
02447        return NS_OK;
02448 }
02449 
02450 //+++++++++++++++++++++++++++++++++++++++++++++++++
02451 // GetNotifyData:
02452 //+++++++++++++++++++++++++++++++++++++++++++++++++
02453 
02454 NS_METHOD
02455 CPluginManagerStream::GetNotifyData(void* *result)
02456 {
02457     assert( pstream != NULL );
02458 
02459     *result = pstream->notifyData;
02460        return NS_OK;
02461 }
02462 
02463 //+++++++++++++++++++++++++++++++++++++++++++++++++
02464 // GetNotifyData:
02465 //+++++++++++++++++++++++++++++++++++++++++++++++++
02466 
02467 NS_METHOD
02468 CPluginManagerStream::Close(void)
02469 {
02470     assert( pstream != NULL );
02471 
02472     return NS_OK;
02473 }
02474 
02475 
02476 //+++++++++++++++++++++++++++++++++++++++++++++++++
02477 // nsISupports functions
02478 //+++++++++++++++++++++++++++++++++++++++++++++++++
02479 
02480 NS_IMPL_ISUPPORTS1(CPluginManagerStream, nsIOutputStream)
02481 
02482 
02483 
02484 NS_IMPL_ISUPPORTS1(CPluginStreamInfo, nsIPluginStreamInfo)
02485 
02486 CPluginInputStream::CPluginInputStream(nsIPluginStreamListener* listener)
02487     : mListener(listener), mStreamType(nsPluginStreamType_Normal),
02488       mNPP(NULL), mStream(NULL),
02489       mBuffer(NULL), mBufferLength(0), mAmountRead(0),
02490       mStreamInfo(NULL)
02491 {
02492     if (mListener != NULL) {
02493         mListener->AddRef();
02494         mListener->GetStreamType(&mStreamType);
02495     }
02496 }
02497 
02498 CPluginInputStream::~CPluginInputStream(void)
02499 {
02500        NS_IF_RELEASE(mListener);
02501 
02502     delete mBuffer;
02503     
02504     NS_IF_RELEASE(mStreamInfo);
02505 }
02506 
02507 NS_IMPL_ISUPPORTS1(CPluginInputStream, nsIPluginInputStream)
02508 
02509 NS_METHOD
02510 CPluginInputStream::Close(void)
02511 {
02512     if (mNPP == NULL || mStream == NULL)
02513         return NS_ERROR_FAILURE;
02514     NPError err = NPN_DestroyStream(mNPP, mStream, NPRES_USER_BREAK);
02515     return fromNPError[err];
02516 }
02517 
02518 NS_METHOD
02519 CPluginInputStream::Available(PRUint32 *aLength)
02520 {
02521     *aLength = mStream->end;
02522     return NS_OK;
02523 }
02524 
02525 NS_METHOD
02526 CPluginInputStream::Read(char* aBuf, PRUint32 aCount, PRUint32 *aReadCount)
02527 {
02528     PRUint32 cnt = PR_MIN(aCount, mBufferLength);
02529     memcpy(aBuf, mBuffer + mAmountRead, cnt);
02530     *aReadCount = cnt;
02531     mAmountRead += cnt;
02532     mBufferLength -= cnt;
02533     return NS_OK;
02534 }
02535 
02536 NS_METHOD
02537 CPluginInputStream::GetLastModified(PRUint32 *result)
02538 {
02539     *result = mStream->lastmodified;
02540     return NS_OK;
02541 }
02542 
02543 NS_METHOD
02544 CPluginInputStream::RequestRead(nsByteRange* rangeList)
02545 {
02546     NPError err = NPN_RequestRead(mStream, (NPByteRange*)rangeList);
02547     return fromNPError[err];
02548 }
02549 
02550 
02552 
02553 //#if defined(__cplusplus)
02554 //} /* extern "C" */
02555 //#endif
02556