Back to index

lightning-sunbird  0.9+nobinonly
plugin.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 the GNU General Public License Version 2 or later (the "GPL"), or
00026  * 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 
00038 #include "plugin.h"
00039 #include "nsIServiceManager.h"
00040 #include "nsIMemory.h"
00041 #include "nsISupportsUtils.h" // this is where some useful macros defined
00042 
00043 // service manager which will give the access to all public browser services
00044 // we will use memory service as an illustration
00045 nsIServiceManager * gServiceManager = NULL;
00046 
00047 // Unix needs this
00048 #ifdef XP_UNIX
00049 #define MIME_TYPES_HANDLED  "application/simple-plugin"
00050 #define PLUGIN_NAME         "Simple Plugin Example for Mozilla"
00051 #define MIME_TYPES_DESCRIPTION  MIME_TYPES_HANDLED"::"PLUGIN_NAME
00052 #define PLUGIN_DESCRIPTION  PLUGIN_NAME " (Plug-ins SDK sample)" 
00053 
00054 char* NPP_GetMIMEDescription(void)
00055 {
00056     return(MIME_TYPES_DESCRIPTION);
00057 }
00058 
00059 // get values per plugin
00060 NPError NS_PluginGetValue(NPPVariable aVariable, void *aValue)
00061 {
00062   NPError err = NPERR_NO_ERROR;
00063   switch (aVariable) {
00064     case NPPVpluginNameString:
00065       *((char **)aValue) = PLUGIN_NAME;
00066       break;
00067     case NPPVpluginDescriptionString:
00068       *((char **)aValue) = PLUGIN_DESCRIPTION;
00069       break;
00070     default:
00071       err = NPERR_INVALID_PARAM;
00072       break;
00073   }
00074   return err;
00075 }
00076 #endif //XP_UNIX
00077 
00079 //
00080 // general initialization and shutdown
00081 //
00082 NPError NS_PluginInitialize()
00083 {
00084   // this is probably a good place to get the service manager
00085   // note that Mozilla will add reference, so do not forget to release
00086   nsISupports * sm = NULL;
00087   
00088   NPN_GetValue(NULL, NPNVserviceManager, &sm);
00089 
00090   // Mozilla returns nsIServiceManager so we can use it directly; doing QI on
00091   // nsISupports here can still be more appropriate in case something is changed 
00092   // in the future so we don't need to do casting of any sort.
00093   if(sm) {
00094     sm->QueryInterface(NS_GET_IID(nsIServiceManager), (void**)&gServiceManager);
00095     NS_RELEASE(sm);
00096   }
00097   
00098   return NPERR_NO_ERROR;
00099 }
00100 
00101 void NS_PluginShutdown()
00102 {
00103   // we should release the service manager
00104   NS_IF_RELEASE(gServiceManager);
00105   gServiceManager = NULL;
00106 }
00107 
00109 //
00110 // construction and destruction of our plugin instance object
00111 //
00112 nsPluginInstanceBase * NS_NewPluginInstance(nsPluginCreateData * aCreateDataStruct)
00113 {
00114   if(!aCreateDataStruct)
00115     return NULL;
00116 
00117   nsPluginInstance * plugin = new nsPluginInstance(aCreateDataStruct->instance);
00118   return plugin;
00119 }
00120 
00121 void NS_DestroyPluginInstance(nsPluginInstanceBase * aPlugin)
00122 {
00123   if(aPlugin)
00124     delete (nsPluginInstance *)aPlugin;
00125 }
00126 
00128 //
00129 // nsPluginInstance class implementation
00130 //
00131 nsPluginInstance::nsPluginInstance(NPP aInstance) : nsPluginInstanceBase(),
00132   mInstance(aInstance),
00133   mInitialized(FALSE),
00134   mScriptablePeer(NULL)
00135 {
00136   mString[0] = '\0';
00137 }
00138 
00139 nsPluginInstance::~nsPluginInstance()
00140 {
00141   // mScriptablePeer may be also held by the browser 
00142   // so releasing it here does not guarantee that it is over
00143   // we should take precaution in case it will be called later
00144   // and zero its mPlugin member
00145   mScriptablePeer->SetInstance(NULL);
00146   NS_IF_RELEASE(mScriptablePeer);
00147 }
00148 
00149 NPBool nsPluginInstance::init(NPWindow* aWindow)
00150 {
00151   if(aWindow == NULL)
00152     return FALSE;
00153 
00154   mInitialized = TRUE;
00155   return TRUE;
00156 }
00157 
00158 void nsPluginInstance::shut()
00159 {
00160   mInitialized = FALSE;
00161 }
00162 
00163 NPBool nsPluginInstance::isInitialized()
00164 {
00165   return mInitialized;
00166 }
00167 
00168 void nsPluginInstance::getVersion(char* *aVersion)
00169 {
00170   const char *ua = NPN_UserAgent(mInstance);
00171   char*& version = *aVersion;
00172 
00173   // although we can use NPAPI NPN_MemAlloc call to allocate memory:
00174   //    version = (char*)NPN_MemAlloc(strlen(ua) + 1);
00175   // for illustration purposed we use the service manager to access 
00176   // the memory service provided by Mozilla
00177   nsIMemory * nsMemoryService = NULL;
00178   
00179   if (gServiceManager) {
00180     // get service using its contract id and use it to allocate the memory
00181     gServiceManager->GetServiceByContractID("@mozilla.org/xpcom/memory-service;1", NS_GET_IID(nsIMemory), (void **)&nsMemoryService);
00182     if(nsMemoryService)
00183       version = (char *)nsMemoryService->Alloc(strlen(ua) + 1);
00184   }
00185 
00186   if (version)
00187     strcpy(version, ua);
00188 
00189   // release service
00190   NS_IF_RELEASE(nsMemoryService);
00191 }
00192 
00193 // ==============================
00194 // ! Scriptability related code !
00195 // ==============================
00196 //
00197 // here the plugin is asked by Mozilla to tell if it is scriptable
00198 // we should return a valid interface id and a pointer to 
00199 // nsScriptablePeer interface which we should have implemented
00200 // and which should be defined in the corressponding *.xpt file
00201 // in the bin/components folder
00202 NPError       nsPluginInstance::GetValue(NPPVariable aVariable, void *aValue)
00203 {
00204   NPError rv = NPERR_NO_ERROR;
00205 
00206   switch (aVariable) {
00207     case NPPVpluginScriptableInstance: {
00208       // addref happens in getter, so we don't addref here
00209       nsISimplePlugin * scriptablePeer = getScriptablePeer();
00210       if (scriptablePeer) {
00211         *(nsISupports **)aValue = scriptablePeer;
00212       } else
00213         rv = NPERR_OUT_OF_MEMORY_ERROR;
00214     }
00215     break;
00216 
00217     case NPPVpluginScriptableIID: {
00218       static nsIID scriptableIID = NS_ISIMPLEPLUGIN_IID;
00219       nsIID* ptr = (nsIID *)NPN_MemAlloc(sizeof(nsIID));
00220       if (ptr) {
00221           *ptr = scriptableIID;
00222           *(nsIID **)aValue = ptr;
00223       } else
00224         rv = NPERR_OUT_OF_MEMORY_ERROR;
00225     }
00226     break;
00227 
00228     default:
00229       break;
00230   }
00231 
00232   return rv;
00233 }
00234 
00235 // ==============================
00236 // ! Scriptability related code !
00237 // ==============================
00238 //
00239 // this method will return the scriptable object (and create it if necessary)
00240 nsScriptablePeer* nsPluginInstance::getScriptablePeer()
00241 {
00242   if (!mScriptablePeer) {
00243     mScriptablePeer = new nsScriptablePeer(this);
00244     if(!mScriptablePeer)
00245       return NULL;
00246 
00247     NS_ADDREF(mScriptablePeer);
00248   }
00249 
00250   // add reference for the caller requesting the object
00251   NS_ADDREF(mScriptablePeer);
00252   return mScriptablePeer;
00253 }