Back to index

lightning-sunbird  0.9+nobinonly
npmac.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is mozilla.org code.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1998
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either of the GNU General Public License Version 2 or later (the "GPL"),
00025  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
00038 //
00039 // npmac.cpp
00040 //
00041 //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
00042 
00043 #include <Processes.h>
00044 #include <Gestalt.h>
00045 #include <CodeFragments.h>
00046 #include <Timer.h>
00047 #include <Resources.h>
00048 #include <ToolUtils.h>
00049 
00050 #define XP_MAC 1
00051 #define NDEBUG 1
00052 
00053 //
00054 // A4Stuff.h contains the definition of EnterCodeResource and 
00055 // EnterCodeResource, used for setting up the code resourcešs
00056 // globals for 68K (analagous to the function SetCurrentA5
00057 // defined by the toolbox).
00058 //
00059 // A4Stuff does not exist as of CW 7. Define them to nothing.
00060 //
00061 
00062 #if defined(__MWERKS__) && (__MWERKS__ >= 0x2400)
00063        #define EnterCodeResource()
00064        #define ExitCodeResource()
00065 #else
00066     #include <A4Stuff.h>
00067 #endif
00068 
00069 #include "jri.h"
00070 #include "npapi.h"
00071 
00072 //
00073 // The Mixed Mode procInfos defined in npupp.h assume Think C-
00074 // style calling conventions.  These conventions are used by
00075 // Metrowerks with the exception of pointer return types, which
00076 // in Metrowerks 68K are returned in A0, instead of the standard
00077 // D0. Thus, since NPN_MemAlloc and NPN_UserAgent return pointers,
00078 // Mixed Mode will return the values to a 68K plugin in D0, but 
00079 // a 68K plugin compiled by Metrowerks will expect the result in
00080 // A0.  The following pragma forces Metrowerks to use D0 instead.
00081 //
00082 #ifdef __MWERKS__
00083 #ifndef powerc
00084 #pragma pointers_in_D0
00085 #endif
00086 #endif
00087 
00088 #include "npupp.h"
00089 
00090 #ifdef __MWERKS__
00091 #ifndef powerc
00092 #pragma pointers_in_A0
00093 #endif
00094 #endif
00095 
00096 // The following fix for static initializers (which fixes a preious
00097 // incompatibility with some parts of PowerPlant, was submitted by 
00098 // Jan Ulbrich.
00099 #ifdef __MWERKS__
00100        #ifdef __cplusplus
00101        extern "C" {
00102        #endif
00103               #ifndef powerc
00104                      extern void   __InitCode__(void);
00105               #else
00106                      extern void __sinit(void);
00107                      #define __InitCode__ __sinit
00108               #endif
00109               extern void   __destroy_global_chain(void);
00110        #ifdef __cplusplus
00111        }
00112        #endif // __cplusplus
00113 #endif // __MWERKS__
00114 
00115 //
00116 // Define PLUGIN_TRACE to 1 to have the wrapper functions emit
00117 // DebugStr messages whenever they are called.
00118 //
00119 #define PLUGIN_TRACE 0
00120 
00121 #if PLUGIN_TRACE
00122 #define PLUGINDEBUGSTR(msg)        ::DebugStr(msg)
00123 #else
00124 #define PLUGINDEBUGSTR
00125 #endif
00126 
00127 
00128 
00129 
00130 
00131 
00132 //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
00133 //
00134 // Globals
00135 //
00136 //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
00137 
00138 QDGlobals*           gQDPtr;                            // Pointer to Netscapešs QuickDraw globals
00139 short                gResFile;                   // Refnum of the pluginšs resource file
00140 NPNetscapeFuncs      gNetscapeFuncs;             // Function table for procs in Netscape called by plugin
00141 
00142 
00143 //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
00144 //
00145 // Wrapper functions for all calls from the plugin to Netscape.
00146 // These functions let the plugin developer just call the APIs
00147 // as documented and defined in npapi.h, without needing to know
00148 // about the function table and call macros in npupp.h.
00149 //
00150 //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
00151 
00152 
00153 void NPN_Version(int* plugin_major, int* plugin_minor, int* netscape_major, int* netscape_minor)
00154 {
00155        *plugin_major = NP_VERSION_MAJOR;
00156        *plugin_minor = NP_VERSION_MINOR;
00157        *netscape_major = gNetscapeFuncs.version >> 8;          // Major version is in high byte
00158        *netscape_minor = gNetscapeFuncs.version & 0xFF; // Minor version is in low byte
00159 }
00160 
00161 NPError NPN_GetURLNotify(NPP instance, const char* url, const char* window, void* notifyData)
00162 {
00163        int navMinorVers = gNetscapeFuncs.version & 0xFF;
00164        NPError err;
00165        
00166        if( navMinorVers >= NPVERS_HAS_NOTIFICATION )
00167        {
00168               err = CallNPN_GetURLNotifyProc(gNetscapeFuncs.geturlnotify, instance, url, window, notifyData);
00169        }
00170        else
00171        {
00172               err = NPERR_INCOMPATIBLE_VERSION_ERROR;
00173        }
00174        return err;
00175 }
00176 
00177 NPError NPN_GetURL(NPP instance, const char* url, const char* window)
00178 {
00179        return CallNPN_GetURLProc(gNetscapeFuncs.geturl, instance, url, window);
00180 }
00181 
00182 NPError NPN_PostURLNotify(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file, void* notifyData)
00183 {
00184        int navMinorVers = gNetscapeFuncs.version & 0xFF;
00185        NPError err;
00186        
00187        if( navMinorVers >= NPVERS_HAS_NOTIFICATION )
00188        {
00189               err = CallNPN_PostURLNotifyProc(gNetscapeFuncs.posturlnotify, instance, url, 
00190                                                                                                   window, len, buf, file, notifyData);
00191        }
00192        else
00193        {
00194               err = NPERR_INCOMPATIBLE_VERSION_ERROR;
00195        }
00196        return err;
00197 }
00198 
00199 NPError NPN_PostURL(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file)
00200 {
00201        return CallNPN_PostURLProc(gNetscapeFuncs.posturl, instance, url, window, len, buf, file);
00202 }
00203 
00204 NPError NPN_RequestRead(NPStream* stream, NPByteRange* rangeList)
00205 {
00206        return CallNPN_RequestReadProc(gNetscapeFuncs.requestread, stream, rangeList);
00207 }
00208 
00209 NPError NPN_NewStream(NPP instance, NPMIMEType type, const char* window, NPStream** stream)
00210 {
00211        int navMinorVers = gNetscapeFuncs.version & 0xFF;
00212        NPError err;
00213        
00214        if( navMinorVers >= NPVERS_HAS_STREAMOUTPUT )
00215        {
00216               err = CallNPN_NewStreamProc(gNetscapeFuncs.newstream, instance, type, window, stream);
00217        }
00218        else
00219        {
00220               err = NPERR_INCOMPATIBLE_VERSION_ERROR;
00221        }
00222        return err;
00223 }
00224 
00225 int32 NPN_Write(NPP instance, NPStream* stream, int32 len, void* buffer)
00226 {
00227        int navMinorVers = gNetscapeFuncs.version & 0xFF;
00228        NPError err;
00229        
00230        if( navMinorVers >= NPVERS_HAS_STREAMOUTPUT )
00231        {
00232               err = CallNPN_WriteProc(gNetscapeFuncs.write, instance, stream, len, buffer);
00233        }
00234        else
00235        {
00236               err = NPERR_INCOMPATIBLE_VERSION_ERROR;
00237        }
00238        return err;
00239 }
00240 
00241 NPError       NPN_DestroyStream(NPP instance, NPStream* stream, NPError reason)
00242 {
00243        int navMinorVers = gNetscapeFuncs.version & 0xFF;
00244        NPError err;
00245        
00246        if( navMinorVers >= NPVERS_HAS_STREAMOUTPUT )
00247        {
00248               err = CallNPN_DestroyStreamProc(gNetscapeFuncs.destroystream, instance, stream, reason);
00249        }
00250        else
00251        {
00252               err = NPERR_INCOMPATIBLE_VERSION_ERROR;
00253        }
00254        return err;
00255 }
00256 
00257 void NPN_Status(NPP instance, const char* message)
00258 {
00259        CallNPN_StatusProc(gNetscapeFuncs.status, instance, message);
00260 }
00261 
00262 const char* NPN_UserAgent(NPP instance)
00263 {
00264        return CallNPN_UserAgentProc(gNetscapeFuncs.uagent, instance);
00265 }
00266 
00267 #define DEBUG_MEMORY 0
00268 
00269 void* NPN_MemAlloc(uint32 size)
00270 {
00271 #if DEBUG_MEMORY
00272        return (void*) NewPtrClear(size);
00273 #else
00274        return CallNPN_MemAllocProc(gNetscapeFuncs.memalloc, size);
00275 #endif
00276 }
00277 
00278 void NPN_MemFree(void* ptr)
00279 {
00280 #if DEBUG_MEMORY
00281        DisposePtr(Ptr(ptr));
00282 #else
00283        CallNPN_MemFreeProc(gNetscapeFuncs.memfree, ptr);
00284 #endif
00285 }
00286 
00287 uint32 NPN_MemFlush(uint32 size)
00288 {
00289        return CallNPN_MemFlushProc(gNetscapeFuncs.memflush, size);
00290 }
00291 
00292 void NPN_ReloadPlugins(NPBool reloadPages)
00293 {
00294        CallNPN_ReloadPluginsProc(gNetscapeFuncs.reloadplugins, reloadPages);
00295 }
00296 
00297 
00298 JRIEnv* NPN_GetJavaEnv(void)
00299 {
00300        return CallNPN_GetJavaEnvProc( gNetscapeFuncs.getJavaEnv );
00301 }
00302 
00303 jref  NPN_GetJavaPeer(NPP instance)
00304 {
00305        return CallNPN_GetJavaPeerProc( gNetscapeFuncs.getJavaPeer, instance );
00306 }
00307 
00308 NPError NPN_GetValue(NPP instance, NPNVariable variable, void *value)
00309 {
00310        return CallNPN_GetValueProc( gNetscapeFuncs.getvalue, instance, variable, value);
00311 }
00312 
00313 NPError NPN_SetValue(NPP instance, NPPVariable variable, void *value)
00314 {
00315        return CallNPN_SetValueProc( gNetscapeFuncs.setvalue, instance, variable, value);
00316 }
00317 
00318 void NPN_InvalidateRect(NPP instance, NPRect *rect)
00319 {
00320        CallNPN_InvalidateRectProc( gNetscapeFuncs.invalidaterect, instance, rect);
00321 }
00322 
00323 void NPN_InvalidateRegion(NPP instance, NPRegion region)
00324 {
00325        CallNPN_InvalidateRegionProc( gNetscapeFuncs.invalidateregion, instance, region);
00326 }
00327 
00328 void NPN_ForceRedraw(NPP instance)
00329 {
00330        CallNPN_ForceRedrawProc( gNetscapeFuncs.forceredraw, instance);
00331 }
00332 
00333 //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
00334 //
00335 // Wrapper functions for all calls from Netscape to the plugin.
00336 // These functions let the plugin developer just create the APIs
00337 // as documented and defined in npapi.h, without needing to 
00338 // install those functions in the function table or worry about
00339 // setting up globals for 68K plugins.
00340 //
00341 //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
00342 
00343 NPError       Private_Initialize(void);
00344 void          Private_Shutdown(void);
00345 NPError              Private_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved);
00346 NPError       Private_Destroy(NPP instance, NPSavedData** save);
00347 NPError              Private_SetWindow(NPP instance, NPWindow* window);
00348 NPError              Private_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype);
00349 NPError              Private_DestroyStream(NPP instance, NPStream* stream, NPError reason);
00350 int32         Private_WriteReady(NPP instance, NPStream* stream);
00351 int32         Private_Write(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer);
00352 void          Private_StreamAsFile(NPP instance, NPStream* stream, const char* fname);
00353 void          Private_Print(NPP instance, NPPrint* platformPrint);
00354 int16         Private_HandleEvent(NPP instance, void* event);
00355 void        Private_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData);
00356 jref          Private_GetJavaClass(void);
00357 
00358 
00359 NPError Private_Initialize(void)
00360 {
00361        NPError err;
00362        EnterCodeResource();
00363        PLUGINDEBUGSTR("\pInitialize;g;");
00364        err = NPP_Initialize();
00365        ExitCodeResource();
00366        return err;
00367 }
00368 
00369 void Private_Shutdown(void)
00370 {
00371        EnterCodeResource();
00372        PLUGINDEBUGSTR("\pShutdown;g;");
00373        NPP_Shutdown();
00374 
00375        __destroy_global_chain();
00376 
00377        ExitCodeResource();
00378 }
00379 
00380 
00381 NPError       Private_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved)
00382 {
00383        EnterCodeResource();
00384        NPError ret = NPP_New(pluginType, instance, mode, argc, argn, argv, saved);
00385        PLUGINDEBUGSTR("\pNew;g;");
00386        ExitCodeResource();
00387        return ret;   
00388 }
00389 
00390 NPError Private_Destroy(NPP instance, NPSavedData** save)
00391 {
00392        NPError err;
00393        EnterCodeResource();
00394        PLUGINDEBUGSTR("\pDestroy;g;");
00395        err = NPP_Destroy(instance, save);
00396        ExitCodeResource();
00397        return err;
00398 }
00399 
00400 NPError Private_SetWindow(NPP instance, NPWindow* window)
00401 {
00402        NPError err;
00403        EnterCodeResource();
00404        PLUGINDEBUGSTR("\pSetWindow;g;");
00405        err = NPP_SetWindow(instance, window);
00406        ExitCodeResource();
00407        return err;
00408 }
00409 
00410 NPError Private_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype)
00411 {
00412        NPError err;
00413        EnterCodeResource();
00414        PLUGINDEBUGSTR("\pNewStream;g;");
00415        err = NPP_NewStream(instance, type, stream, seekable, stype);
00416        ExitCodeResource();
00417        return err;
00418 }
00419 
00420 int32 Private_WriteReady(NPP instance, NPStream* stream)
00421 {
00422        int32 result;
00423        EnterCodeResource();
00424        PLUGINDEBUGSTR("\pWriteReady;g;");
00425        result = NPP_WriteReady(instance, stream);
00426        ExitCodeResource();
00427        return result;
00428 }
00429 
00430 int32 Private_Write(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer)
00431 {
00432        int32 result;
00433        EnterCodeResource();
00434        PLUGINDEBUGSTR("\pWrite;g;");
00435        result = NPP_Write(instance, stream, offset, len, buffer);
00436        ExitCodeResource();
00437        return result;
00438 }
00439 
00440 void Private_StreamAsFile(NPP instance, NPStream* stream, const char* fname)
00441 {
00442        EnterCodeResource();
00443        PLUGINDEBUGSTR("\pStreamAsFile;g;");
00444        NPP_StreamAsFile(instance, stream, fname);
00445        ExitCodeResource();
00446 }
00447 
00448 
00449 NPError Private_DestroyStream(NPP instance, NPStream* stream, NPError reason)
00450 {
00451        NPError err;
00452        EnterCodeResource();
00453        PLUGINDEBUGSTR("\pDestroyStream;g;");
00454        err = NPP_DestroyStream(instance, stream, reason);
00455        ExitCodeResource();
00456        return err;
00457 }
00458 
00459 int16 Private_HandleEvent(NPP instance, void* event)
00460 {
00461        int16 result;
00462        EnterCodeResource();
00463        PLUGINDEBUGSTR("\pHandleEvent;g;");
00464        result = NPP_HandleEvent(instance, event);
00465        ExitCodeResource();
00466        return result;
00467 }
00468 
00469 void Private_Print(NPP instance, NPPrint* platformPrint)
00470 {
00471        EnterCodeResource();
00472        PLUGINDEBUGSTR("\pPrint;g;");
00473        NPP_Print(instance, platformPrint);
00474        ExitCodeResource();
00475 }
00476 
00477 void Private_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData)
00478 {
00479        EnterCodeResource();
00480        PLUGINDEBUGSTR("\pURLNotify;g;");
00481        NPP_URLNotify(instance, url, reason, notifyData);
00482        ExitCodeResource();
00483 }
00484 
00485 
00486 jref Private_GetJavaClass(void)
00487 {
00488        EnterCodeResource();
00489        PLUGINDEBUGSTR("\pGetJavaClass;g;");
00490 
00491     jref clazz = NPP_GetJavaClass();
00492     ExitCodeResource();
00493     if (clazz)
00494     {
00495               JRIEnv* env = NPN_GetJavaEnv();
00496               return (jref)JRI_NewGlobalRef(env, clazz);
00497     }
00498     return NULL;
00499 }
00500 
00501 
00502 void SetUpQD(void);
00503 
00504 void SetUpQD(void)
00505 {
00506        ProcessSerialNumber PSN;
00507        FSSpec                      myFSSpec;
00508        Str63                       name;
00509        ProcessInfoRec              infoRec;
00510        OSErr                       result = noErr;
00511        CFragConnectionID    connID;
00512        Str255                             errName;
00513        
00514        //
00515        // Memorize the pluginšs resource file 
00516        // refnum for later use.
00517        //
00518        gResFile = CurResFile();
00519        
00520        //
00521        // Ask the system if CFM is available.
00522        //
00523        long response;
00524        OSErr err = Gestalt(gestaltCFMAttr, &response);
00525        Boolean hasCFM = BitTst(&response, 31-gestaltCFMPresent);
00526                      
00527        if (hasCFM)
00528        {
00529               //
00530               // GetProcessInformation takes a process serial number and 
00531               // will give us back the name and FSSpec of the application.
00532               // See the Process Manager in IM.
00533               //
00534               infoRec.processInfoLength = sizeof(ProcessInfoRec);
00535               infoRec.processName = name;
00536               infoRec.processAppSpec = &myFSSpec;
00537               
00538               PSN.highLongOfPSN = 0;
00539               PSN.lowLongOfPSN = kCurrentProcess;
00540               
00541               result = GetProcessInformation(&PSN, &infoRec);
00542               if (result != noErr)
00543                      PLUGINDEBUGSTR("\pFailed in GetProcessInformation");
00544               }
00545        else
00546               //
00547               // If no CFM installed, assume it must be a 68K app.
00548               //
00549               result = -1;         
00550               
00551        if (result == noErr)
00552        {
00553               //
00554               // Now that we know the app name and FSSpec, we can call GetDiskFragment
00555               // to get a connID to use in a subsequent call to FindSymbol (it will also
00556               // return the address of ŗmain˛ in app, which we ignore).  If GetDiskFragment 
00557               // returns an error, we assume the app must be 68K.
00558               //
00559               Ptr mainAddr;        
00560               result =  GetDiskFragment(infoRec.processAppSpec, 0L, 0L, infoRec.processName,
00561                                                           kReferenceCFrag, &connID, (Ptr*)&mainAddr, errName);
00562        }
00563 
00564        if (result == noErr) 
00565        {
00566               //
00567               // The app is a PPC code fragment, so call FindSymbol
00568               // to get the exported ŗqd˛ symbol so we can access its
00569               // QuickDraw globals.
00570               //
00571               CFragSymbolClass symClass;
00572               result = FindSymbol(connID, "\pqd", (Ptr*)&gQDPtr, &symClass);
00573               if (result != noErr)
00574                      PLUGINDEBUGSTR("\pFailed in FindSymbol qd");
00575        }
00576        else
00577        {
00578               //
00579               // The app is 68K, so use its A5 to compute the address
00580               // of its QuickDraw globals.
00581               //
00582               gQDPtr = (QDGlobals*)(*((long*)SetCurrentA5()) - (sizeof(QDGlobals) - sizeof(GrafPtr)));
00583        }
00584 
00585 }
00586 
00587 
00588 
00589 NPError main(NPNetscapeFuncs* nsTable, NPPluginFuncs* pluginFuncs, NPP_ShutdownUPP* unloadUpp);
00590 
00591 #pragma export on
00592 
00593 #if GENERATINGCFM
00594 RoutineDescriptor mainRD = BUILD_ROUTINE_DESCRIPTOR(uppNPP_MainEntryProcInfo, main);
00595 #endif
00596 
00597 #pragma export off
00598  
00599 
00600 NPError main(NPNetscapeFuncs* nsTable, NPPluginFuncs* pluginFuncs, NPP_ShutdownUPP* unloadUpp)
00601 {
00602        EnterCodeResource();
00603        PLUGINDEBUGSTR("\pmain");
00604 
00605        NPError err = NPERR_NO_ERROR;
00606        
00607        //
00608        // Ensure that everything Netscape passed us is valid!
00609        //
00610        if ((nsTable == NULL) || (pluginFuncs == NULL) || (unloadUpp == NULL))
00611               err = NPERR_INVALID_FUNCTABLE_ERROR;
00612        
00613        //
00614        // Check the ŗmajor˛ version passed in Netscapešs function table.
00615        // We wonšt load if the major version is newer than what we expect.
00616        // Also check that the function tables passed in are big enough for
00617        // all the functions we need (they could be bigger, if Netscape added
00618        // new APIs, but thatšs OK with us -- wešll just ignore them).
00619        //
00620        if (err == NPERR_NO_ERROR)
00621        {
00622               if ((nsTable->version >> 8) > NP_VERSION_MAJOR)         // Major version is in high byte
00623                      err = NPERR_INCOMPATIBLE_VERSION_ERROR;
00624 //            if (nsTable->size < sizeof(NPNetscapeFuncs))
00625 //                   err = NPERR_INVALID_FUNCTABLE_ERROR;
00626 //            if (pluginFuncs->size < sizeof(NPPluginFuncs))          
00627 //                   err = NPERR_INVALID_FUNCTABLE_ERROR;
00628        }
00629               
00630        
00631        if (err == NPERR_NO_ERROR)
00632        {
00633               //
00634               // Copy all the fields of Netscapešs function table into our
00635               // copy so we can call back into Netscape later.  Note that
00636               // we need to copy the fields one by one, rather than assigning
00637               // the whole structure, because the Netscape function table
00638               // could actually be bigger than what we expect.
00639               //
00640               
00641               int navMinorVers = nsTable->version & 0xFF;
00642 
00643               gNetscapeFuncs.version = nsTable->version;
00644               gNetscapeFuncs.size = nsTable->size;
00645               gNetscapeFuncs.posturl = nsTable->posturl;
00646               gNetscapeFuncs.geturl = nsTable->geturl;
00647               gNetscapeFuncs.requestread = nsTable->requestread;
00648               gNetscapeFuncs.newstream = nsTable->newstream;
00649               gNetscapeFuncs.write = nsTable->write;
00650               gNetscapeFuncs.destroystream = nsTable->destroystream;
00651               gNetscapeFuncs.status = nsTable->status;
00652               gNetscapeFuncs.uagent = nsTable->uagent;
00653               gNetscapeFuncs.memalloc = nsTable->memalloc;
00654               gNetscapeFuncs.memfree = nsTable->memfree;
00655               gNetscapeFuncs.memflush = nsTable->memflush;
00656               gNetscapeFuncs.reloadplugins = nsTable->reloadplugins;
00657               if( navMinorVers >= NPVERS_HAS_LIVECONNECT )
00658               {
00659                      gNetscapeFuncs.getJavaEnv = nsTable->getJavaEnv;
00660                      gNetscapeFuncs.getJavaPeer = nsTable->getJavaPeer;
00661               }
00662               if( navMinorVers >= NPVERS_HAS_NOTIFICATION )
00663               {      
00664                      gNetscapeFuncs.geturlnotify = nsTable->geturlnotify;
00665                      gNetscapeFuncs.posturlnotify = nsTable->posturlnotify;
00666               }
00667               gNetscapeFuncs.getvalue = nsTable->getvalue;
00668               gNetscapeFuncs.setvalue = nsTable->setvalue;
00669               gNetscapeFuncs.invalidaterect = nsTable->invalidaterect;
00670               gNetscapeFuncs.invalidateregion = nsTable->invalidateregion;
00671               gNetscapeFuncs.forceredraw = nsTable->forceredraw;
00672 
00673               // defer static constructors until the global functions are initialized.
00674               __InitCode__();
00675               
00676               //
00677               // Set up the plugin function table that Netscape will use to
00678               // call us.  Netscape needs to know about our version and size
00679               // and have a UniversalProcPointer for every function we implement.
00680               //
00681               pluginFuncs->version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR;
00682               pluginFuncs->size = sizeof(NPPluginFuncs);
00683               pluginFuncs->newp = NewNPP_NewProc(Private_New);
00684               pluginFuncs->destroy = NewNPP_DestroyProc(Private_Destroy);
00685               pluginFuncs->setwindow = NewNPP_SetWindowProc(Private_SetWindow);
00686               pluginFuncs->newstream = NewNPP_NewStreamProc(Private_NewStream);
00687               pluginFuncs->destroystream = NewNPP_DestroyStreamProc(Private_DestroyStream);
00688               pluginFuncs->asfile = NewNPP_StreamAsFileProc(Private_StreamAsFile);
00689               pluginFuncs->writeready = NewNPP_WriteReadyProc(Private_WriteReady);
00690               pluginFuncs->write = NewNPP_WriteProc(Private_Write);
00691               pluginFuncs->print = NewNPP_PrintProc(Private_Print);
00692               pluginFuncs->event = NewNPP_HandleEventProc(Private_HandleEvent);     
00693               if( navMinorVers >= NPVERS_HAS_NOTIFICATION )
00694               {      
00695                      pluginFuncs->urlnotify = NewNPP_URLNotifyProc(Private_URLNotify);                   
00696               }
00697               if( navMinorVers >= NPVERS_HAS_LIVECONNECT )
00698               {
00699                      pluginFuncs->javaClass      = (JRIGlobalRef) Private_GetJavaClass();
00700               }
00701               *unloadUpp = NewNPP_ShutdownProc(Private_Shutdown);
00702               SetUpQD();
00703               err = Private_Initialize();
00704        }
00705        
00706        ExitCodeResource();
00707        return err;
00708 }