Home | History | Annotate | Download | only in common
      1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
      2 /* ***** BEGIN LICENSE BLOCK *****
      3  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
      4  *
      5  * The contents of this file are subject to the Mozilla Public License Version
      6  * 1.1 (the "License"); you may not use this file except in compliance with
      7  * the License. You may obtain a copy of the License at
      8  * http://www.mozilla.org/MPL/
      9  *
     10  * Software distributed under the License is distributed on an "AS IS" basis,
     11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
     12  * for the specific language governing rights and limitations under the
     13  * License.
     14  *
     15  * The Original Code is mozilla.org code.
     16  *
     17  * The Initial Developer of the Original Code is
     18  * Netscape Communications Corporation.
     19  * Portions created by the Initial Developer are Copyright (C) 1998
     20  * the Initial Developer. All Rights Reserved.
     21  *
     22  * Contributor(s):
     23  *
     24  * Alternatively, the contents of this file may be used under the terms of
     25  * either the GNU General Public License Version 2 or later (the "GPL"), or
     26  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
     27  * in which case the provisions of the GPL or the LGPL are applicable instead
     28  * of those above. If you wish to allow use of your version of this file only
     29  * under the terms of either the GPL or the LGPL, and not to allow others to
     30  * use your version of this file under the terms of the MPL, indicate your
     31  * decision by deleting the provisions above and replace them with the notice
     32  * and other provisions required by the GPL or the LGPL. If you do not delete
     33  * the provisions above, a recipient may use your version of this file under
     34  * the terms of any one of the MPL, the GPL or the LGPL.
     35  *
     36  * ***** END LICENSE BLOCK ***** */
     37 
     38 #include "xp.h"
     39 
     40 #include "epmanager.h"
     41 #include "logger.h"
     42 
     43 extern Logger * logger;
     44 
     45 InstanceList::InstanceList(NPP _instance) :
     46   next(NULL),
     47   instance(_instance)
     48 {
     49 }
     50 
     51 InstanceList::~InstanceList()
     52 {
     53 }
     54 
     55 PluginEntryPointList::PluginEntryPointList() :
     56   next(NULL),
     57   instances(NULL)
     58 {
     59   mimetype[0] = '\0';
     60   memset((void *)&realNPPFuncs, 0, sizeof(realNPPFuncs));
     61   realShutdown = NULL;
     62   hLib = NULL;
     63 }
     64 
     65 PluginEntryPointList::~PluginEntryPointList()
     66 {
     67 }
     68 
     69 NPPEntryPointManager::NPPEntryPointManager() :
     70   mEntryPoints(NULL)
     71 {
     72 }
     73 
     74 NPPEntryPointManager::~NPPEntryPointManager()
     75 {
     76   for(PluginEntryPointList * eps = mEntryPoints; eps != NULL;)
     77   {
     78     for(InstanceList * instances = eps->instances; instances != NULL;)
     79     {
     80       InstanceList * next = instances->next;
     81       delete instances;
     82       instances = next;
     83     }
     84 
     85     PluginEntryPointList * next = eps->next;
     86     delete eps;
     87     eps = next;
     88   }
     89 }
     90 
     91 void NPPEntryPointManager::createEntryPointsForPlugin(char * mimetype, NPPluginFuncs * funcs, NP_SHUTDOWN shutdownproc, XP_HLIB hLib)
     92 {
     93   PluginEntryPointList * eps = new PluginEntryPointList();
     94 
     95   if(eps == NULL)
     96     return;
     97 
     98   strcpy(eps->mimetype, mimetype);
     99 
    100   if(funcs)
    101   {
    102     eps->realNPPFuncs.size          = funcs->size;
    103     eps->realNPPFuncs.version       = funcs->version;
    104     eps->realNPPFuncs.newp          = funcs->newp;
    105     eps->realNPPFuncs.destroy       = funcs->destroy;
    106     eps->realNPPFuncs.setwindow     = funcs->setwindow;
    107     eps->realNPPFuncs.newstream     = funcs->newstream;
    108     eps->realNPPFuncs.destroystream = funcs->destroystream;
    109     eps->realNPPFuncs.asfile        = funcs->asfile;
    110     eps->realNPPFuncs.writeready    = funcs->writeready;
    111     eps->realNPPFuncs.write         = funcs->write;
    112     eps->realNPPFuncs.print         = funcs->print;
    113     eps->realNPPFuncs.event         = funcs->event;
    114     eps->realNPPFuncs.urlnotify     = funcs->urlnotify;
    115     eps->realNPPFuncs.javaClass     = funcs->javaClass;
    116     eps->realNPPFuncs.getvalue      = funcs->getvalue;
    117 
    118   }
    119 
    120   eps->realShutdown = shutdownproc;
    121   eps->hLib = hLib;
    122 
    123   eps->next = mEntryPoints;
    124   mEntryPoints = eps;
    125 }
    126 
    127 void NPPEntryPointManager::removeEntryPointsForPlugin(NPP instance, XP_HLIB * lib)
    128 {
    129   NPPluginFuncs * eptoremove = findEntryPointsForInstance(instance);
    130 
    131   PluginEntryPointList * prev = NULL;
    132 
    133   for(PluginEntryPointList * eps = mEntryPoints; eps != NULL; eps = eps->next)
    134   {
    135     if(&eps->realNPPFuncs == eptoremove)
    136     {
    137       if(prev)
    138         prev->next = eps->next;
    139       else
    140         mEntryPoints = eps->next;
    141 
    142       *lib = eps->hLib;
    143       delete eps;
    144       return;
    145     }
    146 
    147     prev = eps;
    148   }
    149 }
    150 
    151 NPPluginFuncs * NPPEntryPointManager::findEntryPointsForPlugin(char * mimetype)
    152 {
    153   for(PluginEntryPointList * eps = mEntryPoints; eps != NULL; eps = eps->next)
    154   {
    155     if(0 == _stricmp(eps->mimetype, mimetype))
    156       return &eps->realNPPFuncs;
    157   }
    158 
    159   return NULL;
    160 }
    161 
    162 NPPluginFuncs * NPPEntryPointManager::findEntryPointsForInstance(NPP instance)
    163 {
    164   for(PluginEntryPointList * eps = mEntryPoints; eps != NULL; eps = eps->next)
    165   {
    166     for(InstanceList * instances = eps->instances; instances != NULL; instances = instances->next)
    167     {
    168       if(instances->instance == instance)
    169         return &eps->realNPPFuncs;
    170     }
    171   }
    172 
    173   return NULL;
    174 }
    175 
    176 void NPPEntryPointManager::callNP_ShutdownAll()
    177 {
    178   for(PluginEntryPointList * eps = mEntryPoints; eps != NULL; eps = eps->next)
    179   {
    180     if(eps->realShutdown)
    181     {
    182       logger->logSPY_NP_Shutdown(eps->mimetype);
    183       eps->realShutdown();
    184       eps->realShutdown = NULL; // don't want to call it more than once
    185     }
    186   }
    187 }
    188 
    189 void NPPEntryPointManager::callNP_Shutdown(NPP instance)
    190 {
    191   for(PluginEntryPointList * eps = mEntryPoints; eps != NULL; eps = eps->next)
    192   {
    193     for(InstanceList * instances = eps->instances; instances != NULL; instances = instances->next)
    194     {
    195       if(instances->instance == instance)
    196       {
    197         if(eps->realShutdown)
    198         {
    199           logger->logSPY_NP_Shutdown(eps->mimetype);
    200           eps->realShutdown();
    201           eps->realShutdown = NULL; // don't want to call it more than once
    202         }
    203       }
    204     }
    205   }
    206 }
    207 
    208 NPError NPPEntryPointManager::callNPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved)
    209 {
    210   NPPluginFuncs * nppfuncs = NULL;
    211 
    212   for(PluginEntryPointList * eps = mEntryPoints; eps != NULL; eps = eps->next)
    213   {
    214     if(0 == _stricmp(eps->mimetype, pluginType))
    215     {
    216       nppfuncs = &eps->realNPPFuncs;
    217 
    218       // now we should associate this plugin instance with plugin entry points
    219       // so that later we could find entry points by instance rather than by mimetype
    220       InstanceList * inst = new InstanceList(instance);
    221       inst->next = eps->instances;
    222       eps->instances = inst;
    223 
    224       break;
    225     }
    226   }
    227 
    228   if(!nppfuncs || !nppfuncs->newp)
    229     return NPERR_GENERIC_ERROR;
    230 
    231   NPError rv = CallNPP_NewProc(nppfuncs->newp, pluginType, instance, mode, argc, argn, argv, saved);
    232 
    233   return rv;
    234 }
    235 
    236 NPError NPPEntryPointManager::callNPP_Destroy(NPP instance, NPSavedData** save, BOOL * last)
    237 {
    238   NPPluginFuncs * nppfuncs = NULL;
    239 
    240   BOOL done = FALSE;
    241 
    242   for(PluginEntryPointList * eps = mEntryPoints; eps != NULL; eps = eps->next)
    243   {
    244     InstanceList * prev = NULL;
    245     for(InstanceList * instances = eps->instances; instances != NULL; instances = instances->next)
    246     {
    247       if(instances->instance == instance)
    248       {
    249         nppfuncs = &eps->realNPPFuncs;
    250         done = TRUE;
    251 
    252         // check if this is the last one
    253         if(eps->instances->next == NULL)
    254           *last = TRUE;
    255         else
    256         {
    257           // deassociate instance if this is not the last one
    258           // last instance will be needed to find corresponding shutdown proc
    259           if(prev)
    260             prev->next = instances->next;
    261           else
    262             eps->instances = instances->next;
    263 
    264           delete instances;
    265         }
    266 
    267         break;
    268       }
    269       prev = instances;
    270     }
    271     if(done)
    272       break;
    273   }
    274 
    275   if(!nppfuncs || !nppfuncs->destroy)
    276     return NPERR_GENERIC_ERROR;
    277 
    278   return CallNPP_DestroyProc(nppfuncs->destroy, instance, save);
    279 }
    280 
    281 NPError NPPEntryPointManager::callNPP_SetWindow(NPP instance, NPWindow* window)
    282 {
    283   NPPluginFuncs * nppfuncs = findEntryPointsForInstance(instance);
    284   if(!nppfuncs || !nppfuncs->setwindow)
    285     return NPERR_GENERIC_ERROR;
    286 
    287   return CallNPP_SetWindowProc(nppfuncs->setwindow, instance, window);
    288 }
    289 
    290 NPError NPPEntryPointManager::callNPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype)
    291 {
    292   NPPluginFuncs * nppfuncs = findEntryPointsForInstance(instance);
    293   if(!nppfuncs || !nppfuncs->newstream)
    294     return NPERR_GENERIC_ERROR;
    295 
    296   return CallNPP_NewStreamProc(nppfuncs->newstream, instance, type, stream, seekable, stype);
    297 }
    298 
    299 NPError NPPEntryPointManager::callNPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason)
    300 {
    301   NPPluginFuncs * nppfuncs = findEntryPointsForInstance(instance);
    302   if(!nppfuncs || !nppfuncs->destroystream)
    303     return NPERR_GENERIC_ERROR;
    304 
    305   return CallNPP_DestroyStreamProc(nppfuncs->destroystream, instance, stream, reason);
    306 }
    307 
    308 int32 NPPEntryPointManager::callNPP_WriteReady(NPP instance, NPStream* stream)
    309 {
    310   NPPluginFuncs * nppfuncs = findEntryPointsForInstance(instance);
    311   if(!nppfuncs || !nppfuncs->writeready)
    312     return NPERR_GENERIC_ERROR;
    313 
    314   return CallNPP_WriteReadyProc(nppfuncs->writeready, instance, stream);
    315 }
    316 
    317 int32 NPPEntryPointManager::callNPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer)
    318 {
    319   NPPluginFuncs * nppfuncs = findEntryPointsForInstance(instance);
    320   if(!nppfuncs || !nppfuncs->write)
    321     return NPERR_GENERIC_ERROR;
    322 
    323   return CallNPP_WriteProc(nppfuncs->write, instance, stream, offset, len, buffer);
    324 }
    325 
    326 void NPPEntryPointManager::callNPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname)
    327 {
    328   NPPluginFuncs * nppfuncs = findEntryPointsForInstance(instance);
    329   if(!nppfuncs || !nppfuncs->asfile)
    330     return;
    331 
    332   CallNPP_StreamAsFileProc(nppfuncs->asfile, instance, stream, fname);
    333 }
    334 
    335 void NPPEntryPointManager::callNPP_Print(NPP instance, NPPrint* platformPrint)
    336 {
    337   NPPluginFuncs * nppfuncs = findEntryPointsForInstance(instance);
    338   if(!nppfuncs || !nppfuncs->print)
    339     return;
    340 
    341   CallNPP_PrintProc(nppfuncs->print, instance, platformPrint);
    342 }
    343 
    344 void NPPEntryPointManager::callNPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData)
    345 {
    346    NPPluginFuncs * nppfuncs = findEntryPointsForInstance(instance);
    347   if(!nppfuncs || !nppfuncs->urlnotify)
    348     return;
    349 
    350   CallNPP_URLNotifyProc(nppfuncs->urlnotify, instance, url, reason, notifyData);
    351 }
    352 
    353 NPError NPPEntryPointManager::callNPP_GetValue(NPP instance, NPPVariable variable, void *value)
    354 {
    355   NPPluginFuncs * nppfuncs = findEntryPointsForInstance(instance);
    356   if(!nppfuncs || !nppfuncs->getvalue)
    357     return NPERR_GENERIC_ERROR;
    358 
    359   return CallNPP_GetValueProc(nppfuncs->getvalue, instance, variable, value);
    360 }
    361 
    362 NPError NPPEntryPointManager::callNPP_SetValue(NPP instance, NPNVariable variable, void *value)
    363 {
    364   NPPluginFuncs * nppfuncs = findEntryPointsForInstance(instance);
    365   if(!nppfuncs || !nppfuncs->setvalue)
    366     return NPERR_GENERIC_ERROR;
    367 
    368   return CallNPP_SetValueProc(nppfuncs->setvalue, instance, variable, value);
    369 }
    370 
    371 int16 NPPEntryPointManager::callNPP_HandleEvent(NPP instance, void* event)
    372 {
    373   NPPluginFuncs * nppfuncs = findEntryPointsForInstance(instance);
    374   if(!nppfuncs || !nppfuncs->event)
    375     return NPERR_GENERIC_ERROR;
    376 
    377   return CallNPP_HandleEventProc(nppfuncs->event, instance, event);
    378 }
    379