Back to index

lightning-sunbird  0.9+nobinonly
plugin.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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 "nsISupportsUtils.h" // some usefule macros are defined here
00040 
00041 #include <string.h>
00042 
00043 #if !TARGET_API_MAC_CARBON
00044 extern QDGlobals*    gQDPtr;
00045 #endif
00046 
00048 //
00049 // general initialization and shutdown
00050 //
00051 NPError NS_PluginInitialize()
00052 {
00053   return NPERR_NO_ERROR;
00054 }
00055 
00056 void NS_PluginShutdown()
00057 {
00058 }
00059 
00061 //
00062 // construction and destruction of our plugin instance object
00063 //
00064 nsPluginInstanceBase * NS_NewPluginInstance(nsPluginCreateData * aCreateDataStruct)
00065 {
00066   if(!aCreateDataStruct)
00067     return NULL;
00068 
00069   nsPluginInstance * plugin = new nsPluginInstance(aCreateDataStruct->instance);
00070   return plugin;
00071 }
00072 
00073 void NS_DestroyPluginInstance(nsPluginInstanceBase * aPlugin)
00074 {
00075   if(aPlugin)
00076     delete (nsPluginInstance *)aPlugin;
00077 }
00078 
00080 //
00081 // nsPluginInstance class implementation
00082 //
00083 nsPluginInstance::nsPluginInstance(NPP aInstance) : nsPluginInstanceBase(),
00084   mInstance(aInstance),
00085   mInitialized(FALSE),
00086   mScriptablePeer(NULL)
00087 {
00088   mWindow = NULL;
00089   mString[0] = '\0';
00090 }
00091 
00092 nsPluginInstance::~nsPluginInstance()
00093 {
00094   // mScriptablePeer may be also held by the browser 
00095   // so releasing it here does not guarantee that it is over
00096   // we should take precaution in case it will be called later
00097   // and zero its mPlugin member
00098   mScriptablePeer->SetInstance(NULL);
00099   NS_IF_RELEASE(mScriptablePeer);
00100 }
00101 
00102 NPBool nsPluginInstance::init(NPWindow* aWindow)
00103 {
00104   if(aWindow == NULL)
00105     return FALSE;
00106   
00107   mWindow = aWindow;
00108   mInitialized = TRUE;
00109   mSaveClip = NewRgn();
00110   return TRUE;
00111 }
00112 
00113 void nsPluginInstance::shut()
00114 {
00115   mWindow = NULL;
00116   mInitialized = FALSE;
00117 }
00118 
00119 NPBool nsPluginInstance::isInitialized()
00120 {
00121   return mInitialized;
00122 }
00123 
00125 //
00126 // DrawString
00127 //
00128 void
00129 nsPluginInstance::DrawString(const unsigned char* text, 
00130                              short width, 
00131                              short height, 
00132                              short centerX, 
00133                              Rect drawRect)
00134 {
00135        short length, textHeight, textWidth;
00136  
00137        if(text == NULL)
00138               return;
00139        
00140        length = strlen((char*)text);
00141        TextFont(1);
00142        TextFace(bold);
00143        TextMode(srcCopy);
00144        TextSize(12);
00145        
00146        FontInfo fontInfo;
00147        GetFontInfo(&fontInfo);
00148 
00149        textHeight = fontInfo.ascent + fontInfo.descent + fontInfo.leading;
00150        textWidth = TextWidth(text, 0, length);
00151               
00152        if (width > textWidth && height > textHeight)
00153        {
00154               MoveTo(centerX - (textWidth >> 1), height >> 1);
00155               DrawText(text, 0, length);
00156        }             
00157 }
00158 
00160 //
00161 // DoDraw - paint
00162 //
00163 void 
00164 nsPluginInstance::DoDraw(void)
00165 {
00166        Rect drawRect;
00167   RGBColor    black = { 0x0000, 0x0000, 0x0000 };
00168   RGBColor    white = { 0xFFFF, 0xFFFF, 0xFFFF };
00169        SInt32        height = mWindow->height;
00170        SInt32        width = mWindow->width;
00171        SInt32        centerX = (width) >> 1;
00172        SInt32        centerY = (height) >> 1;
00173 
00174        UInt8         *pTheText = (unsigned char*) mString;
00175 
00176        drawRect.top = 0;
00177        drawRect.left = 0;
00178        drawRect.bottom = drawRect.top + height;
00179        drawRect.right = drawRect.left + width;
00180 
00181   PenNormal();
00182   RGBForeColor(&black);
00183   RGBBackColor(&white);
00184 
00185 #if !TARGET_API_MAC_CARBON
00186   FillRect(&drawRect, &(gQDPtr->white));
00187 #else
00188   Pattern qdWhite;
00189   FillRect(&drawRect, GetQDGlobalsWhite(&qdWhite));
00190 #endif
00191 
00192        FrameRect(&drawRect);
00193   DrawString(pTheText, width, height, centerX, drawRect);
00194 }
00195 
00197 //
00198 // SetWindow
00199 //
00200 NPError
00201 nsPluginInstance::SetWindow(NPWindow* window)
00202 {
00203        mWindow = window;
00204        if( StartDraw(window) ) {
00205               DoDraw();
00206               EndDraw(window);
00207        }
00208        return NPERR_NO_ERROR;
00209 }
00210 
00212 //
00213 // HandleEvent
00214 //
00215 uint16
00216 nsPluginInstance::HandleEvent(void* event)
00217 {
00218        int16 eventHandled = FALSE;
00219        
00220        EventRecord* ev = (EventRecord*) event;
00221        if (event != NULL)
00222        {
00223               switch (ev->what)
00224               {
00225                      /*
00226                       * Draw ourselves on update events
00227                       */
00228                      case updateEvt:
00229                             if( StartDraw(mWindow) ) {
00230                                    DoDraw();
00231                                    EndDraw(mWindow);
00232                             }
00233                             eventHandled = true;
00234                             break;
00235 
00236                      default:
00237                             break;
00238               }
00239        }
00240        return eventHandled;
00241 }
00242 
00244 //
00245 // StartDraw - setup port state
00246 //
00247 NPBool
00248 nsPluginInstance::StartDraw(NPWindow* window)
00249 {
00250        if (mWindow == NULL)
00251               return false;
00252               
00253        NP_Port* npport = (NP_Port*) mWindow->window;
00254        CGrafPtr ourPort = npport->port;
00255        
00256        if (mWindow->clipRect.left < mWindow->clipRect.right)
00257        {
00258               GetPort(&mSavePort);
00259               SetPort((GrafPtr) ourPort);
00260     Rect portRect;
00261 #if !TARGET_API_MAC_CARBON
00262     portRect = ourPort->portRect;
00263 #else
00264     GetPortBounds(ourPort, &portRect);
00265 #endif
00266               mSavePortTop = portRect.top;
00267               mSavePortLeft = portRect.left;
00268               GetClip(mSaveClip);
00269               
00270               mRevealedRect.top = mWindow->clipRect.top + npport->porty;
00271               mRevealedRect.left = mWindow->clipRect.left + npport->portx;
00272               mRevealedRect.bottom = mWindow->clipRect.bottom + npport->porty;
00273               mRevealedRect.right = mWindow->clipRect.right + npport->portx;
00274               SetOrigin(npport->portx, npport->porty);
00275               ClipRect(&mRevealedRect);
00276 
00277               return true;
00278        }
00279        else
00280               return false;
00281 }
00282 
00284 //
00285 // EndDraw - restore port state
00286 //
00287 void
00288 nsPluginInstance::EndDraw(NPWindow* window)
00289 {
00290        SetOrigin(mSavePortLeft, mSavePortTop);
00291        SetClip(mSaveClip);
00292        SetPort(mSavePort);
00293 }
00294 
00295 
00296 // this will force to draw a version string in the plugin window
00297 void nsPluginInstance::showVersion()
00298 {
00299   const char *ua = NPN_UserAgent(mInstance);
00300   strcpy(mString, ua);
00301 
00302   StartDraw(mWindow);
00303   DoDraw();
00304   EndDraw(mWindow);
00305 }
00306 
00307 // this will clean the plugin window
00308 void nsPluginInstance::clear()
00309 {
00310   strcpy(mString, "");
00311 
00312   StartDraw(mWindow);
00313   DoDraw();
00314   EndDraw(mWindow);
00315 }
00316 
00317 // ==============================
00318 // ! Scriptability related code !
00319 // ==============================
00320 //
00321 // here the plugin is asked by Mozilla to tell if it is scriptable
00322 // we should return a valid interface id and a pointer to 
00323 // nsScriptablePeer interface which we should have implemented
00324 // and which should be defined in the corressponding *.xpt file
00325 // in the bin/components folder
00326 NPError       nsPluginInstance::GetValue(NPPVariable aVariable, void *aValue)
00327 {
00328   NPError rv = NPERR_NO_ERROR;
00329 
00330   switch (aVariable) {
00331     case NPPVpluginScriptableInstance: {
00332       // addref happens in getter, so we don't addref here
00333       nsIScriptablePluginSample * scriptablePeer = getScriptablePeer();
00334       if (scriptablePeer) {
00335         *(nsISupports **)aValue = scriptablePeer;
00336       } else
00337         rv = NPERR_OUT_OF_MEMORY_ERROR;
00338     }
00339     break;
00340 
00341     case NPPVpluginScriptableIID: {
00342       static nsIID scriptableIID = NS_ISCRIPTABLEPLUGINSAMPLE_IID;
00343       nsIID* ptr = (nsIID *)NPN_MemAlloc(sizeof(nsIID));
00344       if (ptr) {
00345           *ptr = scriptableIID;
00346           *(nsIID **)aValue = ptr;
00347       } else
00348         rv = NPERR_OUT_OF_MEMORY_ERROR;
00349     }
00350     break;
00351 
00352     default:
00353       break;
00354   }
00355 
00356   return rv;
00357 }
00358 
00359 // ==============================
00360 // ! Scriptability related code !
00361 // ==============================
00362 //
00363 // this method will return the scriptable object (and create it if necessary)
00364 nsScriptablePeer* nsPluginInstance::getScriptablePeer()
00365 {
00366   if (!mScriptablePeer) {
00367     mScriptablePeer = new nsScriptablePeer(this);
00368     if(!mScriptablePeer)
00369       return NULL;
00370 
00371     NS_ADDREF(mScriptablePeer);
00372   }
00373 
00374   // add reference for the caller requesting the object
00375   NS_ADDREF(mScriptablePeer);
00376   return mScriptablePeer;
00377 }