LCOV - code coverage report
Current view: directory - dom/plugins/ipc - PluginInstanceChild.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 894 0 0.0 %
Date: 2012-06-02 Functions: 80 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2                 :  * vim: sw=4 ts=4 et :
       3                 :  * ***** BEGIN LICENSE BLOCK *****
       4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       5                 :  *
       6                 :  * The contents of this file are subject to the Mozilla Public License Version
       7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       8                 :  * the License. You may obtain a copy of the License at
       9                 :  * http://www.mozilla.org/MPL/
      10                 :  *
      11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      13                 :  * for the specific language governing rights and limitations under the
      14                 :  * License.
      15                 :  *
      16                 :  * The Original Code is Mozilla Plugin App.
      17                 :  *
      18                 :  * The Initial Developer of the Original Code is
      19                 :  *   Chris Jones <jones.chris.g@gmail.com>
      20                 :  * Portions created by the Initial Developer are Copyright (C) 2009
      21                 :  * the Initial Developer. All Rights Reserved.
      22                 :  *
      23                 :  * Contributor(s):
      24                 :  *   Jim Mathies <jmathies@mozilla.com>
      25                 :  *
      26                 :  * Alternatively, the contents of this file may be used under the terms of
      27                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      28                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      30                 :  * of those above. If you wish to allow use of your version of this file only
      31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      32                 :  * use your version of this file under the terms of the MPL, indicate your
      33                 :  * decision by deleting the provisions above and replace them with the notice
      34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      35                 :  * the provisions above, a recipient may use your version of this file under
      36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      37                 :  *
      38                 :  * ***** END LICENSE BLOCK ***** */
      39                 : 
      40                 : #if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
      41                 : #include <QEvent>
      42                 : #include <QKeyEvent>
      43                 : #include <QApplication>
      44                 : #include <QInputMethodEvent>
      45                 : #include "nsQtKeyUtils.h"
      46                 : #endif
      47                 : 
      48                 : #include "PluginBackgroundDestroyer.h"
      49                 : #include "PluginInstanceChild.h"
      50                 : #include "PluginModuleChild.h"
      51                 : #include "BrowserStreamChild.h"
      52                 : #include "PluginStreamChild.h"
      53                 : #include "StreamNotifyChild.h"
      54                 : #include "PluginProcessChild.h"
      55                 : #include "gfxASurface.h"
      56                 : #include "gfxContext.h"
      57                 : #include "nsNPAPIPluginInstance.h"
      58                 : #ifdef MOZ_X11
      59                 : #include "gfxXlibSurface.h"
      60                 : #endif
      61                 : #ifdef XP_WIN
      62                 : #include "mozilla/gfx/SharedDIBSurface.h"
      63                 : #include "nsCrashOnException.h"
      64                 : extern const PRUnichar* kFlashFullscreenClass;
      65                 : using mozilla::gfx::SharedDIBSurface;
      66                 : #endif
      67                 : #include "gfxSharedImageSurface.h"
      68                 : #include "gfxUtils.h"
      69                 : #include "gfxAlphaRecovery.h"
      70                 : 
      71                 : #include "mozilla/Util.h"
      72                 : #include "mozilla/ipc/SyncChannel.h"
      73                 : #include "mozilla/AutoRestore.h"
      74                 : 
      75                 : using namespace mozilla;
      76                 : using mozilla::ipc::ProcessChild;
      77                 : using namespace mozilla::plugins;
      78                 : using namespace std;
      79                 : 
      80                 : #ifdef MOZ_WIDGET_GTK2
      81                 : 
      82                 : #include <gtk/gtk.h>
      83                 : #include <gdk/gdkx.h>
      84                 : #include <gdk/gdk.h>
      85                 : #include "gtk2xtbin.h"
      86                 : 
      87                 : #elif defined(MOZ_WIDGET_QT)
      88                 : #include <QX11Info>
      89                 : #undef KeyPress
      90                 : #undef KeyRelease
      91                 : #elif defined(OS_WIN)
      92                 : #ifndef WM_MOUSEHWHEEL
      93                 : #define WM_MOUSEHWHEEL     0x020E
      94                 : #endif
      95                 : 
      96                 : #include "nsWindowsDllInterceptor.h"
      97                 : 
      98                 : typedef BOOL (WINAPI *User32TrackPopupMenu)(HMENU hMenu,
      99                 :                                             UINT uFlags,
     100                 :                                             int x,
     101                 :                                             int y,
     102                 :                                             int nReserved,
     103                 :                                             HWND hWnd,
     104                 :                                             CONST RECT *prcRect);
     105                 : static WindowsDllInterceptor sUser32Intercept;
     106                 : static HWND sWinlessPopupSurrogateHWND = NULL;
     107                 : static User32TrackPopupMenu sUser32TrackPopupMenuStub = NULL;
     108                 : 
     109                 : using mozilla::gfx::SharedDIB;
     110                 : 
     111                 : #include <windows.h>
     112                 : #include <windowsx.h>
     113                 : 
     114                 : // Flash WM_USER message delay time for PostDelayedTask. Borrowed
     115                 : // from Chromium's web plugin delegate src. See 'flash msg throttling
     116                 : // helpers' section for details.
     117                 : const int kFlashWMUSERMessageThrottleDelayMs = 5;
     118                 : 
     119                 : static const TCHAR kPluginIgnoreSubclassProperty[] = TEXT("PluginIgnoreSubclassProperty");
     120                 : 
     121                 : #elif defined(XP_MACOSX)
     122                 : #include <ApplicationServices/ApplicationServices.h>
     123                 : #include "nsCocoaFeatures.h"
     124                 : #include "PluginUtilsOSX.h"
     125                 : #endif // defined(XP_MACOSX)
     126                 : 
     127                 : template<>
     128                 : struct RunnableMethodTraits<PluginInstanceChild>
     129               0 : {
     130               0 :     static void RetainCallee(PluginInstanceChild* obj) { }
     131               0 :     static void ReleaseCallee(PluginInstanceChild* obj) { }
     132                 : };
     133                 : 
     134               0 : PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface)
     135                 :     : mPluginIface(aPluginIface)
     136                 :     , mDrawingModel(kDefaultDrawingModel)
     137                 :     , mCurrentAsyncSurface(0)
     138                 :     , mAsyncInvalidateMutex("PluginInstanceChild::mAsyncInvalidateMutex")
     139                 :     , mAsyncInvalidateTask(0)
     140                 :     , mCachedWindowActor(nsnull)
     141                 :     , mCachedElementActor(nsnull)
     142                 : #if defined(OS_WIN)
     143                 :     , mPluginWindowHWND(0)
     144                 :     , mPluginWndProc(0)
     145                 :     , mPluginParentHWND(0)
     146                 :     , mCachedWinlessPluginHWND(0)
     147                 :     , mWinlessPopupSurrogateHWND(0)
     148                 :     , mWinlessThrottleOldWndProc(0)
     149                 :     , mWinlessHiddenMsgHWND(0)
     150                 : #endif // OS_WIN
     151                 :     , mAsyncCallMutex("PluginInstanceChild::mAsyncCallMutex")
     152                 : #if defined(MOZ_WIDGET_COCOA)
     153                 : #if defined(__i386__)
     154                 :     , mEventModel(NPEventModelCarbon)
     155                 : #endif
     156                 :     , mShColorSpace(nsnull)
     157                 :     , mShContext(nsnull)
     158                 :     , mCGLayer(nsnull)
     159                 :     , mCurrentEvent(nsnull)
     160                 : #endif
     161                 :     , mLayersRendering(false)
     162                 : #ifdef XP_WIN
     163                 :     , mCurrentSurfaceActor(NULL)
     164                 :     , mBackSurfaceActor(NULL)
     165                 : #endif
     166                 :     , mAccumulatedInvalidRect(0,0,0,0)
     167                 :     , mIsTransparent(false)
     168                 :     , mSurfaceType(gfxASurface::SurfaceTypeMax)
     169                 :     , mCurrentInvalidateTask(nsnull)
     170                 :     , mCurrentAsyncSetWindowTask(nsnull)
     171                 :     , mPendingPluginCall(false)
     172                 :     , mDoAlphaExtraction(false)
     173                 :     , mHasPainted(false)
     174               0 :     , mSurfaceDifferenceRect(0,0,0,0)
     175                 : #if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6)
     176                 :     , mMaemoImageRendering(true)
     177                 : #endif
     178                 : {
     179               0 :     memset(&mWindow, 0, sizeof(mWindow));
     180               0 :     mData.ndata = (void*) this;
     181               0 :     mData.pdata = nsnull;
     182               0 :     mAsyncBitmaps.Init();
     183                 : #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
     184               0 :     mWindow.ws_info = &mWsInfo;
     185               0 :     memset(&mWsInfo, 0, sizeof(mWsInfo));
     186               0 :     mWsInfo.display = DefaultXDisplay();
     187                 : #endif // MOZ_X11 && XP_UNIX && !XP_MACOSX
     188                 : #if defined(OS_WIN)
     189                 :     memset(&mAlphaExtract, 0, sizeof(mAlphaExtract));
     190                 : #endif // OS_WIN
     191                 : #if defined(OS_WIN)
     192                 :     InitPopupMenuHook();
     193                 : #endif // OS_WIN
     194               0 : }
     195                 : 
     196               0 : PluginInstanceChild::~PluginInstanceChild()
     197                 : {
     198                 : #if defined(OS_WIN)
     199                 :     NS_ASSERTION(!mPluginWindowHWND, "Destroying PluginInstanceChild without NPP_Destroy?");
     200                 : #endif
     201                 : #if defined(MOZ_WIDGET_COCOA)
     202                 :     if (mShColorSpace) {
     203                 :         ::CGColorSpaceRelease(mShColorSpace);
     204                 :     }
     205                 :     if (mShContext) {
     206                 :         ::CGContextRelease(mShContext);
     207                 :     }
     208                 :     if (mCGLayer) {
     209                 :         PluginUtilsOSX::ReleaseCGLayer(mCGLayer);
     210                 :     }
     211                 :     if (mDrawingModel == NPDrawingModelCoreAnimation) {
     212                 :         UnscheduleTimer(mCARefreshTimer);
     213                 :     }
     214                 : #endif
     215               0 : }
     216                 : 
     217                 : int
     218               0 : PluginInstanceChild::GetQuirks()
     219                 : {
     220               0 :     return PluginModuleChild::current()->GetQuirks();
     221                 : }
     222                 : 
     223                 : NPError
     224               0 : PluginInstanceChild::InternalGetNPObjectForValue(NPNVariable aValue,
     225                 :                                                  NPObject** aObject)
     226                 : {
     227               0 :     PluginScriptableObjectChild* actor = NULL;
     228               0 :     NPError result = NPERR_NO_ERROR;
     229                 : 
     230               0 :     switch (aValue) {
     231                 :         case NPNVWindowNPObject:
     232               0 :             if (!(actor = mCachedWindowActor)) {
     233                 :                 PPluginScriptableObjectChild* actorProtocol;
     234               0 :                 CallNPN_GetValue_NPNVWindowNPObject(&actorProtocol, &result);
     235               0 :                 if (result == NPERR_NO_ERROR) {
     236                 :                     actor = mCachedWindowActor =
     237               0 :                         static_cast<PluginScriptableObjectChild*>(actorProtocol);
     238               0 :                     NS_ASSERTION(actor, "Null actor!");
     239                 :                     PluginModuleChild::sBrowserFuncs.retainobject(
     240               0 :                         actor->GetObject(false));
     241                 :                 }
     242                 :             }
     243               0 :             break;
     244                 : 
     245                 :         case NPNVPluginElementNPObject:
     246               0 :             if (!(actor = mCachedElementActor)) {
     247                 :                 PPluginScriptableObjectChild* actorProtocol;
     248                 :                 CallNPN_GetValue_NPNVPluginElementNPObject(&actorProtocol,
     249               0 :                                                            &result);
     250               0 :                 if (result == NPERR_NO_ERROR) {
     251                 :                     actor = mCachedElementActor =
     252               0 :                         static_cast<PluginScriptableObjectChild*>(actorProtocol);
     253               0 :                     NS_ASSERTION(actor, "Null actor!");
     254                 :                     PluginModuleChild::sBrowserFuncs.retainobject(
     255               0 :                         actor->GetObject(false));
     256                 :                 }
     257                 :             }
     258               0 :             break;
     259                 : 
     260                 :         default:
     261               0 :             NS_NOTREACHED("Don't know what to do with this value type!");
     262                 :     }
     263                 : 
     264                 : #ifdef DEBUG
     265                 :     {
     266                 :         NPError currentResult;
     267                 :         PPluginScriptableObjectChild* currentActor;
     268                 : 
     269               0 :         switch (aValue) {
     270                 :             case NPNVWindowNPObject:
     271                 :                 CallNPN_GetValue_NPNVWindowNPObject(&currentActor,
     272               0 :                                                     &currentResult);
     273               0 :                 break;
     274                 :             case NPNVPluginElementNPObject:
     275                 :                 CallNPN_GetValue_NPNVPluginElementNPObject(&currentActor,
     276               0 :                                                            &currentResult);
     277               0 :                 break;
     278                 :             default:
     279               0 :                 NS_NOTREACHED("Don't know what to do with this value type!");
     280                 :         }
     281                 : 
     282                 :         // Make sure that the current actor returned by the parent matches our
     283                 :         // cached actor!
     284               0 :         NS_ASSERTION(static_cast<PluginScriptableObjectChild*>(currentActor) ==
     285                 :                      actor, "Cached actor is out of date!");
     286               0 :         NS_ASSERTION(currentResult == result, "Results don't match?!");
     287                 :     }
     288                 : #endif
     289                 : 
     290               0 :     if (result != NPERR_NO_ERROR) {
     291               0 :         return result;
     292                 :     }
     293                 : 
     294               0 :     NPObject* object = actor->GetObject(false);
     295               0 :     NS_ASSERTION(object, "Null object?!");
     296                 : 
     297               0 :     *aObject = PluginModuleChild::sBrowserFuncs.retainobject(object);
     298               0 :     return NPERR_NO_ERROR;
     299                 : 
     300                 : }
     301                 : 
     302                 : NPError
     303               0 : PluginInstanceChild::NPN_GetValue(NPNVariable aVar,
     304                 :                                   void* aValue)
     305                 : {
     306               0 :     PLUGIN_LOG_DEBUG(("%s (aVar=%i)", FULLFUNCTION, (int) aVar));
     307               0 :     AssertPluginThread();
     308                 : 
     309               0 :     switch(aVar) {
     310                 : 
     311                 :     case NPNVSupportsWindowless:
     312                 : #if defined(OS_LINUX) || defined(MOZ_X11) || defined(OS_WIN)
     313               0 :         *((NPBool*)aValue) = true;
     314                 : #else
     315                 :         *((NPBool*)aValue) = false;
     316                 : #endif
     317               0 :         return NPERR_NO_ERROR;
     318                 : 
     319                 : #if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6)
     320                 :     case NPNVSupportsWindowlessLocal: {
     321                 : #ifdef MOZ_WIDGET_QT
     322                 :         const char *graphicsSystem = PR_GetEnv("MOZ_QT_GRAPHICSSYSTEM");
     323                 :         // we should set local rendering to false in order to render X-Plugin
     324                 :         // there is no possibility to change it later on maemo5 platform
     325                 :         mMaemoImageRendering = (!(graphicsSystem && !strcmp(graphicsSystem, "native")));
     326                 : #endif
     327                 :         *((NPBool*)aValue) = mMaemoImageRendering;
     328                 :         return NPERR_NO_ERROR;
     329                 :     }
     330                 : #endif
     331                 : #if defined(MOZ_X11)
     332                 :     case NPNVSupportsXEmbedBool:
     333               0 :         *((NPBool*)aValue) = true;
     334               0 :         return NPERR_NO_ERROR;
     335                 : 
     336                 :     case NPNVToolkit:
     337               0 :         *((NPNToolkitType*)aValue) = NPNVGtk2;
     338               0 :         return NPERR_NO_ERROR;
     339                 : 
     340                 : #elif defined(OS_WIN)
     341                 :     case NPNVToolkit:
     342                 :         return NPERR_GENERIC_ERROR;
     343                 : #endif
     344                 :     case NPNVjavascriptEnabledBool: {
     345               0 :         bool v = false;
     346                 :         NPError result;
     347               0 :         if (!CallNPN_GetValue_NPNVjavascriptEnabledBool(&v, &result)) {
     348               0 :             return NPERR_GENERIC_ERROR;
     349                 :         }
     350               0 :         *static_cast<NPBool*>(aValue) = v;
     351               0 :         return result;
     352                 :     }
     353                 : 
     354                 :     case NPNVisOfflineBool: {
     355               0 :         bool v = false;
     356                 :         NPError result;
     357               0 :         if (!CallNPN_GetValue_NPNVisOfflineBool(&v, &result)) {
     358               0 :             return NPERR_GENERIC_ERROR;
     359                 :         }
     360               0 :         *static_cast<NPBool*>(aValue) = v;
     361               0 :         return result;
     362                 :     }
     363                 : 
     364                 :     case NPNVprivateModeBool: {
     365               0 :         bool v = false;
     366                 :         NPError result;
     367               0 :         if (!CallNPN_GetValue_NPNVprivateModeBool(&v, &result)) {
     368               0 :             return NPERR_GENERIC_ERROR;
     369                 :         }
     370               0 :         *static_cast<NPBool*>(aValue) = v;
     371               0 :         return result;
     372                 :     }
     373                 : 
     374                 :     case NPNVdocumentOrigin: {
     375               0 :         nsCString v;
     376                 :         NPError result;
     377               0 :         if (!CallNPN_GetValue_NPNVdocumentOrigin(&v, &result)) {
     378               0 :             return NPERR_GENERIC_ERROR;
     379                 :         }
     380               0 :         if (result == NPERR_NO_ERROR) {
     381               0 :             *static_cast<char**>(aValue) = ToNewCString(v);
     382                 :         }
     383               0 :         return result;
     384                 :     }
     385                 : 
     386                 :     case NPNVWindowNPObject: // Intentional fall-through
     387                 :     case NPNVPluginElementNPObject: {
     388                 :         NPObject* object;
     389               0 :         NPError result = InternalGetNPObjectForValue(aVar, &object);
     390               0 :         if (result == NPERR_NO_ERROR) {
     391               0 :             *((NPObject**)aValue) = object;
     392                 :         }
     393               0 :         return result;
     394                 :     }
     395                 : 
     396                 :     case NPNVnetscapeWindow: {
     397                 : #ifdef XP_WIN
     398                 :         if (mWindow.type == NPWindowTypeDrawable) {
     399                 :             if (mCachedWinlessPluginHWND) {
     400                 :               *static_cast<HWND*>(aValue) = mCachedWinlessPluginHWND;
     401                 :               return NPERR_NO_ERROR;
     402                 :             }
     403                 :             NPError result;
     404                 :             if (!CallNPN_GetValue_NPNVnetscapeWindow(&mCachedWinlessPluginHWND, &result)) {
     405                 :                 return NPERR_GENERIC_ERROR;
     406                 :             }
     407                 :             *static_cast<HWND*>(aValue) = mCachedWinlessPluginHWND;
     408                 :             return result;
     409                 :         }
     410                 :         else {
     411                 :             *static_cast<HWND*>(aValue) = mPluginWindowHWND;
     412                 :             return NPERR_NO_ERROR;
     413                 :         }
     414                 : #elif defined(MOZ_X11)
     415                 :         NPError result;
     416               0 :         CallNPN_GetValue_NPNVnetscapeWindow(static_cast<XID*>(aValue), &result);
     417               0 :         return result;
     418                 : #else
     419                 :         return NPERR_GENERIC_ERROR;
     420                 : #endif
     421                 :     }
     422                 : 
     423                 :     case NPNVsupportsAsyncBitmapSurfaceBool: {
     424                 : #ifdef XP_WIN
     425                 :         *((NPBool*)aValue) = PluginModuleChild::current()->AsyncDrawingAllowed();
     426                 : #else
     427                 :         // We do not support non-windows yet.
     428               0 :         *((NPBool*)aValue) = false;
     429                 : #endif
     430               0 :         return NPERR_NO_ERROR;
     431                 :     }
     432                 : 
     433                 : #ifdef XP_MACOSX
     434                 :    case NPNVsupportsCoreGraphicsBool: {
     435                 :         *((NPBool*)aValue) = true;
     436                 :         return NPERR_NO_ERROR;
     437                 :     }
     438                 : 
     439                 :     case NPNVsupportsCoreAnimationBool: {
     440                 :         *((NPBool*)aValue) = nsCocoaFeatures::SupportCoreAnimationPlugins();
     441                 :         return NPERR_NO_ERROR;
     442                 :     }
     443                 : 
     444                 :     case NPNVsupportsInvalidatingCoreAnimationBool: {
     445                 :         *((NPBool*)aValue) = nsCocoaFeatures::SupportCoreAnimationPlugins();
     446                 :         return NPERR_NO_ERROR;
     447                 :     }
     448                 : 
     449                 :     case NPNVsupportsCocoaBool: {
     450                 :         *((NPBool*)aValue) = true;
     451                 :         return NPERR_NO_ERROR;
     452                 :     }
     453                 : 
     454                 : #ifndef NP_NO_CARBON
     455                 :     case NPNVsupportsCarbonBool: {
     456                 :       *((NPBool*)aValue) = false;
     457                 :       return NPERR_NO_ERROR;
     458                 :     }
     459                 : #endif
     460                 : 
     461                 :     case NPNVsupportsUpdatedCocoaTextInputBool: {
     462                 :       *static_cast<NPBool*>(aValue) = true;
     463                 :       return NPERR_NO_ERROR;
     464                 :     }
     465                 : 
     466                 : #ifndef NP_NO_QUICKDRAW
     467                 :     case NPNVsupportsQuickDrawBool: {
     468                 :         *((NPBool*)aValue) = false;
     469                 :         return NPERR_NO_ERROR;
     470                 :     }
     471                 : #endif /* NP_NO_QUICKDRAW */
     472                 : #endif /* XP_MACOSX */
     473                 : 
     474                 :     default:
     475               0 :         PR_LOG(gPluginLog, PR_LOG_WARNING,
     476                 :                ("In PluginInstanceChild::NPN_GetValue: Unhandled NPNVariable %i (%s)",
     477                 :                 (int) aVar, NPNVariableToString(aVar)));
     478               0 :         return NPERR_GENERIC_ERROR;
     479                 :     }
     480                 : 
     481                 : }
     482                 : 
     483                 : #ifdef MOZ_WIDGET_COCOA
     484                 : #define DEFAULT_REFRESH_MS 20 // CoreAnimation: 50 FPS
     485                 : 
     486                 : void
     487                 : CAUpdate(NPP npp, uint32_t timerID) {
     488                 :     static_cast<PluginInstanceChild*>(npp->ndata)->Invalidate();
     489                 : }
     490                 : 
     491                 : void
     492                 : PluginInstanceChild::Invalidate()
     493                 : {
     494                 :     NPRect windowRect = {0, 0, uint16_t(mWindow.height),
     495                 :         uint16_t(mWindow.width)};
     496                 : 
     497                 :     InvalidateRect(&windowRect);
     498                 : }
     499                 : #endif
     500                 : 
     501                 : NPError
     502               0 : PluginInstanceChild::NPN_SetValue(NPPVariable aVar, void* aValue)
     503                 : {
     504               0 :     PR_LOG(gPluginLog, PR_LOG_DEBUG, ("%s (aVar=%i, aValue=%p)",
     505                 :                                       FULLFUNCTION, (int) aVar, aValue));
     506                 : 
     507               0 :     AssertPluginThread();
     508                 : 
     509               0 :     switch (aVar) {
     510                 :     case NPPVpluginWindowBool: {
     511                 :         NPError rv;
     512               0 :         bool windowed = (NPBool) (intptr_t) aValue;
     513                 : 
     514               0 :         if (!CallNPN_SetValue_NPPVpluginWindow(windowed, &rv))
     515               0 :             return NPERR_GENERIC_ERROR;
     516                 : 
     517               0 :         return rv;
     518                 :     }
     519                 : 
     520                 :     case NPPVpluginTransparentBool: {
     521                 :         NPError rv;
     522               0 :         mIsTransparent = (!!aValue);
     523                 : 
     524               0 :         if (!CallNPN_SetValue_NPPVpluginTransparent(mIsTransparent, &rv))
     525               0 :             return NPERR_GENERIC_ERROR;
     526                 : 
     527               0 :         return rv;
     528                 :     }
     529                 : 
     530                 :     case NPPVpluginUsesDOMForCursorBool: {
     531               0 :         NPError rv = NPERR_GENERIC_ERROR;
     532               0 :         if (!CallNPN_SetValue_NPPVpluginUsesDOMForCursor((NPBool)(intptr_t)aValue, &rv)) {
     533               0 :             return NPERR_GENERIC_ERROR;
     534                 :         }
     535               0 :         return rv;
     536                 :     }
     537                 : 
     538                 :     case NPPVpluginDrawingModel: {
     539                 :         NPError rv;
     540               0 :         int drawingModel = (int16) (intptr_t) aValue;
     541                 : 
     542               0 :         if (!PluginModuleChild::current()->AsyncDrawingAllowed() &&
     543               0 :             IsDrawingModelAsync(drawingModel)) {
     544               0 :             return NPERR_GENERIC_ERROR;
     545                 :         }              
     546                 : 
     547                 :         CrossProcessMutexHandle handle;
     548               0 :         OptionalShmem optionalShmem;
     549               0 :         if (!CallNPN_SetValue_NPPVpluginDrawingModel(drawingModel, &optionalShmem, &handle, &rv))
     550               0 :             return NPERR_GENERIC_ERROR;
     551                 : 
     552               0 :         if (drawingModel == NPDrawingModelAsyncBitmapSurface) {
     553               0 :             if (optionalShmem.type() != OptionalShmem::TShmem) {
     554               0 :                 return NPERR_GENERIC_ERROR;
     555                 :             }
     556               0 :             mRemoteImageDataShmem = optionalShmem.get_Shmem();
     557               0 :             mRemoteImageData = mRemoteImageDataShmem.get<RemoteImageData>();
     558               0 :             mRemoteImageDataMutex = new CrossProcessMutex(handle);
     559                 :         }
     560               0 :         mDrawingModel = drawingModel;
     561                 : 
     562                 : #ifdef XP_MACOSX
     563                 :         if (drawingModel == NPDrawingModelCoreAnimation) {
     564                 :             mCARefreshTimer = ScheduleTimer(DEFAULT_REFRESH_MS, true, CAUpdate);
     565                 :         }
     566                 : #endif
     567                 : 
     568               0 :         PLUGIN_LOG_DEBUG(("  Plugin requested drawing model id  #%i\n",
     569                 :             mDrawingModel));
     570                 : 
     571               0 :         return rv;
     572                 :     }
     573                 : 
     574                 : #ifdef XP_MACOSX
     575                 :     case NPPVpluginEventModel: {
     576                 :         NPError rv;
     577                 :         int eventModel = (int16) (intptr_t) aValue;
     578                 : 
     579                 :         if (!CallNPN_SetValue_NPPVpluginEventModel(eventModel, &rv))
     580                 :             return NPERR_GENERIC_ERROR;
     581                 : #if defined(__i386__)
     582                 :         mEventModel = static_cast<NPEventModel>(eventModel);
     583                 : #endif
     584                 : 
     585                 :         PLUGIN_LOG_DEBUG(("  Plugin requested event model id # %i\n",
     586                 :             eventModel));
     587                 : 
     588                 :         return rv;
     589                 :     }
     590                 : #endif
     591                 : 
     592                 :     default:
     593               0 :         PR_LOG(gPluginLog, PR_LOG_WARNING,
     594                 :                ("In PluginInstanceChild::NPN_SetValue: Unhandled NPPVariable %i (%s)",
     595                 :                 (int) aVar, NPPVariableToString(aVar)));
     596               0 :         return NPERR_GENERIC_ERROR;
     597                 :     }
     598                 : }
     599                 : 
     600                 : bool
     601               0 : PluginInstanceChild::AnswerNPP_GetValue_NPPVpluginWantsAllNetworkStreams(
     602                 :     bool* wantsAllStreams, NPError* rv)
     603                 : {
     604               0 :     AssertPluginThread();
     605                 : 
     606               0 :     PRUint32 value = 0;
     607               0 :     if (!mPluginIface->getvalue) {
     608               0 :         *rv = NPERR_GENERIC_ERROR;
     609                 :     }
     610                 :     else {
     611                 :         *rv = mPluginIface->getvalue(GetNPP(), NPPVpluginWantsAllNetworkStreams,
     612               0 :                                      &value);
     613                 :     }
     614               0 :     *wantsAllStreams = value;
     615               0 :     return true;
     616                 : }
     617                 : 
     618                 : bool
     619               0 : PluginInstanceChild::AnswerNPP_GetValue_NPPVpluginNeedsXEmbed(
     620                 :     bool* needs, NPError* rv)
     621                 : {
     622               0 :     AssertPluginThread();
     623                 : 
     624                 : #ifdef MOZ_X11
     625                 :     // The documentation on the types for many variables in NP(N|P)_GetValue
     626                 :     // is vague.  Often boolean values are NPBool (1 byte), but
     627                 :     // https://developer.mozilla.org/en/XEmbed_Extension_for_Mozilla_Plugins
     628                 :     // treats NPPVpluginNeedsXEmbed as PRBool (int), and
     629                 :     // on x86/32-bit, flash stores to this using |movl 0x1,&needsXEmbed|.
     630                 :     // thus we can't use NPBool for needsXEmbed, or the three bytes above
     631                 :     // it on the stack would get clobbered. so protect with the larger bool.
     632               0 :     int needsXEmbed = 0;
     633               0 :     if (!mPluginIface->getvalue) {
     634               0 :         *rv = NPERR_GENERIC_ERROR;
     635                 :     }
     636                 :     else {
     637                 :         *rv = mPluginIface->getvalue(GetNPP(), NPPVpluginNeedsXEmbed,
     638               0 :                                      &needsXEmbed);
     639                 :     }
     640               0 :     *needs = needsXEmbed;
     641               0 :     return true;
     642                 : 
     643                 : #else
     644                 : 
     645                 :     NS_RUNTIMEABORT("shouldn't be called on non-X11 platforms");
     646                 :     return false;               // not reached
     647                 : 
     648                 : #endif
     649                 : }
     650                 : 
     651                 : bool
     652               0 : PluginInstanceChild::AnswerNPP_GetValue_NPPVpluginScriptableNPObject(
     653                 :                                           PPluginScriptableObjectChild** aValue,
     654                 :                                           NPError* aResult)
     655                 : {
     656               0 :     AssertPluginThread();
     657                 : 
     658               0 :     NPObject* object = nsnull;
     659               0 :     NPError result = NPERR_GENERIC_ERROR;
     660               0 :     if (mPluginIface->getvalue) {
     661                 :         result = mPluginIface->getvalue(GetNPP(), NPPVpluginScriptableNPObject,
     662               0 :                                         &object);
     663                 :     }
     664               0 :     if (result == NPERR_NO_ERROR && object) {
     665               0 :         PluginScriptableObjectChild* actor = GetActorForNPObject(object);
     666                 : 
     667                 :         // If we get an actor then it has retained. Otherwise we don't need it
     668                 :         // any longer.
     669               0 :         PluginModuleChild::sBrowserFuncs.releaseobject(object);
     670               0 :         if (actor) {
     671               0 :             *aValue = actor;
     672               0 :             *aResult = NPERR_NO_ERROR;
     673               0 :             return true;
     674                 :         }
     675                 : 
     676               0 :         NS_ERROR("Failed to get actor!");
     677               0 :         result = NPERR_GENERIC_ERROR;
     678                 :     }
     679                 :     else {
     680               0 :         result = NPERR_GENERIC_ERROR;
     681                 :     }
     682                 : 
     683               0 :     *aValue = nsnull;
     684               0 :     *aResult = result;
     685               0 :     return true;
     686                 : }
     687                 : 
     688                 : bool
     689               0 : PluginInstanceChild::AnswerNPP_GetValue_NPPVpluginNativeAccessibleAtkPlugId(
     690                 :                                           nsCString* aPlugId,
     691                 :                                           NPError* aResult)
     692                 : {
     693               0 :     AssertPluginThread();
     694                 : 
     695                 : #if MOZ_ACCESSIBILITY_ATK
     696                 : 
     697               0 :     char* plugId = NULL;
     698               0 :     NPError result = NPERR_GENERIC_ERROR;
     699               0 :     if (mPluginIface->getvalue) {
     700                 :         result = mPluginIface->getvalue(GetNPP(),
     701                 :                                         NPPVpluginNativeAccessibleAtkPlugId,
     702               0 :                                         &plugId);
     703                 :     }
     704                 : 
     705               0 :     *aPlugId = nsCString(plugId);
     706               0 :     *aResult = result;
     707               0 :     return true;
     708                 : 
     709                 : #else
     710                 : 
     711                 :     NS_RUNTIMEABORT("shouldn't be called on non-ATK platforms");
     712                 :     return false;
     713                 : 
     714                 : #endif
     715                 : }
     716                 : 
     717                 : bool
     718               0 : PluginInstanceChild::AnswerNPP_SetValue_NPNVprivateModeBool(const bool& value,
     719                 :                                                             NPError* result)
     720                 : {
     721               0 :     if (!mPluginIface->setvalue) {
     722               0 :         *result = NPERR_GENERIC_ERROR;
     723               0 :         return true;
     724                 :     }
     725                 : 
     726               0 :     NPBool v = value;
     727               0 :     *result = mPluginIface->setvalue(GetNPP(), NPNVprivateModeBool, &v);
     728               0 :     return true;
     729                 : }
     730                 : 
     731                 : bool
     732               0 : PluginInstanceChild::AnswerNPP_HandleEvent(const NPRemoteEvent& event,
     733                 :                                            int16_t* handled)
     734                 : {
     735               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
     736               0 :     AssertPluginThread();
     737                 : 
     738                 : #if defined(MOZ_X11) && defined(DEBUG)
     739               0 :     if (GraphicsExpose == event.event.type)
     740               0 :         PLUGIN_LOG_DEBUG(("  received drawable 0x%lx\n",
     741                 :                           event.event.xgraphicsexpose.drawable));
     742                 : #endif
     743                 : 
     744                 : #ifdef XP_MACOSX
     745                 :     // Mac OS X does not define an NPEvent structure. It defines more specific types.
     746                 :     NPCocoaEvent evcopy = event.event;
     747                 : 
     748                 :     // Make sure we reset mCurrentEvent in case of an exception
     749                 :     AutoRestore<const NPCocoaEvent*> savePreviousEvent(mCurrentEvent);
     750                 : 
     751                 :     // Track the current event for NPN_PopUpContextMenu.
     752                 :     mCurrentEvent = &event.event;
     753                 : #else
     754                 :     // Make a copy since we may modify values.
     755               0 :     NPEvent evcopy = event.event;
     756                 : #endif
     757                 : 
     758                 : #ifdef OS_WIN
     759                 :     // FIXME/bug 567645: temporarily drop the "dummy event" on the floor
     760                 :     if (WM_NULL == evcopy.event)
     761                 :         return true;
     762                 : 
     763                 :     // Painting for win32. SharedSurfacePaint handles everything.
     764                 :     if (mWindow.type == NPWindowTypeDrawable) {
     765                 :        if (evcopy.event == WM_PAINT) {
     766                 :           *handled = SharedSurfacePaint(evcopy);
     767                 :           return true;
     768                 :        }
     769                 :        else if (DoublePassRenderingEvent() == evcopy.event) {
     770                 :             // We'll render to mSharedSurfaceDib first, then render to a cached bitmap
     771                 :             // we store locally. The two passes are for alpha extraction, so the second
     772                 :             // pass must be to a flat white surface in order for things to work.
     773                 :             mAlphaExtract.doublePass = RENDER_BACK_ONE;
     774                 :             *handled = true;
     775                 :             return true;
     776                 :        }
     777                 :     }
     778                 :     *handled = WinlessHandleEvent(evcopy);
     779                 :     return true;
     780                 : #endif
     781                 : 
     782                 :     // XXX A previous call to mPluginIface->event might block, e.g. right click
     783                 :     // for context menu. Still, we might get here again, calling into the plugin
     784                 :     // a second time while it's in the previous call.
     785               0 :     if (!mPluginIface->event)
     786               0 :         *handled = false;
     787                 :     else
     788               0 :         *handled = mPluginIface->event(&mData, reinterpret_cast<void*>(&evcopy));
     789                 : 
     790                 : #ifdef XP_MACOSX
     791                 :     // Release any reference counted objects created in the child process.
     792                 :     if (evcopy.type == NPCocoaEventKeyDown ||
     793                 :         evcopy.type == NPCocoaEventKeyUp) {
     794                 :       ::CFRelease((CFStringRef)evcopy.data.key.characters);
     795                 :       ::CFRelease((CFStringRef)evcopy.data.key.charactersIgnoringModifiers);
     796                 :     }
     797                 :     else if (evcopy.type == NPCocoaEventTextInput) {
     798                 :       ::CFRelease((CFStringRef)evcopy.data.text.text);
     799                 :     }
     800                 : #endif
     801                 : 
     802                 : #ifdef MOZ_X11
     803               0 :     if (GraphicsExpose == event.event.type) {
     804                 :         // Make sure the X server completes the drawing before the parent
     805                 :         // draws on top and destroys the Drawable.
     806                 :         //
     807                 :         // XSync() waits for the X server to complete.  Really this child
     808                 :         // process does not need to wait; the parent is the process that needs
     809                 :         // to wait.  A possibly-slightly-better alternative would be to send
     810                 :         // an X event to the parent that the parent would wait for.
     811               0 :         XSync(mWsInfo.display, False);
     812                 :     }
     813                 : #endif
     814                 : 
     815               0 :     return true;
     816                 : }
     817                 : 
     818                 : #ifdef XP_MACOSX
     819                 : 
     820                 : bool
     821                 : PluginInstanceChild::AnswerNPP_HandleEvent_Shmem(const NPRemoteEvent& event,
     822                 :                                                  Shmem& mem,
     823                 :                                                  int16_t* handled,
     824                 :                                                  Shmem* rtnmem)
     825                 : {
     826                 :     PLUGIN_LOG_DEBUG_FUNCTION;
     827                 :     AssertPluginThread();
     828                 : 
     829                 :     PaintTracker pt;
     830                 : 
     831                 :     NPCocoaEvent evcopy = event.event;
     832                 : 
     833                 :     if (evcopy.type == NPCocoaEventDrawRect) {
     834                 :         if (!mShColorSpace) {
     835                 :             mShColorSpace = CreateSystemColorSpace();
     836                 :             if (!mShColorSpace) {
     837                 :                 PLUGIN_LOG_DEBUG(("Could not allocate ColorSpace."));
     838                 :                 *handled = false;
     839                 :                 *rtnmem = mem;
     840                 :                 return true;
     841                 :             } 
     842                 :         }
     843                 :         if (!mShContext) {
     844                 :             void* cgContextByte = mem.get<char>();
     845                 :             mShContext = ::CGBitmapContextCreate(cgContextByte, 
     846                 :                               mWindow.width, mWindow.height, 8, 
     847                 :                               mWindow.width * 4, mShColorSpace, 
     848                 :                               kCGImageAlphaPremultipliedFirst |
     849                 :                               kCGBitmapByteOrder32Host);
     850                 :     
     851                 :             if (!mShContext) {
     852                 :                 PLUGIN_LOG_DEBUG(("Could not allocate CGBitmapContext."));
     853                 :                 *handled = false;
     854                 :                 *rtnmem = mem;
     855                 :                 return true;
     856                 :             }
     857                 :         }
     858                 :         CGRect clearRect = ::CGRectMake(0, 0, mWindow.width, mWindow.height);
     859                 :         ::CGContextClearRect(mShContext, clearRect);
     860                 :         evcopy.data.draw.context = mShContext; 
     861                 :     } else {
     862                 :         PLUGIN_LOG_DEBUG(("Invalid event type for AnswerNNP_HandleEvent_Shmem."));
     863                 :         *handled = false;
     864                 :         *rtnmem = mem;
     865                 :         return true;
     866                 :     } 
     867                 : 
     868                 :     if (!mPluginIface->event) {
     869                 :         *handled = false;
     870                 :     } else {
     871                 :         ::CGContextSaveGState(evcopy.data.draw.context);
     872                 :         *handled = mPluginIface->event(&mData, reinterpret_cast<void*>(&evcopy));
     873                 :         ::CGContextRestoreGState(evcopy.data.draw.context);
     874                 :     }
     875                 : 
     876                 :     *rtnmem = mem;
     877                 :     return true;
     878                 : }
     879                 : 
     880                 : #else
     881                 : bool
     882               0 : PluginInstanceChild::AnswerNPP_HandleEvent_Shmem(const NPRemoteEvent& event,
     883                 :                                                  Shmem& mem,
     884                 :                                                  int16_t* handled,
     885                 :                                                  Shmem* rtnmem)
     886                 : {
     887               0 :     NS_RUNTIMEABORT("not reached.");
     888               0 :     *rtnmem = mem;
     889               0 :     return true;
     890                 : }
     891                 : #endif
     892                 : 
     893                 : #ifdef XP_MACOSX
     894                 : 
     895                 : void CallCGDraw(CGContextRef ref, void* aPluginInstance, nsIntRect aUpdateRect) {
     896                 :   PluginInstanceChild* pluginInstance = (PluginInstanceChild*)aPluginInstance;
     897                 : 
     898                 :   pluginInstance->CGDraw(ref, aUpdateRect);
     899                 : }
     900                 : 
     901                 : bool
     902                 : PluginInstanceChild::CGDraw(CGContextRef ref, nsIntRect aUpdateRect) {
     903                 : 
     904                 :   NPCocoaEvent drawEvent;
     905                 :   drawEvent.type = NPCocoaEventDrawRect;
     906                 :   drawEvent.version = 0;
     907                 :   drawEvent.data.draw.x = aUpdateRect.x;
     908                 :   drawEvent.data.draw.y = aUpdateRect.y;
     909                 :   drawEvent.data.draw.width = aUpdateRect.width;
     910                 :   drawEvent.data.draw.height = aUpdateRect.height;
     911                 :   drawEvent.data.draw.context = ref;
     912                 : 
     913                 :   NPRemoteEvent remoteDrawEvent = {drawEvent};
     914                 : 
     915                 :   int16_t handled;
     916                 :   AnswerNPP_HandleEvent(remoteDrawEvent, &handled);
     917                 :   return handled == true;
     918                 : }
     919                 : 
     920                 : bool
     921                 : PluginInstanceChild::AnswerNPP_HandleEvent_IOSurface(const NPRemoteEvent& event,
     922                 :                                                      const uint32_t &surfaceid,
     923                 :                                                      int16_t* handled)
     924                 : {
     925                 :     PLUGIN_LOG_DEBUG_FUNCTION;
     926                 :     AssertPluginThread();
     927                 : 
     928                 :     PaintTracker pt;
     929                 : 
     930                 :     NPCocoaEvent evcopy = event.event;
     931                 :     nsRefPtr<nsIOSurface> surf = nsIOSurface::LookupSurface(surfaceid);
     932                 :     if (!surf) {
     933                 :         NS_ERROR("Invalid IOSurface.");
     934                 :         *handled = false;
     935                 :         return false;
     936                 :     }
     937                 : 
     938                 :     if (evcopy.type == NPCocoaEventDrawRect) {
     939                 :         mCARenderer.AttachIOSurface(surf);
     940                 :         if (!mCARenderer.isInit()) {
     941                 :             void *caLayer = nsnull;
     942                 :             NPError result = mPluginIface->getvalue(GetNPP(), 
     943                 :                                      NPPVpluginCoreAnimationLayer,
     944                 :                                      &caLayer);
     945                 :             
     946                 :             if (result != NPERR_NO_ERROR || !caLayer) {
     947                 :                 PLUGIN_LOG_DEBUG(("Plugin requested CoreAnimation but did not "
     948                 :                                   "provide CALayer."));
     949                 :                 *handled = false;
     950                 :                 return false;
     951                 :             }
     952                 : 
     953                 :             mCARenderer.SetupRenderer(caLayer, mWindow.width, mWindow.height,
     954                 :                             GetQuirks() & PluginModuleChild::QUIRK_ALLOW_OFFLINE_RENDERER ?
     955                 :                             ALLOW_OFFLINE_RENDERER : DISALLOW_OFFLINE_RENDERER);
     956                 : 
     957                 :             // Flash needs to have the window set again after this step
     958                 :             if (mPluginIface->setwindow)
     959                 :                 (void) mPluginIface->setwindow(&mData, &mWindow);
     960                 :         }
     961                 :     } else {
     962                 :         PLUGIN_LOG_DEBUG(("Invalid event type for "
     963                 :                           "AnswerNNP_HandleEvent_IOSurface."));
     964                 :         *handled = false;
     965                 :         return false;
     966                 :     } 
     967                 : 
     968                 :     mCARenderer.Render(mWindow.width, mWindow.height, nsnull);
     969                 : 
     970                 :     return true;
     971                 : 
     972                 : }
     973                 : 
     974                 : #else
     975                 : bool
     976               0 : PluginInstanceChild::AnswerNPP_HandleEvent_IOSurface(const NPRemoteEvent& event,
     977                 :                                                      const uint32_t &surfaceid,
     978                 :                                                      int16_t* handled)
     979                 : {
     980               0 :     NS_RUNTIMEABORT("NPP_HandleEvent_IOSurface is a OSX-only message");
     981               0 :     return false;
     982                 : }
     983                 : #endif
     984                 : 
     985                 : bool
     986               0 : PluginInstanceChild::RecvWindowPosChanged(const NPRemoteEvent& event)
     987                 : {
     988               0 :     NS_ASSERTION(!mLayersRendering && !mPendingPluginCall,
     989                 :                  "Shouldn't be receiving WindowPosChanged with layer rendering");
     990                 : 
     991                 : #ifdef OS_WIN
     992                 :     int16_t dontcare;
     993                 :     return AnswerNPP_HandleEvent(event, &dontcare);
     994                 : #else
     995               0 :     NS_RUNTIMEABORT("WindowPosChanged is a windows-only message");
     996               0 :     return false;
     997                 : #endif
     998                 : }
     999                 : 
    1000                 : bool
    1001               0 : PluginInstanceChild::AnswerNPP_SetWindow(const NPRemoteWindow& aWindow)
    1002                 : {
    1003               0 :     PLUGIN_LOG_DEBUG(("%s (aWindow=<window: 0x%lx, x: %d, y: %d, width: %d, height: %d>)",
    1004                 :                       FULLFUNCTION,
    1005                 :                       aWindow.window,
    1006                 :                       aWindow.x, aWindow.y,
    1007                 :                       aWindow.width, aWindow.height));
    1008               0 :     NS_ASSERTION(!mLayersRendering && !mPendingPluginCall,
    1009                 :                  "Shouldn't be receiving NPP_SetWindow with layer rendering");
    1010               0 :     AssertPluginThread();
    1011                 : 
    1012                 : #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
    1013                 :     // The minimum info is sent over IPC to allow this
    1014                 :     // code to determine the rest.
    1015                 : 
    1016               0 :     mWindow.window = reinterpret_cast<void*>(aWindow.window);
    1017               0 :     mWindow.x = aWindow.x;
    1018               0 :     mWindow.y = aWindow.y;
    1019               0 :     mWindow.width = aWindow.width;
    1020               0 :     mWindow.height = aWindow.height;
    1021               0 :     mWindow.clipRect = aWindow.clipRect;
    1022               0 :     mWindow.type = aWindow.type;
    1023                 : 
    1024               0 :     mWsInfo.colormap = aWindow.colormap;
    1025               0 :     if (!XVisualIDToInfo(mWsInfo.display, aWindow.visualID,
    1026               0 :                          &mWsInfo.visual, &mWsInfo.depth))
    1027               0 :         return false;
    1028                 : 
    1029                 : #ifdef MOZ_WIDGET_GTK2
    1030               0 :     if (gtk_check_version(2,18,7) != NULL) { // older
    1031               0 :         if (aWindow.type == NPWindowTypeWindow) {
    1032               0 :             GdkWindow* socket_window = gdk_window_lookup(static_cast<GdkNativeWindow>(aWindow.window));
    1033               0 :             if (socket_window) {
    1034                 :                 // A GdkWindow for the socket already exists.  Need to
    1035                 :                 // workaround https://bugzilla.gnome.org/show_bug.cgi?id=607061
    1036                 :                 // See wrap_gtk_plug_embedded in PluginModuleChild.cpp.
    1037               0 :                 g_object_set_data(G_OBJECT(socket_window),
    1038                 :                                   "moz-existed-before-set-window",
    1039               0 :                                   GUINT_TO_POINTER(1));
    1040                 :             }
    1041                 :         }
    1042                 : 
    1043               0 :         if (aWindow.visualID != None
    1044               0 :             && gtk_check_version(2, 12, 10) != NULL) { // older
    1045                 :             // Workaround for a bug in Gtk+ (prior to 2.12.10) where deleting
    1046                 :             // a foreign GdkColormap will also free the XColormap.
    1047                 :             // http://git.gnome.org/browse/gtk+/log/gdk/x11/gdkcolor-x11.c?id=GTK_2_12_10
    1048               0 :             GdkVisual *gdkvisual = gdkx_visual_get(aWindow.visualID);
    1049                 :             GdkColormap *gdkcolor =
    1050               0 :                 gdk_x11_colormap_foreign_new(gdkvisual, aWindow.colormap);
    1051                 : 
    1052               0 :             if (g_object_get_data(G_OBJECT(gdkcolor), "moz-have-extra-ref")) {
    1053                 :                 // We already have a ref to keep the object alive.
    1054               0 :                 g_object_unref(gdkcolor);
    1055                 :             } else {
    1056                 :                 // leak and mark as already leaked
    1057               0 :                 g_object_set_data(G_OBJECT(gdkcolor),
    1058               0 :                                   "moz-have-extra-ref", GUINT_TO_POINTER(1));
    1059                 :             }
    1060                 :         }
    1061                 :     }
    1062                 : #endif
    1063                 : 
    1064               0 :     PLUGIN_LOG_DEBUG(
    1065                 :         ("[InstanceChild][%p] Answer_SetWindow w=<x=%d,y=%d, w=%d,h=%d>, clip=<l=%d,t=%d,r=%d,b=%d>",
    1066                 :          this, mWindow.x, mWindow.y, mWindow.width, mWindow.height,
    1067                 :          mWindow.clipRect.left, mWindow.clipRect.top, mWindow.clipRect.right, mWindow.clipRect.bottom));
    1068                 : 
    1069               0 :     if (mPluginIface->setwindow)
    1070               0 :         (void) mPluginIface->setwindow(&mData, &mWindow);
    1071                 : 
    1072                 : #elif defined(OS_WIN)
    1073                 :     switch (aWindow.type) {
    1074                 :       case NPWindowTypeWindow:
    1075                 :       {
    1076                 :           if ((GetQuirks() & PluginModuleChild::QUIRK_QUICKTIME_AVOID_SETWINDOW) &&
    1077                 :               aWindow.width == 0 &&
    1078                 :               aWindow.height == 0) {
    1079                 :             // Skip SetWindow call for hidden QuickTime plugins
    1080                 :             return true;
    1081                 :           }
    1082                 : 
    1083                 :           if (!CreatePluginWindow())
    1084                 :               return false;
    1085                 : 
    1086                 :           ReparentPluginWindow(reinterpret_cast<HWND>(aWindow.window));
    1087                 :           SizePluginWindow(aWindow.width, aWindow.height);
    1088                 : 
    1089                 :           mWindow.window = (void*)mPluginWindowHWND;
    1090                 :           mWindow.x = aWindow.x;
    1091                 :           mWindow.y = aWindow.y;
    1092                 :           mWindow.width = aWindow.width;
    1093                 :           mWindow.height = aWindow.height;
    1094                 :           mWindow.type = aWindow.type;
    1095                 : 
    1096                 :           if (mPluginIface->setwindow) {
    1097                 :               SetProp(mPluginWindowHWND, kPluginIgnoreSubclassProperty, (HANDLE)1);
    1098                 :               (void) mPluginIface->setwindow(&mData, &mWindow);
    1099                 :               WNDPROC wndProc = reinterpret_cast<WNDPROC>(
    1100                 :                   GetWindowLongPtr(mPluginWindowHWND, GWLP_WNDPROC));
    1101                 :               if (wndProc != PluginWindowProc) {
    1102                 :                   mPluginWndProc = reinterpret_cast<WNDPROC>(
    1103                 :                       SetWindowLongPtr(mPluginWindowHWND, GWLP_WNDPROC,
    1104                 :                                        reinterpret_cast<LONG_PTR>(PluginWindowProc)));
    1105                 :                   NS_ASSERTION(mPluginWndProc != PluginWindowProc, "WTF?");
    1106                 :               }
    1107                 :               RemoveProp(mPluginWindowHWND, kPluginIgnoreSubclassProperty);
    1108                 :               HookSetWindowLongPtr();
    1109                 :           }
    1110                 :       }
    1111                 :       break;
    1112                 : 
    1113                 :       case NPWindowTypeDrawable:
    1114                 :           mWindow.type = aWindow.type;
    1115                 :           if (GetQuirks() & PluginModuleChild::QUIRK_WINLESS_TRACKPOPUP_HOOK)
    1116                 :               CreateWinlessPopupSurrogate();
    1117                 :           if (GetQuirks() & PluginModuleChild::QUIRK_FLASH_THROTTLE_WMUSER_EVENTS)
    1118                 :               SetupFlashMsgThrottle();
    1119                 :           return SharedSurfaceSetWindow(aWindow);
    1120                 :       break;
    1121                 : 
    1122                 :       default:
    1123                 :           NS_NOTREACHED("Bad plugin window type.");
    1124                 :           return false;
    1125                 :       break;
    1126                 :     }
    1127                 : 
    1128                 : #elif defined(XP_MACOSX)
    1129                 : 
    1130                 :     mWindow.x = aWindow.x;
    1131                 :     mWindow.y = aWindow.y;
    1132                 :     mWindow.width = aWindow.width;
    1133                 :     mWindow.height = aWindow.height;
    1134                 :     mWindow.clipRect = aWindow.clipRect;
    1135                 :     mWindow.type = aWindow.type;
    1136                 : 
    1137                 :     if (mShContext) {
    1138                 :         // Release the shared context so that it is reallocated
    1139                 :         // with the new size. 
    1140                 :         ::CGContextRelease(mShContext);
    1141                 :         mShContext = nsnull;
    1142                 :     }
    1143                 : 
    1144                 :     if (mPluginIface->setwindow)
    1145                 :         (void) mPluginIface->setwindow(&mData, &mWindow);
    1146                 : 
    1147                 : #elif defined(ANDROID)
    1148                 : #  warning Need Android impl
    1149                 : #elif defined(MOZ_WIDGET_QT)
    1150                 : #  warning Need QT-nonX impl
    1151                 : #else
    1152                 : #  error Implement me for your OS
    1153                 : #endif
    1154                 : 
    1155               0 :     return true;
    1156                 : }
    1157                 : 
    1158                 : bool
    1159               0 : PluginInstanceChild::Initialize()
    1160                 : {
    1161               0 :     return true;
    1162                 : }
    1163                 : 
    1164                 : #if defined(OS_WIN)
    1165                 : 
    1166                 : static const TCHAR kWindowClassName[] = TEXT("GeckoPluginWindow");
    1167                 : static const TCHAR kPluginInstanceChildProperty[] = TEXT("PluginInstanceChildProperty");
    1168                 : static const TCHAR kFlashThrottleProperty[] = TEXT("MozillaFlashThrottleProperty");
    1169                 : 
    1170                 : // static
    1171                 : bool
    1172                 : PluginInstanceChild::RegisterWindowClass()
    1173                 : {
    1174                 :     static bool alreadyRegistered = false;
    1175                 :     if (alreadyRegistered)
    1176                 :         return true;
    1177                 : 
    1178                 :     alreadyRegistered = true;
    1179                 : 
    1180                 :     WNDCLASSEX wcex;
    1181                 :     wcex.cbSize         = sizeof(WNDCLASSEX);
    1182                 :     wcex.style          = CS_DBLCLKS;
    1183                 :     wcex.lpfnWndProc    = DummyWindowProc;
    1184                 :     wcex.cbClsExtra     = 0;
    1185                 :     wcex.cbWndExtra     = 0;
    1186                 :     wcex.hInstance      = GetModuleHandle(NULL);
    1187                 :     wcex.hIcon          = 0;
    1188                 :     wcex.hCursor        = 0;
    1189                 :     wcex.hbrBackground  = reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1);
    1190                 :     wcex.lpszMenuName   = 0;
    1191                 :     wcex.lpszClassName  = kWindowClassName;
    1192                 :     wcex.hIconSm        = 0;
    1193                 : 
    1194                 :     return RegisterClassEx(&wcex) ? true : false;
    1195                 : }
    1196                 : 
    1197                 : bool
    1198                 : PluginInstanceChild::CreatePluginWindow()
    1199                 : {
    1200                 :     // already initialized
    1201                 :     if (mPluginWindowHWND)
    1202                 :         return true;
    1203                 :         
    1204                 :     if (!RegisterWindowClass())
    1205                 :         return false;
    1206                 : 
    1207                 :     mPluginWindowHWND =
    1208                 :         CreateWindowEx(WS_EX_LEFT | WS_EX_LTRREADING |
    1209                 :                        WS_EX_NOPARENTNOTIFY | // XXXbent Get rid of this!
    1210                 :                        WS_EX_RIGHTSCROLLBAR,
    1211                 :                        kWindowClassName, 0,
    1212                 :                        WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0,
    1213                 :                        0, 0, NULL, 0, GetModuleHandle(NULL), 0);
    1214                 :     if (!mPluginWindowHWND)
    1215                 :         return false;
    1216                 :     if (!SetProp(mPluginWindowHWND, kPluginInstanceChildProperty, this))
    1217                 :         return false;
    1218                 : 
    1219                 :     // Apparently some plugins require an ASCII WndProc.
    1220                 :     SetWindowLongPtrA(mPluginWindowHWND, GWLP_WNDPROC,
    1221                 :                       reinterpret_cast<LONG_PTR>(DefWindowProcA));
    1222                 : 
    1223                 :     return true;
    1224                 : }
    1225                 : 
    1226                 : void
    1227                 : PluginInstanceChild::DestroyPluginWindow()
    1228                 : {
    1229                 :     if (mPluginWindowHWND) {
    1230                 :         // Unsubclass the window.
    1231                 :         WNDPROC wndProc = reinterpret_cast<WNDPROC>(
    1232                 :             GetWindowLongPtr(mPluginWindowHWND, GWLP_WNDPROC));
    1233                 :         // Removed prior to SetWindowLongPtr, see HookSetWindowLongPtr.
    1234                 :         RemoveProp(mPluginWindowHWND, kPluginInstanceChildProperty);
    1235                 :         if (wndProc == PluginWindowProc) {
    1236                 :             NS_ASSERTION(mPluginWndProc, "Should have old proc here!");
    1237                 :             SetWindowLongPtr(mPluginWindowHWND, GWLP_WNDPROC,
    1238                 :                              reinterpret_cast<LONG_PTR>(mPluginWndProc));
    1239                 :             mPluginWndProc = 0;
    1240                 :         }
    1241                 :         DestroyWindow(mPluginWindowHWND);
    1242                 :         mPluginWindowHWND = 0;
    1243                 :     }
    1244                 : }
    1245                 : 
    1246                 : void
    1247                 : PluginInstanceChild::ReparentPluginWindow(HWND hWndParent)
    1248                 : {
    1249                 :     if (hWndParent != mPluginParentHWND && IsWindow(hWndParent)) {
    1250                 :         // Fix the child window's style to be a child window.
    1251                 :         LONG_PTR style = GetWindowLongPtr(mPluginWindowHWND, GWL_STYLE);
    1252                 :         style |= WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
    1253                 :         style &= ~WS_POPUP;
    1254                 :         SetWindowLongPtr(mPluginWindowHWND, GWL_STYLE, style);
    1255                 : 
    1256                 :         // Do the reparenting.
    1257                 :         SetParent(mPluginWindowHWND, hWndParent);
    1258                 : 
    1259                 :         // Make sure we're visible.
    1260                 :         ShowWindow(mPluginWindowHWND, SW_SHOWNA);
    1261                 :     }
    1262                 :     mPluginParentHWND = hWndParent;
    1263                 : }
    1264                 : 
    1265                 : void
    1266                 : PluginInstanceChild::SizePluginWindow(int width,
    1267                 :                                       int height)
    1268                 : {
    1269                 :     if (mPluginWindowHWND) {
    1270                 :         mPluginSize.x = width;
    1271                 :         mPluginSize.y = height;
    1272                 :         SetWindowPos(mPluginWindowHWND, NULL, 0, 0, width, height,
    1273                 :                      SWP_NOZORDER | SWP_NOREPOSITION);
    1274                 :     }
    1275                 : }
    1276                 : 
    1277                 : // See chromium's webplugin_delegate_impl.cc for explanation of this function.
    1278                 : // static
    1279                 : LRESULT CALLBACK
    1280                 : PluginInstanceChild::DummyWindowProc(HWND hWnd,
    1281                 :                                      UINT message,
    1282                 :                                      WPARAM wParam,
    1283                 :                                      LPARAM lParam)
    1284                 : {
    1285                 :     return CallWindowProc(DefWindowProc, hWnd, message, wParam, lParam);
    1286                 : }
    1287                 : 
    1288                 : // static
    1289                 : LRESULT CALLBACK
    1290                 : PluginInstanceChild::PluginWindowProc(HWND hWnd,
    1291                 :                                       UINT message,
    1292                 :                                       WPARAM wParam,
    1293                 :                                       LPARAM lParam)
    1294                 : {
    1295                 :   return mozilla::CallWindowProcCrashProtected(PluginWindowProcInternal, hWnd, message, wParam, lParam);
    1296                 : }
    1297                 : 
    1298                 : // static
    1299                 : LRESULT CALLBACK
    1300                 : PluginInstanceChild::PluginWindowProcInternal(HWND hWnd,
    1301                 :                                               UINT message,
    1302                 :                                               WPARAM wParam,
    1303                 :                                               LPARAM lParam)
    1304                 : {
    1305                 :     NS_ASSERTION(!mozilla::ipc::SyncChannel::IsPumpingMessages(),
    1306                 :                  "Failed to prevent a nonqueued message from running!");
    1307                 :     PluginInstanceChild* self = reinterpret_cast<PluginInstanceChild*>(
    1308                 :         GetProp(hWnd, kPluginInstanceChildProperty));
    1309                 :     if (!self) {
    1310                 :         NS_NOTREACHED("Badness!");
    1311                 :         return 0;
    1312                 :     }
    1313                 : 
    1314                 :     NS_ASSERTION(self->mPluginWindowHWND == hWnd, "Wrong window!");
    1315                 :     NS_ASSERTION(self->mPluginWndProc != PluginWindowProc, "Self-referential windowproc. Infinite recursion will happen soon.");
    1316                 : 
    1317                 :     // Adobe's shockwave positions the plugin window relative to the browser
    1318                 :     // frame when it initializes. With oopp disabled, this wouldn't have an
    1319                 :     // effect. With oopp, GeckoPluginWindow is a child of the parent plugin
    1320                 :     // window, so the move offsets the child within the parent. Generally
    1321                 :     // we don't want plugins moving or sizing our window, so we prevent these
    1322                 :     // changes here.
    1323                 :     if (message == WM_WINDOWPOSCHANGING) {
    1324                 :       WINDOWPOS* pos = reinterpret_cast<WINDOWPOS*>(lParam);
    1325                 :       if (pos && (!(pos->flags & SWP_NOMOVE) || !(pos->flags & SWP_NOSIZE))) {
    1326                 :         pos->x = pos->y = 0;
    1327                 :         pos->cx = self->mPluginSize.x;
    1328                 :         pos->cy = self->mPluginSize.y;
    1329                 :         LRESULT res = CallWindowProc(self->mPluginWndProc, hWnd, message, wParam,
    1330                 :                                      lParam);
    1331                 :         pos->x = pos->y = 0;
    1332                 :         pos->cx = self->mPluginSize.x;
    1333                 :         pos->cy = self->mPluginSize.y;
    1334                 :         return res;
    1335                 :       }
    1336                 :     }
    1337                 : 
    1338                 :     // The plugin received keyboard focus, let the parent know so the dom is up to date.
    1339                 :     if (message == WM_MOUSEACTIVATE)
    1340                 :       self->CallPluginFocusChange(true);
    1341                 : 
    1342                 :     // Prevent lockups due to plugins making rpc calls when the parent
    1343                 :     // is making a synchronous SendMessage call to the child window. Add
    1344                 :     // more messages as needed.
    1345                 :     if ((InSendMessageEx(NULL)&(ISMEX_REPLIED|ISMEX_SEND)) == ISMEX_SEND) {
    1346                 :         switch(message) {
    1347                 :             case WM_KILLFOCUS:
    1348                 :             ReplyMessage(0);
    1349                 :             break;
    1350                 :         }
    1351                 :     }
    1352                 : 
    1353                 :     if (message == WM_KILLFOCUS)
    1354                 :       self->CallPluginFocusChange(false);
    1355                 : 
    1356                 :     if (message == WM_USER+1 &&
    1357                 :         (self->GetQuirks() & PluginModuleChild::QUIRK_FLASH_THROTTLE_WMUSER_EVENTS)) {
    1358                 :         self->FlashThrottleMessage(hWnd, message, wParam, lParam, true);
    1359                 :         return 0;
    1360                 :     }
    1361                 : 
    1362                 :     NS_ASSERTION(self->mPluginWndProc != PluginWindowProc,
    1363                 :       "Self-referential windowproc happened inside our hook proc. "
    1364                 :       "Infinite recursion will happen soon.");
    1365                 : 
    1366                 :     LRESULT res = CallWindowProc(self->mPluginWndProc, hWnd, message, wParam,
    1367                 :                                  lParam);
    1368                 : 
    1369                 :     // Make sure capture is released by the child on mouse events. Fixes a
    1370                 :     // problem with flash full screen mode mouse input. Appears to be
    1371                 :     // caused by a bug in flash, since we are not setting the capture
    1372                 :     // on the window.
    1373                 :     if (message == WM_LBUTTONDOWN &&
    1374                 :         self->GetQuirks() & PluginModuleChild::QUIRK_FLASH_FIXUP_MOUSE_CAPTURE) {
    1375                 :       PRUnichar szClass[26];
    1376                 :       HWND hwnd = GetForegroundWindow();
    1377                 :       if (hwnd && GetClassNameW(hwnd, szClass,
    1378                 :                                 sizeof(szClass)/sizeof(PRUnichar)) &&
    1379                 :           !wcscmp(szClass, kFlashFullscreenClass)) {
    1380                 :         ReleaseCapture();
    1381                 :         SetFocus(hwnd);
    1382                 :       }
    1383                 :     }
    1384                 : 
    1385                 :     if (message == WM_CLOSE)
    1386                 :         self->DestroyPluginWindow();
    1387                 : 
    1388                 :     if (message == WM_NCDESTROY)
    1389                 :         RemoveProp(hWnd, kPluginInstanceChildProperty);
    1390                 : 
    1391                 :     return res;
    1392                 : }
    1393                 : 
    1394                 : /* set window long ptr hook for flash */
    1395                 : 
    1396                 : /*
    1397                 :  * Flash will reset the subclass of our widget at various times.
    1398                 :  * (Notably when entering and exiting full screen mode.) This
    1399                 :  * occurs independent of the main plugin window event procedure.
    1400                 :  * We trap these subclass calls to prevent our subclass hook from
    1401                 :  * getting dropped.
    1402                 :  * Note, ascii versions can be nixed once flash versions < 10.1
    1403                 :  * are considered obsolete.
    1404                 :  */
    1405                 :  
    1406                 : #ifdef _WIN64
    1407                 : typedef LONG_PTR
    1408                 :   (WINAPI *User32SetWindowLongPtrA)(HWND hWnd,
    1409                 :                                     int nIndex,
    1410                 :                                     LONG_PTR dwNewLong);
    1411                 : typedef LONG_PTR
    1412                 :   (WINAPI *User32SetWindowLongPtrW)(HWND hWnd,
    1413                 :                                     int nIndex,
    1414                 :                                     LONG_PTR dwNewLong);
    1415                 : static User32SetWindowLongPtrA sUser32SetWindowLongAHookStub = NULL;
    1416                 : static User32SetWindowLongPtrW sUser32SetWindowLongWHookStub = NULL;
    1417                 : #else
    1418                 : typedef LONG
    1419                 : (WINAPI *User32SetWindowLongA)(HWND hWnd,
    1420                 :                                int nIndex,
    1421                 :                                LONG dwNewLong);
    1422                 : typedef LONG
    1423                 : (WINAPI *User32SetWindowLongW)(HWND hWnd,
    1424                 :                                int nIndex,
    1425                 :                                LONG dwNewLong);
    1426                 : static User32SetWindowLongA sUser32SetWindowLongAHookStub = NULL;
    1427                 : static User32SetWindowLongW sUser32SetWindowLongWHookStub = NULL;
    1428                 : #endif
    1429                 : 
    1430                 : extern LRESULT CALLBACK
    1431                 : NeuteredWindowProc(HWND hwnd,
    1432                 :                    UINT uMsg,
    1433                 :                    WPARAM wParam,
    1434                 :                    LPARAM lParam);
    1435                 : 
    1436                 : const wchar_t kOldWndProcProp[] = L"MozillaIPCOldWndProc";
    1437                 : 
    1438                 : // static
    1439                 : bool
    1440                 : PluginInstanceChild::SetWindowLongHookCheck(HWND hWnd,
    1441                 :                                             int nIndex,
    1442                 :                                             LONG_PTR newLong)
    1443                 : {
    1444                 :       // Let this go through if it's not a subclass
    1445                 :   if (nIndex != GWLP_WNDPROC ||
    1446                 :       // if it's not a subclassed plugin window
    1447                 :       !GetProp(hWnd, kPluginInstanceChildProperty) ||
    1448                 :       // if we're not disabled
    1449                 :       GetProp(hWnd, kPluginIgnoreSubclassProperty) ||
    1450                 :       // if the subclass is set to a known procedure
    1451                 :       newLong == reinterpret_cast<LONG_PTR>(PluginWindowProc) ||
    1452                 :       newLong == reinterpret_cast<LONG_PTR>(NeuteredWindowProc) ||
    1453                 :       newLong == reinterpret_cast<LONG_PTR>(DefWindowProcA) ||
    1454                 :       newLong == reinterpret_cast<LONG_PTR>(DefWindowProcW) ||
    1455                 :       // if the subclass is a WindowsMessageLoop subclass restore
    1456                 :       GetProp(hWnd, kOldWndProcProp))
    1457                 :       return true;
    1458                 :   // prevent the subclass
    1459                 :   return false;
    1460                 : }
    1461                 : 
    1462                 : #ifdef _WIN64
    1463                 : LONG_PTR WINAPI
    1464                 : PluginInstanceChild::SetWindowLongPtrAHook(HWND hWnd,
    1465                 :                                            int nIndex,
    1466                 :                                            LONG_PTR newLong)
    1467                 : #else
    1468                 : LONG WINAPI
    1469                 : PluginInstanceChild::SetWindowLongAHook(HWND hWnd,
    1470                 :                                         int nIndex,
    1471                 :                                         LONG newLong)
    1472                 : #endif
    1473                 : {
    1474                 :     if (SetWindowLongHookCheck(hWnd, nIndex, newLong))
    1475                 :         return sUser32SetWindowLongAHookStub(hWnd, nIndex, newLong);
    1476                 : 
    1477                 :     // Set flash's new subclass to get the result. 
    1478                 :     LONG_PTR proc = sUser32SetWindowLongAHookStub(hWnd, nIndex, newLong);
    1479                 : 
    1480                 :     // We already checked this in SetWindowLongHookCheck
    1481                 :     PluginInstanceChild* self = reinterpret_cast<PluginInstanceChild*>(
    1482                 :         GetProp(hWnd, kPluginInstanceChildProperty));
    1483                 : 
    1484                 :     // Hook our subclass back up, just like we do on setwindow.   
    1485                 :     WNDPROC currentProc =
    1486                 :         reinterpret_cast<WNDPROC>(GetWindowLongPtr(hWnd, GWLP_WNDPROC));
    1487                 :     if (currentProc != PluginWindowProc) {
    1488                 :         self->mPluginWndProc =
    1489                 :             reinterpret_cast<WNDPROC>(sUser32SetWindowLongWHookStub(hWnd, nIndex,
    1490                 :                 reinterpret_cast<LONG_PTR>(PluginWindowProc)));
    1491                 :         NS_ASSERTION(self->mPluginWndProc != PluginWindowProc, "Infinite recursion coming up!");
    1492                 :     }
    1493                 :     return proc;
    1494                 : }
    1495                 : 
    1496                 : #ifdef _WIN64
    1497                 : LONG_PTR WINAPI
    1498                 : PluginInstanceChild::SetWindowLongPtrWHook(HWND hWnd,
    1499                 :                                            int nIndex,
    1500                 :                                            LONG_PTR newLong)
    1501                 : #else
    1502                 : LONG WINAPI
    1503                 : PluginInstanceChild::SetWindowLongWHook(HWND hWnd,
    1504                 :                                         int nIndex,
    1505                 :                                         LONG newLong)
    1506                 : #endif
    1507                 : {
    1508                 :     if (SetWindowLongHookCheck(hWnd, nIndex, newLong))
    1509                 :         return sUser32SetWindowLongWHookStub(hWnd, nIndex, newLong);
    1510                 : 
    1511                 :     // Set flash's new subclass to get the result. 
    1512                 :     LONG_PTR proc = sUser32SetWindowLongWHookStub(hWnd, nIndex, newLong);
    1513                 : 
    1514                 :     // We already checked this in SetWindowLongHookCheck
    1515                 :     PluginInstanceChild* self = reinterpret_cast<PluginInstanceChild*>(
    1516                 :         GetProp(hWnd, kPluginInstanceChildProperty));
    1517                 : 
    1518                 :     // Hook our subclass back up, just like we do on setwindow.   
    1519                 :     WNDPROC currentProc =
    1520                 :         reinterpret_cast<WNDPROC>(GetWindowLongPtr(hWnd, GWLP_WNDPROC));
    1521                 :     if (currentProc != PluginWindowProc) {
    1522                 :         self->mPluginWndProc =
    1523                 :             reinterpret_cast<WNDPROC>(sUser32SetWindowLongWHookStub(hWnd, nIndex,
    1524                 :                 reinterpret_cast<LONG_PTR>(PluginWindowProc)));
    1525                 :         NS_ASSERTION(self->mPluginWndProc != PluginWindowProc, "Infinite recursion coming up!");
    1526                 :     }
    1527                 :     return proc;
    1528                 : }
    1529                 : 
    1530                 : void
    1531                 : PluginInstanceChild::HookSetWindowLongPtr()
    1532                 : {
    1533                 :     if (!(GetQuirks() & PluginModuleChild::QUIRK_FLASH_HOOK_SETLONGPTR))
    1534                 :         return;
    1535                 : 
    1536                 :     sUser32Intercept.Init("user32.dll");
    1537                 : #ifdef _WIN64
    1538                 :     if (!sUser32SetWindowLongAHookStub)
    1539                 :         sUser32Intercept.AddHook("SetWindowLongPtrA", reinterpret_cast<intptr_t>(SetWindowLongPtrAHook),
    1540                 :                                  (void**) &sUser32SetWindowLongAHookStub);
    1541                 :     if (!sUser32SetWindowLongWHookStub)
    1542                 :         sUser32Intercept.AddHook("SetWindowLongPtrW", reinterpret_cast<intptr_t>(SetWindowLongPtrWHook),
    1543                 :                                  (void**) &sUser32SetWindowLongWHookStub);
    1544                 : #else
    1545                 :     if (!sUser32SetWindowLongAHookStub)
    1546                 :         sUser32Intercept.AddHook("SetWindowLongA", reinterpret_cast<intptr_t>(SetWindowLongAHook),
    1547                 :                                  (void**) &sUser32SetWindowLongAHookStub);
    1548                 :     if (!sUser32SetWindowLongWHookStub)
    1549                 :         sUser32Intercept.AddHook("SetWindowLongW", reinterpret_cast<intptr_t>(SetWindowLongWHook),
    1550                 :                                  (void**) &sUser32SetWindowLongWHookStub);
    1551                 : #endif
    1552                 : }
    1553                 : 
    1554                 : /* windowless track popup menu helpers */
    1555                 : 
    1556                 : BOOL
    1557                 : WINAPI
    1558                 : PluginInstanceChild::TrackPopupHookProc(HMENU hMenu,
    1559                 :                                         UINT uFlags,
    1560                 :                                         int x,
    1561                 :                                         int y,
    1562                 :                                         int nReserved,
    1563                 :                                         HWND hWnd,
    1564                 :                                         CONST RECT *prcRect)
    1565                 : {
    1566                 :   if (!sUser32TrackPopupMenuStub) {
    1567                 :       NS_ERROR("TrackPopupMenu stub isn't set! Badness!");
    1568                 :       return 0;
    1569                 :   }
    1570                 : 
    1571                 :   // Only change the parent when we know this is a context on the plugin
    1572                 :   // surface within the browser. Prevents resetting the parent on child ui
    1573                 :   // displayed by plugins that have working parent-child relationships.
    1574                 :   PRUnichar szClass[21];
    1575                 :   bool haveClass = GetClassNameW(hWnd, szClass, ArrayLength(szClass));
    1576                 :   if (!haveClass || 
    1577                 :       (wcscmp(szClass, L"MozillaWindowClass") &&
    1578                 :        wcscmp(szClass, L"SWFlash_Placeholder"))) {
    1579                 :       // Unrecognized parent
    1580                 :       return sUser32TrackPopupMenuStub(hMenu, uFlags, x, y, nReserved,
    1581                 :                                        hWnd, prcRect);
    1582                 :   }
    1583                 : 
    1584                 :   // Called on an unexpected event, warn.
    1585                 :   if (!sWinlessPopupSurrogateHWND) {
    1586                 :       NS_WARNING(
    1587                 :           "Untraced TrackPopupHookProc call! Menu might not work right!");
    1588                 :       return sUser32TrackPopupMenuStub(hMenu, uFlags, x, y, nReserved,
    1589                 :                                        hWnd, prcRect);
    1590                 :   }
    1591                 : 
    1592                 :   HWND surrogateHwnd = sWinlessPopupSurrogateHWND;
    1593                 :   sWinlessPopupSurrogateHWND = NULL;
    1594                 : 
    1595                 :   // Popups that don't use TPM_RETURNCMD expect a final command message
    1596                 :   // when an item is selected and the context closes. Since we replace
    1597                 :   // the parent, we need to forward this back to the real parent so it
    1598                 :   // can act on the menu item selected.
    1599                 :   bool isRetCmdCall = (uFlags & TPM_RETURNCMD);
    1600                 : 
    1601                 :   DWORD res = sUser32TrackPopupMenuStub(hMenu, uFlags|TPM_RETURNCMD, x, y,
    1602                 :                                         nReserved, surrogateHwnd, prcRect);
    1603                 : 
    1604                 :   if (!isRetCmdCall && res) {
    1605                 :       SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(res, 0), 0);
    1606                 :   }
    1607                 : 
    1608                 :   return res;
    1609                 : }
    1610                 : 
    1611                 : void
    1612                 : PluginInstanceChild::InitPopupMenuHook()
    1613                 : {
    1614                 :     if (!(GetQuirks() & PluginModuleChild::QUIRK_WINLESS_TRACKPOPUP_HOOK) ||
    1615                 :         sUser32TrackPopupMenuStub)
    1616                 :         return;
    1617                 : 
    1618                 :     // Note, once WindowsDllInterceptor is initialized for a module,
    1619                 :     // it remains initialized for that particular module for it's
    1620                 :     // lifetime. Additional instances are needed if other modules need
    1621                 :     // to be hooked.
    1622                 :     if (!sUser32TrackPopupMenuStub) {
    1623                 :         sUser32Intercept.Init("user32.dll");
    1624                 :         sUser32Intercept.AddHook("TrackPopupMenu", reinterpret_cast<intptr_t>(TrackPopupHookProc),
    1625                 :                                  (void**) &sUser32TrackPopupMenuStub);
    1626                 :     }
    1627                 : }
    1628                 : 
    1629                 : void
    1630                 : PluginInstanceChild::CreateWinlessPopupSurrogate()
    1631                 : {
    1632                 :     // already initialized
    1633                 :     if (mWinlessPopupSurrogateHWND)
    1634                 :         return;
    1635                 : 
    1636                 :     HWND hwnd = NULL;
    1637                 :     NPError result;
    1638                 :     if (!CallNPN_GetValue_NPNVnetscapeWindow(&hwnd, &result)) {
    1639                 :         NS_ERROR("CallNPN_GetValue_NPNVnetscapeWindow failed.");
    1640                 :         return;
    1641                 :     }
    1642                 : 
    1643                 :     mWinlessPopupSurrogateHWND =
    1644                 :         CreateWindowEx(WS_EX_NOPARENTNOTIFY, L"Static", NULL, WS_CHILD, 0, 0,
    1645                 :                        0, 0, hwnd, 0, GetModuleHandle(NULL), 0);
    1646                 :     if (!mWinlessPopupSurrogateHWND) {
    1647                 :         NS_ERROR("CreateWindowEx failed for winless placeholder!");
    1648                 :         return;
    1649                 :     }
    1650                 :     return;
    1651                 : }
    1652                 : 
    1653                 : void
    1654                 : PluginInstanceChild::DestroyWinlessPopupSurrogate()
    1655                 : {
    1656                 :     if (mWinlessPopupSurrogateHWND)
    1657                 :         DestroyWindow(mWinlessPopupSurrogateHWND);
    1658                 :     mWinlessPopupSurrogateHWND = NULL;
    1659                 : }
    1660                 : 
    1661                 : int16_t
    1662                 : PluginInstanceChild::WinlessHandleEvent(NPEvent& event)
    1663                 : {
    1664                 :     if (!mPluginIface->event)
    1665                 :         return false;
    1666                 : 
    1667                 :     // Events that might generate nested event dispatch loops need
    1668                 :     // special handling during delivery.
    1669                 :     int16_t handled;
    1670                 :     
    1671                 :     HWND focusHwnd = NULL;
    1672                 : 
    1673                 :     // TrackPopupMenu will fail if the parent window is not associated with
    1674                 :     // our ui thread. So we hook TrackPopupMenu so we can hand in a surrogate
    1675                 :     // parent created in the child process.
    1676                 :     if ((GetQuirks() & PluginModuleChild::QUIRK_WINLESS_TRACKPOPUP_HOOK) && // XXX turn on by default?
    1677                 :           (event.event == WM_RBUTTONDOWN || // flash
    1678                 :            event.event == WM_RBUTTONUP)) {  // silverlight
    1679                 :       sWinlessPopupSurrogateHWND = mWinlessPopupSurrogateHWND;
    1680                 :       
    1681                 :       // A little trick scrounged from chromium's code - set the focus
    1682                 :       // to our surrogate parent so keyboard nav events go to the menu. 
    1683                 :       focusHwnd = SetFocus(mWinlessPopupSurrogateHWND);
    1684                 :     }
    1685                 : 
    1686                 :     MessageLoop* loop = MessageLoop::current();
    1687                 :     AutoRestore<bool> modalLoop(loop->os_modal_loop());
    1688                 : 
    1689                 :     handled = mPluginIface->event(&mData, reinterpret_cast<void*>(&event));
    1690                 : 
    1691                 :     sWinlessPopupSurrogateHWND = NULL;
    1692                 : 
    1693                 :     if (IsWindow(focusHwnd)) {
    1694                 :       SetFocus(focusHwnd);
    1695                 :     }
    1696                 : 
    1697                 :     return handled;
    1698                 : }
    1699                 : 
    1700                 : /* windowless drawing helpers */
    1701                 : 
    1702                 : bool
    1703                 : PluginInstanceChild::SharedSurfaceSetWindow(const NPRemoteWindow& aWindow)
    1704                 : {
    1705                 :     // If the surfaceHandle is empty, parent is telling us we can reuse our cached
    1706                 :     // memory surface and hdc. Otherwise, we need to reset, usually due to a
    1707                 :     // expanding plugin port size.
    1708                 :     if (!aWindow.surfaceHandle) {
    1709                 :         if (!mSharedSurfaceDib.IsValid()) {
    1710                 :             return false;
    1711                 :         }
    1712                 :     }
    1713                 :     else {
    1714                 :         // Attach to the new shared surface parent handed us.
    1715                 :         if (NS_FAILED(mSharedSurfaceDib.Attach((SharedDIB::Handle)aWindow.surfaceHandle,
    1716                 :                                                aWindow.width, aWindow.height, false)))
    1717                 :           return false;
    1718                 :         // Free any alpha extraction resources if needed. This will be reset
    1719                 :         // the next time it's used.
    1720                 :         AlphaExtractCacheRelease();
    1721                 :     }
    1722                 :       
    1723                 :     // NPRemoteWindow's origin is the origin of our shared dib.
    1724                 :     mWindow.x      = aWindow.x;
    1725                 :     mWindow.y      = aWindow.y;
    1726                 :     mWindow.width  = aWindow.width;
    1727                 :     mWindow.height = aWindow.height;
    1728                 :     mWindow.type   = aWindow.type;
    1729                 : 
    1730                 :     mWindow.window = reinterpret_cast<void*>(mSharedSurfaceDib.GetHDC());
    1731                 :     ::SetViewportOrgEx(mSharedSurfaceDib.GetHDC(), -aWindow.x, -aWindow.y, NULL);
    1732                 : 
    1733                 :     if (mPluginIface->setwindow)
    1734                 :         mPluginIface->setwindow(&mData, &mWindow);
    1735                 : 
    1736                 :     return true;
    1737                 : }
    1738                 : 
    1739                 : void
    1740                 : PluginInstanceChild::SharedSurfaceRelease()
    1741                 : {
    1742                 :     mSharedSurfaceDib.Close();
    1743                 :     AlphaExtractCacheRelease();
    1744                 : }
    1745                 : 
    1746                 : /* double pass cache buffer - (rarely) used in cases where alpha extraction
    1747                 :  * occurs for windowless plugins. */
    1748                 :  
    1749                 : bool
    1750                 : PluginInstanceChild::AlphaExtractCacheSetup()
    1751                 : {
    1752                 :     AlphaExtractCacheRelease();
    1753                 : 
    1754                 :     mAlphaExtract.hdc = ::CreateCompatibleDC(NULL);
    1755                 : 
    1756                 :     if (!mAlphaExtract.hdc)
    1757                 :         return false;
    1758                 : 
    1759                 :     BITMAPINFOHEADER bmih;
    1760                 :     memset((void*)&bmih, 0, sizeof(BITMAPINFOHEADER));
    1761                 :     bmih.biSize        = sizeof(BITMAPINFOHEADER);
    1762                 :     bmih.biWidth       = mWindow.width;
    1763                 :     bmih.biHeight      = mWindow.height;
    1764                 :     bmih.biPlanes      = 1;
    1765                 :     bmih.biBitCount    = 32;
    1766                 :     bmih.biCompression = BI_RGB;
    1767                 : 
    1768                 :     void* ppvBits = nsnull;
    1769                 :     mAlphaExtract.bmp = ::CreateDIBSection(mAlphaExtract.hdc,
    1770                 :                                            (BITMAPINFO*)&bmih,
    1771                 :                                            DIB_RGB_COLORS,
    1772                 :                                            (void**)&ppvBits,
    1773                 :                                            NULL,
    1774                 :                                            (unsigned long)sizeof(BITMAPINFOHEADER));
    1775                 :     if (!mAlphaExtract.bmp)
    1776                 :       return false;
    1777                 : 
    1778                 :     DeleteObject(::SelectObject(mAlphaExtract.hdc, mAlphaExtract.bmp));
    1779                 :     return true;
    1780                 : }
    1781                 : 
    1782                 : void
    1783                 : PluginInstanceChild::AlphaExtractCacheRelease()
    1784                 : {
    1785                 :     if (mAlphaExtract.bmp)
    1786                 :         ::DeleteObject(mAlphaExtract.bmp);
    1787                 : 
    1788                 :     if (mAlphaExtract.hdc)
    1789                 :         ::DeleteObject(mAlphaExtract.hdc);
    1790                 : 
    1791                 :     mAlphaExtract.bmp = NULL;
    1792                 :     mAlphaExtract.hdc = NULL;
    1793                 : }
    1794                 : 
    1795                 : void
    1796                 : PluginInstanceChild::UpdatePaintClipRect(RECT* aRect)
    1797                 : {
    1798                 :     if (aRect) {
    1799                 :         // Update the clip rect on our internal hdc
    1800                 :         HRGN clip = ::CreateRectRgnIndirect(aRect);
    1801                 :         ::SelectClipRgn(mSharedSurfaceDib.GetHDC(), clip);
    1802                 :         ::DeleteObject(clip);
    1803                 :     }
    1804                 : }
    1805                 : 
    1806                 : int16_t
    1807                 : PluginInstanceChild::SharedSurfacePaint(NPEvent& evcopy)
    1808                 : {
    1809                 :     if (!mPluginIface->event)
    1810                 :         return false;
    1811                 : 
    1812                 :     RECT* pRect = reinterpret_cast<RECT*>(evcopy.lParam);
    1813                 : 
    1814                 :     switch(mAlphaExtract.doublePass) {
    1815                 :         case RENDER_NATIVE:
    1816                 :             // pass the internal hdc to the plugin
    1817                 :             UpdatePaintClipRect(pRect);
    1818                 :             evcopy.wParam = WPARAM(mSharedSurfaceDib.GetHDC());
    1819                 :             return mPluginIface->event(&mData, reinterpret_cast<void*>(&evcopy));
    1820                 :         break;
    1821                 :         case RENDER_BACK_ONE:
    1822                 :               // Handle a double pass render used in alpha extraction for transparent
    1823                 :               // plugins. (See nsObjectFrame and gfxWindowsNativeDrawing for details.)
    1824                 :               // We render twice, once to the shared dib, and once to a cache which
    1825                 :               // we copy back on a second paint. These paints can't be spread across
    1826                 :               // multiple rpc messages as delays cause animation frame changes.
    1827                 :               if (!mAlphaExtract.bmp && !AlphaExtractCacheSetup()) {
    1828                 :                   mAlphaExtract.doublePass = RENDER_NATIVE;
    1829                 :                   return false;
    1830                 :               }
    1831                 : 
    1832                 :               // See gfxWindowsNativeDrawing, color order doesn't have to match.
    1833                 :               UpdatePaintClipRect(pRect);
    1834                 :               ::FillRect(mSharedSurfaceDib.GetHDC(), pRect, (HBRUSH)GetStockObject(WHITE_BRUSH));
    1835                 :               evcopy.wParam = WPARAM(mSharedSurfaceDib.GetHDC());
    1836                 :               if (!mPluginIface->event(&mData, reinterpret_cast<void*>(&evcopy))) {
    1837                 :                   mAlphaExtract.doublePass = RENDER_NATIVE;
    1838                 :                   return false;
    1839                 :               }
    1840                 : 
    1841                 :               // Copy to cache. We render to shared dib so we don't have to call
    1842                 :               // setwindow between calls (flash issue).  
    1843                 :               ::BitBlt(mAlphaExtract.hdc,
    1844                 :                        pRect->left,
    1845                 :                        pRect->top,
    1846                 :                        pRect->right - pRect->left,
    1847                 :                        pRect->bottom - pRect->top,
    1848                 :                        mSharedSurfaceDib.GetHDC(),
    1849                 :                        pRect->left,
    1850                 :                        pRect->top,
    1851                 :                        SRCCOPY);
    1852                 : 
    1853                 :               ::FillRect(mSharedSurfaceDib.GetHDC(), pRect, (HBRUSH)GetStockObject(BLACK_BRUSH));
    1854                 :               if (!mPluginIface->event(&mData, reinterpret_cast<void*>(&evcopy))) {
    1855                 :                   mAlphaExtract.doublePass = RENDER_NATIVE;
    1856                 :                   return false;
    1857                 :               }
    1858                 :               mAlphaExtract.doublePass = RENDER_BACK_TWO;
    1859                 :               return true;
    1860                 :         break;
    1861                 :         case RENDER_BACK_TWO:
    1862                 :               // copy our cached surface back
    1863                 :               UpdatePaintClipRect(pRect);
    1864                 :               ::BitBlt(mSharedSurfaceDib.GetHDC(),
    1865                 :                        pRect->left,
    1866                 :                        pRect->top,
    1867                 :                        pRect->right - pRect->left,
    1868                 :                        pRect->bottom - pRect->top,
    1869                 :                        mAlphaExtract.hdc,
    1870                 :                        pRect->left,
    1871                 :                        pRect->top,
    1872                 :                        SRCCOPY);
    1873                 :               mAlphaExtract.doublePass = RENDER_NATIVE;
    1874                 :               return true;
    1875                 :         break;
    1876                 :     }
    1877                 :     return false;
    1878                 : }
    1879                 : 
    1880                 : /* flash msg throttling helpers */
    1881                 : 
    1882                 : // Flash has the unfortunate habit of flooding dispatch loops with custom
    1883                 : // windowing events they use for timing. We throttle these by dropping the
    1884                 : // delivery priority below any other event, including pending ipc io
    1885                 : // notifications. We do this for both windowed and windowless controls.
    1886                 : // Note flash's windowless msg window can last longer than our instance,
    1887                 : // so we try to unhook when the window is destroyed and in NPP_Destroy.
    1888                 : 
    1889                 : void
    1890                 : PluginInstanceChild::UnhookWinlessFlashThrottle()
    1891                 : {
    1892                 :   // We may have already unhooked
    1893                 :   if (!mWinlessThrottleOldWndProc)
    1894                 :       return;
    1895                 : 
    1896                 :   WNDPROC tmpProc = mWinlessThrottleOldWndProc;
    1897                 :   mWinlessThrottleOldWndProc = nsnull;
    1898                 : 
    1899                 :   NS_ASSERTION(mWinlessHiddenMsgHWND,
    1900                 :                "Missing mWinlessHiddenMsgHWND w/subclass set??");
    1901                 : 
    1902                 :   // reset the subclass
    1903                 :   SetWindowLongPtr(mWinlessHiddenMsgHWND, GWLP_WNDPROC,
    1904                 :                    reinterpret_cast<LONG_PTR>(tmpProc));
    1905                 : 
    1906                 :   // Remove our instance prop
    1907                 :   RemoveProp(mWinlessHiddenMsgHWND, kFlashThrottleProperty);
    1908                 :   mWinlessHiddenMsgHWND = nsnull;
    1909                 : }
    1910                 : 
    1911                 : // static
    1912                 : LRESULT CALLBACK
    1913                 : PluginInstanceChild::WinlessHiddenFlashWndProc(HWND hWnd,
    1914                 :                                                UINT message,
    1915                 :                                                WPARAM wParam,
    1916                 :                                                LPARAM lParam)
    1917                 : {
    1918                 :     PluginInstanceChild* self = reinterpret_cast<PluginInstanceChild*>(
    1919                 :         GetProp(hWnd, kFlashThrottleProperty));
    1920                 :     if (!self) {
    1921                 :         NS_NOTREACHED("Badness!");
    1922                 :         return 0;
    1923                 :     }
    1924                 : 
    1925                 :     NS_ASSERTION(self->mWinlessThrottleOldWndProc,
    1926                 :                  "Missing subclass procedure!!");
    1927                 : 
    1928                 :     // Throttle
    1929                 :     if (message == WM_USER+1) {
    1930                 :         self->FlashThrottleMessage(hWnd, message, wParam, lParam, false);
    1931                 :         return 0;
    1932                 :      }
    1933                 : 
    1934                 :     // Unhook
    1935                 :     if (message == WM_CLOSE || message == WM_NCDESTROY) {
    1936                 :         WNDPROC tmpProc = self->mWinlessThrottleOldWndProc;
    1937                 :         self->UnhookWinlessFlashThrottle();
    1938                 :         LRESULT res = CallWindowProc(tmpProc, hWnd, message, wParam, lParam);
    1939                 :         return res;
    1940                 :     }
    1941                 : 
    1942                 :     return CallWindowProc(self->mWinlessThrottleOldWndProc,
    1943                 :                           hWnd, message, wParam, lParam);
    1944                 : }
    1945                 : 
    1946                 : // Enumerate all thread windows looking for flash's hidden message window.
    1947                 : // Once we find it, sub class it so we can throttle user msgs.  
    1948                 : // static
    1949                 : BOOL CALLBACK
    1950                 : PluginInstanceChild::EnumThreadWindowsCallback(HWND hWnd,
    1951                 :                                                LPARAM aParam)
    1952                 : {
    1953                 :     PluginInstanceChild* self = reinterpret_cast<PluginInstanceChild*>(aParam);
    1954                 :     if (!self) {
    1955                 :         NS_NOTREACHED("Enum befuddled!");
    1956                 :         return FALSE;
    1957                 :     }
    1958                 : 
    1959                 :     PRUnichar className[64];
    1960                 :     if (!GetClassNameW(hWnd, className, sizeof(className)/sizeof(PRUnichar)))
    1961                 :       return TRUE;
    1962                 :     
    1963                 :     if (!wcscmp(className, L"SWFlash_PlaceholderX")) {
    1964                 :         WNDPROC oldWndProc =
    1965                 :             reinterpret_cast<WNDPROC>(GetWindowLongPtr(hWnd, GWLP_WNDPROC));
    1966                 :         // Only set this if we haven't already.
    1967                 :         if (oldWndProc != WinlessHiddenFlashWndProc) {
    1968                 :             if (self->mWinlessThrottleOldWndProc) {
    1969                 :                 NS_WARNING("mWinlessThrottleWndProc already set???");
    1970                 :                 return FALSE;
    1971                 :             }
    1972                 :             // Subsclass and store self as a property
    1973                 :             self->mWinlessHiddenMsgHWND = hWnd;
    1974                 :             self->mWinlessThrottleOldWndProc =
    1975                 :                 reinterpret_cast<WNDPROC>(SetWindowLongPtr(hWnd, GWLP_WNDPROC,
    1976                 :                 reinterpret_cast<LONG_PTR>(WinlessHiddenFlashWndProc)));
    1977                 :             SetProp(hWnd, kFlashThrottleProperty, self);
    1978                 :             NS_ASSERTION(self->mWinlessThrottleOldWndProc,
    1979                 :                          "SetWindowLongPtr failed?!");
    1980                 :         }
    1981                 :         // Return no matter what once we find the right window.
    1982                 :         return FALSE;
    1983                 :     }
    1984                 : 
    1985                 :     return TRUE;
    1986                 : }
    1987                 : 
    1988                 : 
    1989                 : void
    1990                 : PluginInstanceChild::SetupFlashMsgThrottle()
    1991                 : {
    1992                 :     if (mWindow.type == NPWindowTypeDrawable) {
    1993                 :         // Search for the flash hidden message window and subclass it. Only
    1994                 :         // search for flash windows belonging to our ui thread!
    1995                 :         if (mWinlessThrottleOldWndProc)
    1996                 :             return;
    1997                 :         EnumThreadWindows(GetCurrentThreadId(), EnumThreadWindowsCallback,
    1998                 :                           reinterpret_cast<LPARAM>(this));
    1999                 :     }
    2000                 :     else {
    2001                 :         // Already setup through quirks and the subclass.
    2002                 :         return;
    2003                 :     }
    2004                 : }
    2005                 : 
    2006                 : WNDPROC
    2007                 : PluginInstanceChild::FlashThrottleAsyncMsg::GetProc()
    2008                 : { 
    2009                 :     if (mInstance) {
    2010                 :         return mWindowed ? mInstance->mPluginWndProc :
    2011                 :                            mInstance->mWinlessThrottleOldWndProc;
    2012                 :     }
    2013                 :     return nsnull;
    2014                 : }
    2015                 :  
    2016                 : void
    2017                 : PluginInstanceChild::FlashThrottleAsyncMsg::Run()
    2018                 : {
    2019                 :     RemoveFromAsyncList();
    2020                 : 
    2021                 :     // GetProc() checks mInstance, and pulls the procedure from
    2022                 :     // PluginInstanceChild. We don't transport sub-class procedure
    2023                 :     // ptrs around in FlashThrottleAsyncMsg msgs.
    2024                 :     if (!GetProc())
    2025                 :         return;
    2026                 :   
    2027                 :     // deliver the event to flash 
    2028                 :     CallWindowProc(GetProc(), GetWnd(), GetMsg(), GetWParam(), GetLParam());
    2029                 : }
    2030                 : 
    2031                 : void
    2032                 : PluginInstanceChild::FlashThrottleMessage(HWND aWnd,
    2033                 :                                           UINT aMsg,
    2034                 :                                           WPARAM aWParam,
    2035                 :                                           LPARAM aLParam,
    2036                 :                                           bool isWindowed)
    2037                 : {
    2038                 :     // We reuse ChildAsyncCall so we get the cancelation work
    2039                 :     // that's done in Destroy.
    2040                 :     FlashThrottleAsyncMsg* task = new FlashThrottleAsyncMsg(this,
    2041                 :         aWnd, aMsg, aWParam, aLParam, isWindowed);
    2042                 :     if (!task)
    2043                 :         return; 
    2044                 : 
    2045                 :     {
    2046                 :         MutexAutoLock lock(mAsyncCallMutex);
    2047                 :         mPendingAsyncCalls.AppendElement(task);
    2048                 :     }
    2049                 :     MessageLoop::current()->PostDelayedTask(FROM_HERE,
    2050                 :         task, kFlashWMUSERMessageThrottleDelayMs);
    2051                 : }
    2052                 : 
    2053                 : #endif // OS_WIN
    2054                 : 
    2055                 : bool
    2056               0 : PluginInstanceChild::AnswerSetPluginFocus()
    2057                 : {
    2058               0 :     PR_LOG(gPluginLog, PR_LOG_DEBUG, ("%s", FULLFUNCTION));
    2059                 : 
    2060                 : #if defined(OS_WIN)
    2061                 :     // Parent is letting us know the dom set focus to the plugin. Note,
    2062                 :     // focus can change during transit in certain edge cases, for example
    2063                 :     // when a button click brings up a full screen window. Since we send
    2064                 :     // this in response to a WM_SETFOCUS event on our parent, the parent
    2065                 :     // should have focus when we receive this. If not, ignore the call.
    2066                 :     if (::GetFocus() == mPluginWindowHWND ||
    2067                 :         ((GetQuirks() & PluginModuleChild::QUIRK_SILVERLIGHT_FOCUS_CHECK_PARENT) &&
    2068                 :          (::GetFocus() != mPluginParentHWND)))
    2069                 :         return true;
    2070                 :     ::SetFocus(mPluginWindowHWND);
    2071                 :     return true;
    2072                 : #else
    2073               0 :     NS_NOTREACHED("PluginInstanceChild::AnswerSetPluginFocus not implemented!");
    2074               0 :     return false;
    2075                 : #endif
    2076                 : }
    2077                 : 
    2078                 : bool
    2079               0 : PluginInstanceChild::AnswerUpdateWindow()
    2080                 : {
    2081               0 :     PR_LOG(gPluginLog, PR_LOG_DEBUG, ("%s", FULLFUNCTION));
    2082                 : 
    2083                 : #if defined(OS_WIN)
    2084                 :     if (mPluginWindowHWND) {
    2085                 :         RECT rect;
    2086                 :         if (GetUpdateRect(GetParent(mPluginWindowHWND), &rect, FALSE)) {
    2087                 :             ::InvalidateRect(mPluginWindowHWND, &rect, FALSE); 
    2088                 :         }
    2089                 :         UpdateWindow(mPluginWindowHWND);
    2090                 :     }
    2091                 :     return true;
    2092                 : #else
    2093               0 :     NS_NOTREACHED("PluginInstanceChild::AnswerUpdateWindow not implemented!");
    2094               0 :     return false;
    2095                 : #endif
    2096                 : }
    2097                 : 
    2098                 : bool
    2099               0 : PluginInstanceChild::RecvNPP_DidComposite()
    2100                 : {
    2101               0 :   if (mPluginIface->didComposite) {
    2102               0 :     mPluginIface->didComposite(GetNPP());
    2103                 :   }
    2104               0 :   return true;
    2105                 : }
    2106                 : 
    2107                 : PPluginScriptableObjectChild*
    2108               0 : PluginInstanceChild::AllocPPluginScriptableObject()
    2109                 : {
    2110               0 :     AssertPluginThread();
    2111               0 :     return new PluginScriptableObjectChild(Proxy);
    2112                 : }
    2113                 : 
    2114                 : bool
    2115               0 : PluginInstanceChild::DeallocPPluginScriptableObject(
    2116                 :     PPluginScriptableObjectChild* aObject)
    2117                 : {
    2118               0 :     AssertPluginThread();
    2119               0 :     delete aObject;
    2120               0 :     return true;
    2121                 : }
    2122                 : 
    2123                 : bool
    2124               0 : PluginInstanceChild::RecvPPluginScriptableObjectConstructor(
    2125                 :                                            PPluginScriptableObjectChild* aActor)
    2126                 : {
    2127               0 :     AssertPluginThread();
    2128                 : 
    2129                 :     // This is only called in response to the parent process requesting the
    2130                 :     // creation of an actor. This actor will represent an NPObject that is
    2131                 :     // created by the browser and returned to the plugin.
    2132                 :     PluginScriptableObjectChild* actor =
    2133               0 :         static_cast<PluginScriptableObjectChild*>(aActor);
    2134               0 :     NS_ASSERTION(!actor->GetObject(false), "Actor already has an object?!");
    2135                 : 
    2136               0 :     actor->InitializeProxy();
    2137               0 :     NS_ASSERTION(actor->GetObject(false), "Actor should have an object!");
    2138                 : 
    2139               0 :     return true;
    2140                 : }
    2141                 : 
    2142                 : bool
    2143               0 : PluginInstanceChild::AnswerPBrowserStreamConstructor(
    2144                 :     PBrowserStreamChild* aActor,
    2145                 :     const nsCString& url,
    2146                 :     const uint32_t& length,
    2147                 :     const uint32_t& lastmodified,
    2148                 :     PStreamNotifyChild* notifyData,
    2149                 :     const nsCString& headers,
    2150                 :     const nsCString& mimeType,
    2151                 :     const bool& seekable,
    2152                 :     NPError* rv,
    2153                 :     uint16_t* stype)
    2154                 : {
    2155               0 :     AssertPluginThread();
    2156                 :     *rv = static_cast<BrowserStreamChild*>(aActor)
    2157               0 :           ->StreamConstructed(mimeType, seekable, stype);
    2158               0 :     return true;
    2159                 : }
    2160                 : 
    2161                 : PBrowserStreamChild*
    2162               0 : PluginInstanceChild::AllocPBrowserStream(const nsCString& url,
    2163                 :                                          const uint32_t& length,
    2164                 :                                          const uint32_t& lastmodified,
    2165                 :                                          PStreamNotifyChild* notifyData,
    2166                 :                                          const nsCString& headers,
    2167                 :                                          const nsCString& mimeType,
    2168                 :                                          const bool& seekable,
    2169                 :                                          NPError* rv,
    2170                 :                                          uint16_t *stype)
    2171                 : {
    2172               0 :     AssertPluginThread();
    2173                 :     return new BrowserStreamChild(this, url, length, lastmodified,
    2174                 :                                   static_cast<StreamNotifyChild*>(notifyData),
    2175               0 :                                   headers, mimeType, seekable, rv, stype);
    2176                 : }
    2177                 : 
    2178                 : bool
    2179               0 : PluginInstanceChild::DeallocPBrowserStream(PBrowserStreamChild* stream)
    2180                 : {
    2181               0 :     AssertPluginThread();
    2182               0 :     delete stream;
    2183               0 :     return true;
    2184                 : }
    2185                 : 
    2186                 : PPluginStreamChild*
    2187               0 : PluginInstanceChild::AllocPPluginStream(const nsCString& mimeType,
    2188                 :                                         const nsCString& target,
    2189                 :                                         NPError* result)
    2190                 : {
    2191               0 :     NS_RUNTIMEABORT("not callable");
    2192               0 :     return NULL;
    2193                 : }
    2194                 : 
    2195                 : bool
    2196               0 : PluginInstanceChild::DeallocPPluginStream(PPluginStreamChild* stream)
    2197                 : {
    2198               0 :     AssertPluginThread();
    2199               0 :     delete stream;
    2200               0 :     return true;
    2201                 : }
    2202                 : 
    2203                 : PStreamNotifyChild*
    2204               0 : PluginInstanceChild::AllocPStreamNotify(const nsCString& url,
    2205                 :                                         const nsCString& target,
    2206                 :                                         const bool& post,
    2207                 :                                         const nsCString& buffer,
    2208                 :                                         const bool& file,
    2209                 :                                         NPError* result)
    2210                 : {
    2211               0 :     AssertPluginThread();
    2212               0 :     NS_RUNTIMEABORT("not reached");
    2213               0 :     return NULL;
    2214                 : }
    2215                 : 
    2216                 : void
    2217               0 : StreamNotifyChild::ActorDestroy(ActorDestroyReason why)
    2218                 : {
    2219               0 :     if (AncestorDeletion == why && mBrowserStream) {
    2220               0 :         NS_ERROR("Pending NPP_URLNotify not called when closing an instance.");
    2221                 : 
    2222                 :         // reclaim responsibility for deleting ourself
    2223               0 :         mBrowserStream->mStreamNotify = NULL;
    2224               0 :         mBrowserStream = NULL;
    2225                 :     }
    2226               0 : }
    2227                 : 
    2228                 : 
    2229                 : void
    2230               0 : StreamNotifyChild::SetAssociatedStream(BrowserStreamChild* bs)
    2231                 : {
    2232               0 :     NS_ASSERTION(bs, "Shouldn't be null");
    2233               0 :     NS_ASSERTION(!mBrowserStream, "Two streams for one streamnotify?");
    2234                 : 
    2235               0 :     mBrowserStream = bs;
    2236               0 : }
    2237                 : 
    2238                 : bool
    2239               0 : StreamNotifyChild::Recv__delete__(const NPReason& reason)
    2240                 : {
    2241               0 :     AssertPluginThread();
    2242                 : 
    2243               0 :     if (mBrowserStream)
    2244               0 :         mBrowserStream->NotifyPending();
    2245                 :     else
    2246               0 :         NPP_URLNotify(reason);
    2247                 : 
    2248               0 :     return true;
    2249                 : }
    2250                 : 
    2251                 : bool
    2252               0 : StreamNotifyChild::RecvRedirectNotify(const nsCString& url, const int32_t& status)
    2253                 : {
    2254                 :     // NPP_URLRedirectNotify requires a non-null closure. Since core logic
    2255                 :     // assumes that all out-of-process notify streams have non-null closure
    2256                 :     // data it will assume that the plugin was notified at this point and
    2257                 :     // expect a response otherwise the redirect will hang indefinitely.
    2258               0 :     if (!mClosure) {
    2259               0 :         SendRedirectNotifyResponse(false);
    2260                 :     }
    2261                 : 
    2262               0 :     PluginInstanceChild* instance = static_cast<PluginInstanceChild*>(Manager());
    2263               0 :     if (instance->mPluginIface->urlredirectnotify)
    2264               0 :       instance->mPluginIface->urlredirectnotify(instance->GetNPP(), url.get(), status, mClosure);
    2265                 : 
    2266               0 :     return true;
    2267                 : }
    2268                 : 
    2269                 : void
    2270               0 : StreamNotifyChild::NPP_URLNotify(NPReason reason)
    2271                 : {
    2272               0 :     PluginInstanceChild* instance = static_cast<PluginInstanceChild*>(Manager());
    2273                 : 
    2274               0 :     if (mClosure)
    2275                 :         instance->mPluginIface->urlnotify(instance->GetNPP(), mURL.get(),
    2276               0 :                                           reason, mClosure);
    2277               0 : }
    2278                 : 
    2279                 : bool
    2280               0 : PluginInstanceChild::DeallocPStreamNotify(PStreamNotifyChild* notifyData)
    2281                 : {
    2282               0 :     AssertPluginThread();
    2283                 : 
    2284               0 :     if (!static_cast<StreamNotifyChild*>(notifyData)->mBrowserStream)
    2285               0 :         delete notifyData;
    2286               0 :     return true;
    2287                 : }
    2288                 : 
    2289                 : PluginScriptableObjectChild*
    2290               0 : PluginInstanceChild::GetActorForNPObject(NPObject* aObject)
    2291                 : {
    2292               0 :     AssertPluginThread();
    2293               0 :     NS_ASSERTION(aObject, "Null pointer!");
    2294                 : 
    2295               0 :     if (aObject->_class == PluginScriptableObjectChild::GetClass()) {
    2296                 :         // One of ours! It's a browser-provided object.
    2297               0 :         ChildNPObject* object = static_cast<ChildNPObject*>(aObject);
    2298               0 :         NS_ASSERTION(object->parent, "Null actor!");
    2299               0 :         return object->parent;
    2300                 :     }
    2301                 : 
    2302                 :     PluginScriptableObjectChild* actor =
    2303               0 :         PluginModuleChild::current()->GetActorForNPObject(aObject);
    2304               0 :     if (actor) {
    2305                 :         // Plugin-provided object that we've previously wrapped.
    2306               0 :         return actor;
    2307                 :     }
    2308                 : 
    2309               0 :     actor = new PluginScriptableObjectChild(LocalObject);
    2310               0 :     if (!SendPPluginScriptableObjectConstructor(actor)) {
    2311               0 :         NS_ERROR("Failed to send constructor message!");
    2312               0 :         return nsnull;
    2313                 :     }
    2314                 : 
    2315               0 :     actor->InitializeLocal(aObject);
    2316               0 :     return actor;
    2317                 : }
    2318                 : 
    2319                 : NPError
    2320               0 : PluginInstanceChild::NPN_NewStream(NPMIMEType aMIMEType, const char* aWindow,
    2321                 :                                    NPStream** aStream)
    2322                 : {
    2323               0 :     AssertPluginThread();
    2324                 : 
    2325               0 :     PluginStreamChild* ps = new PluginStreamChild();
    2326                 : 
    2327                 :     NPError result;
    2328               0 :     CallPPluginStreamConstructor(ps, nsDependentCString(aMIMEType),
    2329               0 :                                  NullableString(aWindow), &result);
    2330               0 :     if (NPERR_NO_ERROR != result) {
    2331               0 :         *aStream = NULL;
    2332               0 :         PPluginStreamChild::Call__delete__(ps, NPERR_GENERIC_ERROR, true);
    2333               0 :         return result;
    2334                 :     }
    2335                 : 
    2336               0 :     *aStream = &ps->mStream;
    2337               0 :     return NPERR_NO_ERROR;
    2338                 : }
    2339                 : 
    2340                 : void
    2341               0 : PluginInstanceChild::NPN_URLRedirectResponse(void* notifyData, NPBool allow)
    2342                 : {
    2343               0 :     if (!notifyData) {
    2344               0 :         return;
    2345                 :     }
    2346                 : 
    2347               0 :     InfallibleTArray<PStreamNotifyChild*> notifyStreams;
    2348               0 :     ManagedPStreamNotifyChild(notifyStreams);
    2349               0 :     PRUint32 notifyStreamCount = notifyStreams.Length();
    2350               0 :     for (PRUint32 i = 0; i < notifyStreamCount; i++) {
    2351               0 :         StreamNotifyChild* sn = static_cast<StreamNotifyChild*>(notifyStreams[i]);
    2352               0 :         if (sn->mClosure == notifyData) {
    2353               0 :             sn->SendRedirectNotifyResponse(static_cast<bool>(allow));
    2354                 :             return;
    2355                 :         }
    2356                 :     }
    2357               0 :     NS_ASSERTION(false, "Couldn't find stream for redirect response!");
    2358                 : }
    2359                 : 
    2360                 : NPError
    2361               0 : PluginInstanceChild::DeallocateAsyncBitmapSurface(NPAsyncSurface *aSurface)
    2362                 : {
    2363                 :     AsyncBitmapData* data;
    2364                 :     
    2365               0 :     if (!mAsyncBitmaps.Get(aSurface, &data)) {
    2366               0 :         return NPERR_INVALID_PARAM;
    2367                 :     }
    2368                 : 
    2369               0 :     DeallocShmem(data->mShmem);
    2370               0 :     aSurface->bitmap.data = nsnull;
    2371                 : 
    2372               0 :     mAsyncBitmaps.Remove(aSurface);
    2373               0 :     return NPERR_NO_ERROR;
    2374                 : }
    2375                 : 
    2376                 : bool
    2377               0 : PluginInstanceChild::IsAsyncDrawing()
    2378                 : {
    2379               0 :     return IsDrawingModelAsync(mDrawingModel);
    2380                 : }
    2381                 : 
    2382                 : NPError
    2383               0 : PluginInstanceChild::NPN_InitAsyncSurface(NPSize *size, NPImageFormat format,
    2384                 :                                           void *initData, NPAsyncSurface *surface)
    2385                 : {
    2386               0 :     AssertPluginThread();
    2387                 : 
    2388               0 :     surface->bitmap.data = NULL;
    2389                 : 
    2390               0 :     if (!IsAsyncDrawing()) {
    2391               0 :         return NPERR_GENERIC_ERROR;
    2392                 :     }
    2393                 : 
    2394               0 :     switch (mDrawingModel) {
    2395                 :     case NPDrawingModelAsyncBitmapSurface: {
    2396               0 :             if (mAsyncBitmaps.Get(surface, nsnull)) {
    2397               0 :                 return NPERR_INVALID_PARAM;
    2398                 :             }
    2399                 : 
    2400               0 :             if (size->width < 0 || size->height < 0) {
    2401               0 :                 return NPERR_INVALID_PARAM;
    2402                 :             }
    2403                 : 
    2404                 : 
    2405                 :             bool result;
    2406               0 :             NPRemoteAsyncSurface remote;
    2407                 : 
    2408               0 :             if (!CallNPN_InitAsyncSurface(gfxIntSize(size->width, size->height), format, &remote, &result) || !result) {
    2409               0 :                 return NPERR_OUT_OF_MEMORY_ERROR;
    2410                 :             }
    2411                 : 
    2412               0 :             NS_ABORT_IF_FALSE(remote.data().get_Shmem().IsWritable(),
    2413                 :                 "Failed to create writable shared memory.");
    2414                 :             
    2415               0 :             AsyncBitmapData *data = new AsyncBitmapData;
    2416               0 :             mAsyncBitmaps.Put(surface, data);
    2417                 : 
    2418               0 :             data->mRemotePtr = (void*)remote.hostPtr();
    2419               0 :             data->mShmem = remote.data().get_Shmem();
    2420                 : 
    2421               0 :             surface->bitmap.data = data->mShmem.get<unsigned char>();
    2422               0 :             surface->bitmap.stride = remote.stride();
    2423               0 :             surface->format = remote.format();
    2424               0 :             surface->size.width = remote.size().width;
    2425               0 :             surface->size.height = remote.size().height;
    2426                 : 
    2427               0 :             return NPERR_NO_ERROR;
    2428                 :         }
    2429                 :     }
    2430                 : 
    2431               0 :     return NPERR_GENERIC_ERROR;
    2432                 : }
    2433                 : 
    2434                 : NPError
    2435               0 : PluginInstanceChild::NPN_FinalizeAsyncSurface(NPAsyncSurface *surface)
    2436                 : {
    2437               0 :     AssertPluginThread();
    2438                 : 
    2439               0 :     if (!IsAsyncDrawing()) {
    2440               0 :         return NPERR_GENERIC_ERROR;
    2441                 :     }
    2442                 : 
    2443               0 :     switch (mDrawingModel) {
    2444                 :     case NPDrawingModelAsyncBitmapSurface: {
    2445                 :             AsyncBitmapData *bitmapData;
    2446                 : 
    2447               0 :             if (!mAsyncBitmaps.Get(surface, &bitmapData)) {
    2448               0 :                 return NPERR_GENERIC_ERROR;
    2449                 :             }
    2450                 : 
    2451                 :             {
    2452               0 :                 CrossProcessMutexAutoLock autoLock(*mRemoteImageDataMutex);
    2453               0 :                 RemoteImageData *data = mRemoteImageData;
    2454               0 :                 if (data->mBitmap.mData == bitmapData->mRemotePtr) {
    2455               0 :                     data->mBitmap.mData = NULL;
    2456               0 :                     data->mSize = gfxIntSize(0, 0);
    2457               0 :                     data->mWasUpdated = true;
    2458                 :                 }
    2459                 :             }
    2460                 : 
    2461               0 :             return DeallocateAsyncBitmapSurface(surface);
    2462                 :         }
    2463                 :     }
    2464                 : 
    2465               0 :     return NPERR_GENERIC_ERROR;
    2466                 : }
    2467                 : 
    2468                 : void
    2469               0 : PluginInstanceChild::NPN_SetCurrentAsyncSurface(NPAsyncSurface *surface, NPRect *changed)
    2470                 : {
    2471               0 :     if (!IsAsyncDrawing()) {
    2472               0 :         return;
    2473                 :     }
    2474                 : 
    2475               0 :     RemoteImageData *data = mRemoteImageData;
    2476                 : 
    2477               0 :     if (!surface) {
    2478               0 :         CrossProcessMutexAutoLock autoLock(*mRemoteImageDataMutex);
    2479               0 :         data->mBitmap.mData = NULL;
    2480               0 :         data->mSize = gfxIntSize(0, 0);
    2481               0 :         data->mWasUpdated = true;
    2482                 :     } else {
    2483               0 :         switch (mDrawingModel) {
    2484                 :         case NPDrawingModelAsyncBitmapSurface:
    2485                 :             {
    2486                 :                 AsyncBitmapData *bitmapData;
    2487                 :         
    2488               0 :                 if (!mAsyncBitmaps.Get(surface, &bitmapData)) {
    2489               0 :                     return;
    2490                 :                 }
    2491                 :               
    2492               0 :                 CrossProcessMutexAutoLock autoLock(*mRemoteImageDataMutex);
    2493               0 :                 data->mBitmap.mData = (unsigned char*)bitmapData->mRemotePtr;
    2494               0 :                 data->mSize = gfxIntSize(surface->size.width, surface->size.height);
    2495                 :                 data->mFormat = surface->format == NPImageFormatBGRX32 ?
    2496               0 :                                 RemoteImageData::BGRX32 : RemoteImageData::BGRA32;
    2497               0 :                 data->mBitmap.mStride = surface->bitmap.stride;
    2498               0 :                 data->mWasUpdated = true;
    2499                 :                 break;
    2500                 :             }
    2501                 :         }
    2502                 :     }
    2503                 : 
    2504                 :     {
    2505               0 :         MutexAutoLock autoLock(mAsyncInvalidateMutex);
    2506               0 :         if (!mAsyncInvalidateTask) {
    2507                 :             mAsyncInvalidateTask = 
    2508                 :                 NewRunnableMethod<PluginInstanceChild, void (PluginInstanceChild::*)()>
    2509               0 :                     (this, &PluginInstanceChild::DoAsyncRedraw);
    2510               0 :             ProcessChild::message_loop()->PostTask(FROM_HERE, mAsyncInvalidateTask);
    2511                 :         }
    2512                 :     }
    2513                 : }
    2514                 : 
    2515                 : void
    2516               0 : PluginInstanceChild::DoAsyncRedraw()
    2517                 : {
    2518                 :     {
    2519               0 :         MutexAutoLock autoLock(mAsyncInvalidateMutex);
    2520               0 :         mAsyncInvalidateTask = NULL;
    2521                 :     }
    2522                 : 
    2523               0 :     SendRedrawPlugin();
    2524               0 : }
    2525                 : 
    2526                 : bool
    2527               0 : PluginInstanceChild::RecvAsyncSetWindow(const gfxSurfaceType& aSurfaceType,
    2528                 :                                         const NPRemoteWindow& aWindow)
    2529                 : {
    2530               0 :     AssertPluginThread();
    2531                 : 
    2532               0 :     NS_ASSERTION(!aWindow.window, "Remote window should be null.");
    2533                 : 
    2534               0 :     if (mCurrentAsyncSetWindowTask) {
    2535               0 :         mCurrentAsyncSetWindowTask->Cancel();
    2536               0 :         mCurrentAsyncSetWindowTask = nsnull;
    2537                 :     }
    2538                 : 
    2539               0 :     if (mPendingPluginCall) {
    2540                 :         // We shouldn't process this now. Run it later.
    2541                 :         mCurrentAsyncSetWindowTask =
    2542                 :             NewRunnableMethod<PluginInstanceChild,
    2543                 :                               void (PluginInstanceChild::*)(const gfxSurfaceType&, const NPRemoteWindow&, bool),
    2544                 :                               gfxSurfaceType, NPRemoteWindow, bool>
    2545                 :                 (this, &PluginInstanceChild::DoAsyncSetWindow,
    2546               0 :                  aSurfaceType, aWindow, true);
    2547               0 :         MessageLoop::current()->PostTask(FROM_HERE, mCurrentAsyncSetWindowTask);
    2548                 :     } else {
    2549               0 :         DoAsyncSetWindow(aSurfaceType, aWindow, false);
    2550                 :     }
    2551                 : 
    2552               0 :     return true;
    2553                 : }
    2554                 : 
    2555                 : bool
    2556               0 : PluginInstanceChild::AnswerHandleKeyEvent(const nsKeyEvent& aKeyEvent,
    2557                 :                                           bool* handled)
    2558                 : {
    2559               0 :     AssertPluginThread();
    2560                 : #if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
    2561                 :     Qt::KeyboardModifiers modifier;
    2562                 :     if (aKeyEvent.isShift)
    2563                 :         modifier |= Qt::ShiftModifier;
    2564                 :     if (aKeyEvent.isControl)
    2565                 :         modifier |= Qt::ControlModifier;
    2566                 :     if (aKeyEvent.isAlt)
    2567                 :         modifier |= Qt::AltModifier;
    2568                 :     if (aKeyEvent.isMeta)
    2569                 :         modifier |= Qt::MetaModifier;
    2570                 : 
    2571                 :     QEvent::Type type;
    2572                 :     if (aKeyEvent.message == NS_KEY_DOWN) {
    2573                 :         type = QEvent::KeyPress;
    2574                 :     } else if (aKeyEvent.message == NS_KEY_UP) {
    2575                 :         type = QEvent::KeyRelease;
    2576                 :     } else {
    2577                 :         *handled = false;
    2578                 :         return true;
    2579                 :     }
    2580                 :     QKeyEvent keyEv(type, DOMKeyCodeToQtKeyCode(aKeyEvent.keyCode), modifier);
    2581                 :     *handled = QApplication::sendEvent(qApp, &keyEv);
    2582                 : #else
    2583               0 :     NS_ERROR("Not implemented");
    2584                 : #endif
    2585                 : 
    2586               0 :     return true;
    2587                 : }
    2588                 : 
    2589                 : bool
    2590               0 : PluginInstanceChild::AnswerHandleTextEvent(const nsTextEvent& aEvent,
    2591                 :                                            bool* handled)
    2592                 : {
    2593               0 :     AssertPluginThread();
    2594                 : #if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
    2595                 :     QInputMethodEvent event;
    2596                 :     event.setCommitString(QString((const QChar*)aEvent.theText.get(),
    2597                 :                           aEvent.theText.Length()));
    2598                 :     *handled = QApplication::sendEvent(qApp, &event);
    2599                 : #else
    2600               0 :     NS_ERROR("Not implemented");
    2601                 : #endif
    2602                 : 
    2603               0 :     return true;
    2604                 : }
    2605                 : 
    2606                 : void
    2607               0 : PluginInstanceChild::DoAsyncSetWindow(const gfxSurfaceType& aSurfaceType,
    2608                 :                                       const NPRemoteWindow& aWindow,
    2609                 :                                       bool aIsAsync)
    2610                 : {
    2611               0 :     PLUGIN_LOG_DEBUG(
    2612                 :         ("[InstanceChild][%p] AsyncSetWindow to <x=%d,y=%d, w=%d,h=%d>",
    2613                 :          this, aWindow.x, aWindow.y, aWindow.width, aWindow.height));
    2614                 : 
    2615               0 :     AssertPluginThread();
    2616               0 :     NS_ASSERTION(!aWindow.window, "Remote window should be null.");
    2617               0 :     NS_ASSERTION(!mPendingPluginCall, "Can't do SetWindow during plugin call!");
    2618                 : 
    2619               0 :     if (aIsAsync) {
    2620               0 :         if (!mCurrentAsyncSetWindowTask) {
    2621               0 :             return;
    2622                 :         }
    2623               0 :         mCurrentAsyncSetWindowTask = nsnull;
    2624                 :     }
    2625                 : 
    2626               0 :     mWindow.window = NULL;
    2627               0 :     if (mWindow.width != aWindow.width || mWindow.height != aWindow.height ||
    2628                 :         mWindow.clipRect.top != aWindow.clipRect.top ||
    2629                 :         mWindow.clipRect.left != aWindow.clipRect.left ||
    2630                 :         mWindow.clipRect.bottom != aWindow.clipRect.bottom ||
    2631                 :         mWindow.clipRect.right != aWindow.clipRect.right)
    2632               0 :         mAccumulatedInvalidRect = nsIntRect(0, 0, aWindow.width, aWindow.height);
    2633                 : 
    2634               0 :     mWindow.x = aWindow.x;
    2635               0 :     mWindow.y = aWindow.y;
    2636               0 :     mWindow.width = aWindow.width;
    2637               0 :     mWindow.height = aWindow.height;
    2638               0 :     mWindow.clipRect = aWindow.clipRect;
    2639               0 :     mWindow.type = aWindow.type;
    2640                 : 
    2641               0 :     if (GetQuirks() & PluginModuleChild::QUIRK_SILVERLIGHT_DEFAULT_TRANSPARENT)
    2642               0 :         mIsTransparent = true;
    2643                 : 
    2644               0 :     mLayersRendering = true;
    2645               0 :     mSurfaceType = aSurfaceType;
    2646               0 :     UpdateWindowAttributes(true);
    2647                 : 
    2648                 : #ifdef XP_WIN
    2649                 :     if (GetQuirks() & PluginModuleChild::QUIRK_WINLESS_TRACKPOPUP_HOOK)
    2650                 :         CreateWinlessPopupSurrogate();
    2651                 :     if (GetQuirks() & PluginModuleChild::QUIRK_FLASH_THROTTLE_WMUSER_EVENTS)
    2652                 :         SetupFlashMsgThrottle();
    2653                 : #endif
    2654                 : 
    2655               0 :     if (!mAccumulatedInvalidRect.IsEmpty()) {
    2656               0 :         AsyncShowPluginFrame();
    2657                 :     }
    2658                 : }
    2659                 : 
    2660                 : static inline gfxRect
    2661               0 : GfxFromNsRect(const nsIntRect& aRect)
    2662                 : {
    2663               0 :     return gfxRect(aRect.x, aRect.y, aRect.width, aRect.height);
    2664                 : }
    2665                 : 
    2666                 : bool
    2667               0 : PluginInstanceChild::CreateOptSurface(void)
    2668                 : {
    2669               0 :     NS_ABORT_IF_FALSE(mSurfaceType != gfxASurface::SurfaceTypeMax,
    2670                 :                       "Need a valid surface type here");
    2671               0 :     NS_ASSERTION(!mCurrentSurface, "mCurrentSurfaceActor can get out of sync.");
    2672                 : 
    2673               0 :     nsRefPtr<gfxASurface> retsurf;
    2674                 :     // Use an opaque surface unless we're transparent and *don't* have
    2675                 :     // a background to source from.
    2676                 :     gfxASurface::gfxImageFormat format =
    2677               0 :         (mIsTransparent && !mBackground) ? gfxASurface::ImageFormatARGB32 :
    2678               0 :                                            gfxASurface::ImageFormatRGB24;
    2679                 : 
    2680                 : #ifdef MOZ_X11
    2681                 : #if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6)
    2682                 :     // On Maemo 5, we must send the Visibility event to activate the plugin
    2683                 :     if (mMaemoImageRendering) {
    2684                 :         NPEvent pluginEvent;
    2685                 :         XVisibilityEvent& visibilityEvent = pluginEvent.xvisibility;
    2686                 :         visibilityEvent.type = VisibilityNotify;
    2687                 :         visibilityEvent.display = 0;
    2688                 :         visibilityEvent.state = VisibilityUnobscured;
    2689                 :         mPluginIface->event(&mData, reinterpret_cast<void*>(&pluginEvent));
    2690                 :     }
    2691                 : #endif
    2692               0 :     Display* dpy = mWsInfo.display;
    2693               0 :     Screen* screen = DefaultScreenOfDisplay(dpy);
    2694               0 :     if (format == gfxASurface::ImageFormatRGB24 &&
    2695               0 :         DefaultDepth(dpy, DefaultScreen(dpy)) == 16) {
    2696               0 :         format = gfxASurface::ImageFormatRGB16_565;
    2697                 :     }
    2698                 : 
    2699               0 :     if (mSurfaceType == gfxASurface::SurfaceTypeXlib) {
    2700               0 :         if (!mIsTransparent  || mBackground) {
    2701               0 :             Visual* defaultVisual = DefaultVisualOfScreen(screen);
    2702                 :             mCurrentSurface =
    2703                 :                 gfxXlibSurface::Create(screen, defaultVisual,
    2704                 :                                        gfxIntSize(mWindow.width,
    2705               0 :                                                   mWindow.height));
    2706               0 :             return mCurrentSurface != nsnull;
    2707                 :         }
    2708                 : 
    2709               0 :         XRenderPictFormat* xfmt = XRenderFindStandardFormat(dpy, PictStandardARGB32);
    2710               0 :         if (!xfmt) {
    2711               0 :             NS_ERROR("Need X falback surface, but FindRenderFormat failed");
    2712               0 :             return false;
    2713                 :         }
    2714                 :         mCurrentSurface =
    2715                 :             gfxXlibSurface::Create(screen, xfmt,
    2716                 :                                    gfxIntSize(mWindow.width,
    2717               0 :                                               mWindow.height));
    2718               0 :         return mCurrentSurface != nsnull;
    2719                 :     }
    2720                 : #endif
    2721                 : 
    2722                 : #ifdef XP_WIN
    2723                 :     if (mSurfaceType == gfxASurface::SurfaceTypeWin32 ||
    2724                 :         mSurfaceType == gfxASurface::SurfaceTypeD2D) {
    2725                 :         bool willHaveTransparentPixels = mIsTransparent && !mBackground;
    2726                 : 
    2727                 :         SharedDIBSurface* s = new SharedDIBSurface();
    2728                 :         if (!s->Create(reinterpret_cast<HDC>(mWindow.window),
    2729                 :                        mWindow.width, mWindow.height,
    2730                 :                        willHaveTransparentPixels))
    2731                 :             return false;
    2732                 : 
    2733                 :         mCurrentSurface = s;
    2734                 :         return true;
    2735                 :     }
    2736                 : 
    2737                 :     NS_RUNTIMEABORT("Shared-memory drawing not expected on Windows.");
    2738                 : #endif
    2739                 : 
    2740                 :     // Make common shmem implementation working for any platform
    2741                 :     mCurrentSurface =
    2742               0 :         gfxSharedImageSurface::CreateUnsafe(this, gfxIntSize(mWindow.width, mWindow.height), format);
    2743               0 :     return !!mCurrentSurface;
    2744                 : }
    2745                 : 
    2746                 : bool
    2747               0 : PluginInstanceChild::MaybeCreatePlatformHelperSurface(void)
    2748                 : {
    2749               0 :     if (!mCurrentSurface) {
    2750               0 :         NS_ERROR("Cannot create helper surface without mCurrentSurface");
    2751               0 :         return false;
    2752                 :     }
    2753                 : 
    2754                 : #ifdef MOZ_X11
    2755                 : #ifdef MOZ_PLATFORM_MAEMO
    2756                 :     // On maemo plugins support non-default visual rendering
    2757                 :     bool supportNonDefaultVisual = true;
    2758                 : #else
    2759               0 :     bool supportNonDefaultVisual = false;
    2760                 : #endif
    2761               0 :     Screen* screen = DefaultScreenOfDisplay(mWsInfo.display);
    2762               0 :     Visual* defaultVisual = DefaultVisualOfScreen(screen);
    2763               0 :     Visual* visual = nsnull;
    2764               0 :     Colormap colormap = 0;
    2765               0 :     mDoAlphaExtraction = false;
    2766               0 :     bool createHelperSurface = false;
    2767                 : 
    2768               0 :     if (mCurrentSurface->GetType() == gfxASurface::SurfaceTypeXlib) {
    2769               0 :         static_cast<gfxXlibSurface*>(mCurrentSurface.get())->
    2770               0 :             GetColormapAndVisual(&colormap, &visual);
    2771                 :         // Create helper surface if layer surface visual not same as default
    2772                 :         // and we don't support non-default visual rendering
    2773               0 :         if (!visual || (defaultVisual != visual && !supportNonDefaultVisual)) {
    2774               0 :             createHelperSurface = true;
    2775               0 :             visual = defaultVisual;
    2776               0 :             mDoAlphaExtraction = mIsTransparent;
    2777                 :         }
    2778               0 :     } else if (mCurrentSurface->GetType() == gfxASurface::SurfaceTypeImage) {
    2779                 : #if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6)
    2780                 :         if (mMaemoImageRendering) {
    2781                 :             // No helper surface needed, when mMaemoImageRendering is TRUE.
    2782                 :             // we can rendering directly into image memory
    2783                 :             // with NPImageExpose Maemo5 NPAPI
    2784                 :             return true;
    2785                 :         }
    2786                 : #endif
    2787                 :         // For image layer surface we should always create helper surface
    2788               0 :         createHelperSurface = true;
    2789                 :         // Check if we can create helper surface with non-default visual
    2790                 :         visual = gfxXlibSurface::FindVisual(screen,
    2791               0 :             static_cast<gfxImageSurface*>(mCurrentSurface.get())->Format());
    2792               0 :         if (!visual || (defaultVisual != visual && !supportNonDefaultVisual)) {
    2793               0 :             visual = defaultVisual;
    2794               0 :             mDoAlphaExtraction = mIsTransparent;
    2795                 :         }
    2796                 :     }
    2797                 : 
    2798               0 :     if (createHelperSurface) {
    2799               0 :         if (!visual) {
    2800               0 :             NS_ERROR("Need X falback surface, but visual failed");
    2801               0 :             return false;
    2802                 :         }
    2803                 :         mHelperSurface =
    2804                 :             gfxXlibSurface::Create(screen, visual,
    2805               0 :                                    mCurrentSurface->GetSize());
    2806               0 :         if (!mHelperSurface) {
    2807               0 :             NS_WARNING("Fail to create create helper surface");
    2808               0 :             return false;
    2809                 :         }
    2810                 :     }
    2811                 : #elif defined(XP_WIN)
    2812                 :     mDoAlphaExtraction = mIsTransparent && !mBackground;
    2813                 : #endif
    2814                 : 
    2815               0 :     return true;
    2816                 : }
    2817                 : 
    2818                 : bool
    2819               0 : PluginInstanceChild::EnsureCurrentBuffer(void)
    2820                 : {
    2821                 : #ifndef XP_MACOSX
    2822               0 :     nsIntRect toInvalidate(0, 0, 0, 0);
    2823               0 :     gfxIntSize winSize = gfxIntSize(mWindow.width, mWindow.height);
    2824                 : 
    2825               0 :     if (mBackground && mBackground->GetSize() != winSize) {
    2826                 :         // It would be nice to keep the old background here, but doing
    2827                 :         // so can lead to cases in which we permanently keep the old
    2828                 :         // background size.
    2829               0 :         mBackground = nsnull;
    2830                 :         toInvalidate.UnionRect(toInvalidate,
    2831               0 :                                nsIntRect(0, 0, winSize.width, winSize.height));
    2832                 :     }
    2833                 : 
    2834               0 :     if (mCurrentSurface) {
    2835               0 :         gfxIntSize surfSize = mCurrentSurface->GetSize();
    2836               0 :         if (winSize != surfSize ||
    2837               0 :             (mBackground && !CanPaintOnBackground()) ||
    2838                 :             (mBackground &&
    2839               0 :              gfxASurface::CONTENT_COLOR != mCurrentSurface->GetContentType()) ||
    2840               0 :             (!mBackground && mIsTransparent &&
    2841               0 :              gfxASurface::CONTENT_COLOR == mCurrentSurface->GetContentType())) {
    2842                 :             // Don't try to use an old, invalid DC.
    2843               0 :             mWindow.window = nsnull;
    2844               0 :             ClearCurrentSurface();
    2845                 :             toInvalidate.UnionRect(toInvalidate,
    2846               0 :                                    nsIntRect(0, 0, winSize.width, winSize.height));
    2847                 :         }
    2848                 :     }
    2849                 : 
    2850               0 :     mAccumulatedInvalidRect.UnionRect(mAccumulatedInvalidRect, toInvalidate);
    2851                 : 
    2852               0 :     if (mCurrentSurface) {
    2853               0 :         return true;
    2854                 :     }
    2855                 : 
    2856               0 :     if (!CreateOptSurface()) {
    2857               0 :         NS_ERROR("Cannot create optimized surface");
    2858               0 :         return false;
    2859                 :     }
    2860                 : 
    2861               0 :     if (!MaybeCreatePlatformHelperSurface()) {
    2862               0 :         NS_ERROR("Cannot create helper surface");
    2863               0 :         return false;
    2864                 :     }
    2865                 : 
    2866               0 :     return true;
    2867                 : #else // XP_MACOSX
    2868                 : 
    2869                 :     if (!mDoubleBufferCARenderer.HasCALayer()) {
    2870                 :         void *caLayer = nsnull;
    2871                 :         if (mDrawingModel == NPDrawingModelCoreGraphics) {
    2872                 :             if (!mCGLayer) {
    2873                 :                 caLayer = mozilla::plugins::PluginUtilsOSX::GetCGLayer(CallCGDraw, this);
    2874                 : 
    2875                 :                 if (!caLayer) {
    2876                 :                     PLUGIN_LOG_DEBUG(("GetCGLayer failed."));
    2877                 :                     return false;
    2878                 :                 }
    2879                 :             }
    2880                 :             mCGLayer = caLayer;
    2881                 :         } else {
    2882                 :             NPError result = mPluginIface->getvalue(GetNPP(),
    2883                 :                                      NPPVpluginCoreAnimationLayer,
    2884                 :                                      &caLayer);
    2885                 :             if (result != NPERR_NO_ERROR || !caLayer) {
    2886                 :                 PLUGIN_LOG_DEBUG(("Plugin requested CoreAnimation but did not "
    2887                 :                                   "provide CALayer."));
    2888                 :                 return false;
    2889                 :             }
    2890                 :         }
    2891                 :         mDoubleBufferCARenderer.SetCALayer(caLayer);
    2892                 :     }
    2893                 : 
    2894                 :     if (mDoubleBufferCARenderer.HasFrontSurface() &&
    2895                 :         (mDoubleBufferCARenderer.GetFrontSurfaceWidth() != mWindow.width ||
    2896                 :          mDoubleBufferCARenderer.GetFrontSurfaceHeight() != mWindow.height) ) {
    2897                 :         mDoubleBufferCARenderer.ClearFrontSurface();
    2898                 :     }
    2899                 : 
    2900                 :     if (!mDoubleBufferCARenderer.HasFrontSurface()) {
    2901                 :         bool allocSurface = mDoubleBufferCARenderer.InitFrontSurface(
    2902                 :                                 mWindow.width, mWindow.height,
    2903                 :                                 GetQuirks() & PluginModuleChild::QUIRK_ALLOW_OFFLINE_RENDERER ?
    2904                 :                                 ALLOW_OFFLINE_RENDERER : DISALLOW_OFFLINE_RENDERER);
    2905                 :         if (!allocSurface) {
    2906                 :             PLUGIN_LOG_DEBUG(("Fail to allocate front IOSurface"));
    2907                 :             return false;
    2908                 :         }
    2909                 : 
    2910                 :         if (mPluginIface->setwindow)
    2911                 :             (void) mPluginIface->setwindow(&mData, &mWindow);
    2912                 : 
    2913                 :         nsIntRect toInvalidate(0, 0, mWindow.width, mWindow.height);
    2914                 :         mAccumulatedInvalidRect.UnionRect(mAccumulatedInvalidRect, toInvalidate);
    2915                 :     }
    2916                 :   
    2917                 :     return true;
    2918                 : #endif
    2919                 : }
    2920                 : 
    2921                 : void
    2922               0 : PluginInstanceChild::UpdateWindowAttributes(bool aForceSetWindow)
    2923                 : {
    2924               0 :     nsRefPtr<gfxASurface> curSurface = mHelperSurface ? mHelperSurface : mCurrentSurface;
    2925               0 :     bool needWindowUpdate = aForceSetWindow;
    2926                 : #ifdef MOZ_X11
    2927               0 :     Visual* visual = nsnull;
    2928               0 :     Colormap colormap = 0;
    2929               0 :     if (curSurface && curSurface->GetType() == gfxASurface::SurfaceTypeXlib) {
    2930               0 :         static_cast<gfxXlibSurface*>(curSurface.get())->
    2931               0 :             GetColormapAndVisual(&colormap, &visual);
    2932               0 :         if (visual != mWsInfo.visual || colormap != mWsInfo.colormap) {
    2933               0 :             mWsInfo.visual = visual;
    2934               0 :             mWsInfo.colormap = colormap;
    2935               0 :             needWindowUpdate = true;
    2936                 :         }
    2937                 :     }
    2938                 : #if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6)
    2939                 :     else if (curSurface && curSurface->GetType() == gfxASurface::SurfaceTypeImage
    2940                 :              && mMaemoImageRendering) {
    2941                 :         // For maemo5 we need to setup window/colormap to 0
    2942                 :         // and specify depth of image surface
    2943                 :         gfxImageSurface* img = static_cast<gfxImageSurface*>(curSurface.get());
    2944                 :         if (mWindow.window ||
    2945                 :             mWsInfo.depth != gfxUtils::ImageFormatToDepth(img->Format()) ||
    2946                 :             mWsInfo.colormap) {
    2947                 :             mWindow.window = nsnull;
    2948                 :             mWsInfo.depth = gfxUtils::ImageFormatToDepth(img->Format());
    2949                 :             mWsInfo.colormap = 0;
    2950                 :             needWindowUpdate = true;
    2951                 :         }
    2952                 :     }
    2953                 : #endif // MAEMO
    2954                 : #endif // MOZ_X11
    2955                 : #ifdef XP_WIN
    2956                 :     HDC dc = NULL;
    2957                 : 
    2958                 :     if (curSurface) {
    2959                 :         if (!SharedDIBSurface::IsSharedDIBSurface(curSurface))
    2960                 :             NS_RUNTIMEABORT("Expected SharedDIBSurface!");
    2961                 : 
    2962                 :         SharedDIBSurface* dibsurf = static_cast<SharedDIBSurface*>(curSurface.get());
    2963                 :         dc = dibsurf->GetHDC();
    2964                 :     }
    2965                 :     if (mWindow.window != dc) {
    2966                 :         mWindow.window = dc;
    2967                 :         needWindowUpdate = true;
    2968                 :     }
    2969                 : #endif // XP_WIN
    2970                 : 
    2971               0 :     if (!needWindowUpdate) {
    2972                 :         return;
    2973                 :     }
    2974                 : 
    2975                 : #ifndef XP_MACOSX
    2976                 :     // Adjusting the window isn't needed for OSX
    2977                 : #ifndef XP_WIN
    2978                 :     // On Windows, we translate the device context, in order for the window
    2979                 :     // origin to be correct.
    2980               0 :     mWindow.x = mWindow.y = 0;
    2981                 : #endif
    2982                 : 
    2983               0 :     if (IsVisible()) {
    2984                 :         // The clip rect is relative to drawable top-left.
    2985               0 :         nsIntRect clipRect;
    2986                 : 
    2987                 :         // Don't ask the plugin to draw outside the drawable. The clip rect
    2988                 :         // is in plugin coordinates, not window coordinates.
    2989                 :         // This also ensures that the unsigned clip rectangle offsets won't be -ve.
    2990               0 :         clipRect.SetRect(0, 0, mWindow.width, mWindow.height);
    2991                 : 
    2992               0 :         mWindow.clipRect.left = 0;
    2993               0 :         mWindow.clipRect.top = 0;
    2994               0 :         mWindow.clipRect.right = clipRect.XMost();
    2995               0 :         mWindow.clipRect.bottom = clipRect.YMost();
    2996                 :     }
    2997                 : #endif // XP_MACOSX
    2998                 : 
    2999                 : #ifdef XP_WIN
    3000                 :     // Windowless plugins on Windows need a WM_WINDOWPOSCHANGED event to update
    3001                 :     // their location... or at least Flash does: Silverlight uses the
    3002                 :     // window.x/y passed to NPP_SetWindow
    3003                 : 
    3004                 :     if (mPluginIface->event) {
    3005                 :         WINDOWPOS winpos = {
    3006                 :             0, 0,
    3007                 :             mWindow.x, mWindow.y,
    3008                 :             mWindow.width, mWindow.height,
    3009                 :             0
    3010                 :         };
    3011                 :         NPEvent pluginEvent = {
    3012                 :             WM_WINDOWPOSCHANGED, 0,
    3013                 :             (LPARAM) &winpos
    3014                 :         };
    3015                 :         mPluginIface->event(&mData, &pluginEvent);
    3016                 :     }
    3017                 : #endif
    3018                 : 
    3019               0 :     PLUGIN_LOG_DEBUG(
    3020                 :         ("[InstanceChild][%p] UpdateWindow w=<x=%d,y=%d, w=%d,h=%d>, clip=<l=%d,t=%d,r=%d,b=%d>",
    3021                 :          this, mWindow.x, mWindow.y, mWindow.width, mWindow.height,
    3022                 :          mWindow.clipRect.left, mWindow.clipRect.top, mWindow.clipRect.right, mWindow.clipRect.bottom));
    3023                 : 
    3024               0 :     if (mPluginIface->setwindow) {
    3025               0 :         mPluginIface->setwindow(&mData, &mWindow);
    3026                 :     }
    3027                 : }
    3028                 : 
    3029                 : void
    3030               0 : PluginInstanceChild::PaintRectToPlatformSurface(const nsIntRect& aRect,
    3031                 :                                                 gfxASurface* aSurface)
    3032                 : {
    3033               0 :     UpdateWindowAttributes();
    3034                 : 
    3035                 : #ifdef MOZ_X11
    3036                 : #if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6)
    3037                 :     // On maemo5 we do support Image rendering NPAPI
    3038                 :     if (mMaemoImageRendering &&
    3039                 :         aSurface->GetType() == gfxASurface::SurfaceTypeImage) {
    3040                 :         aSurface->Flush();
    3041                 :         gfxImageSurface* image = static_cast<gfxImageSurface*>(aSurface);
    3042                 :         NPImageExpose imgExp;
    3043                 :         imgExp.depth = gfxUtils::ImageFormatToDepth(image->Format());
    3044                 :         imgExp.x = aRect.x;
    3045                 :         imgExp.y = aRect.y;
    3046                 :         imgExp.width = aRect.width;
    3047                 :         imgExp.height = aRect.height;
    3048                 :         imgExp.stride = image->Stride();
    3049                 :         imgExp.data = (char *)image->Data();
    3050                 :         imgExp.dataSize.width = image->Width();
    3051                 :         imgExp.dataSize.height = image->Height();
    3052                 :         imgExp.translateX = 0;
    3053                 :         imgExp.translateY = 0;
    3054                 :         imgExp.scaleX = 1;
    3055                 :         imgExp.scaleY = 1;
    3056                 :         NPEvent pluginEvent;
    3057                 :         XGraphicsExposeEvent& exposeEvent = pluginEvent.xgraphicsexpose;
    3058                 :         exposeEvent.type = GraphicsExpose;
    3059                 :         exposeEvent.display = 0;
    3060                 :         // Store imageExpose structure pointer as drawable member
    3061                 :         exposeEvent.drawable = (Drawable)&imgExp;
    3062                 :         exposeEvent.x = imgExp.x;
    3063                 :         exposeEvent.y = imgExp.y;
    3064                 :         exposeEvent.width = imgExp.width;
    3065                 :         exposeEvent.height = imgExp.height;
    3066                 :         exposeEvent.count = 0;
    3067                 :         // information not set:
    3068                 :         exposeEvent.serial = 0;
    3069                 :         exposeEvent.send_event = False;
    3070                 :         exposeEvent.major_code = 0;
    3071                 :         exposeEvent.minor_code = 0;
    3072                 :         mPluginIface->event(&mData, reinterpret_cast<void*>(&exposeEvent));
    3073                 :         aSurface->MarkDirty(gfxRect(aRect.x, aRect.y, aRect.width, aRect.height));
    3074                 :     } else
    3075                 : #endif
    3076                 :     {
    3077               0 :         NS_ASSERTION(aSurface->GetType() == gfxASurface::SurfaceTypeXlib,
    3078                 :                      "Non supported platform surface type");
    3079                 : 
    3080                 :         NPEvent pluginEvent;
    3081               0 :         XGraphicsExposeEvent& exposeEvent = pluginEvent.xgraphicsexpose;
    3082               0 :         exposeEvent.type = GraphicsExpose;
    3083               0 :         exposeEvent.display = mWsInfo.display;
    3084               0 :         exposeEvent.drawable = static_cast<gfxXlibSurface*>(aSurface)->XDrawable();
    3085               0 :         exposeEvent.x = aRect.x;
    3086               0 :         exposeEvent.y = aRect.y;
    3087               0 :         exposeEvent.width = aRect.width;
    3088               0 :         exposeEvent.height = aRect.height;
    3089               0 :         exposeEvent.count = 0;
    3090                 :         // information not set:
    3091               0 :         exposeEvent.serial = 0;
    3092               0 :         exposeEvent.send_event = False;
    3093               0 :         exposeEvent.major_code = 0;
    3094               0 :         exposeEvent.minor_code = 0;
    3095               0 :         mPluginIface->event(&mData, reinterpret_cast<void*>(&exposeEvent));
    3096                 :     }
    3097                 : #elif defined(XP_WIN)
    3098                 :     NS_ASSERTION(SharedDIBSurface::IsSharedDIBSurface(aSurface),
    3099                 :                  "Expected (SharedDIB) image surface.");
    3100                 : 
    3101                 :     // This rect is in the window coordinate space. aRect is in the plugin
    3102                 :     // coordinate space.
    3103                 :     RECT rect = {
    3104                 :         mWindow.x + aRect.x,
    3105                 :         mWindow.y + aRect.y,
    3106                 :         mWindow.x + aRect.XMost(),
    3107                 :         mWindow.y + aRect.YMost()
    3108                 :     };
    3109                 :     NPEvent paintEvent = {
    3110                 :         WM_PAINT,
    3111                 :         uintptr_t(mWindow.window),
    3112                 :         uintptr_t(&rect)
    3113                 :     };
    3114                 : 
    3115                 :     ::SetViewportOrgEx((HDC) mWindow.window, -mWindow.x, -mWindow.y, NULL);
    3116                 :     ::SelectClipRgn((HDC) mWindow.window, NULL);
    3117                 :     ::IntersectClipRect((HDC) mWindow.window, rect.left, rect.top, rect.right, rect.bottom);
    3118                 :     mPluginIface->event(&mData, reinterpret_cast<void*>(&paintEvent));
    3119                 : #else
    3120                 :     NS_RUNTIMEABORT("Surface type not implemented.");
    3121                 : #endif
    3122               0 : }
    3123                 : 
    3124                 : void
    3125               0 : PluginInstanceChild::PaintRectToSurface(const nsIntRect& aRect,
    3126                 :                                         gfxASurface* aSurface,
    3127                 :                                         const gfxRGBA& aColor)
    3128                 : {
    3129                 :     // Render using temporary X surface, with copy to image surface
    3130               0 :     nsIntRect plPaintRect(aRect);
    3131               0 :     nsRefPtr<gfxASurface> renderSurface = aSurface;
    3132                 : #ifdef MOZ_X11
    3133               0 :     if (mIsTransparent && (GetQuirks() & PluginModuleChild::QUIRK_FLASH_EXPOSE_COORD_TRANSLATION)) {
    3134                 :         // Work around a bug in Flash up to 10.1 d51 at least, where expose event
    3135                 :         // top left coordinates within the plugin-rect and not at the drawable
    3136                 :         // origin are misinterpreted.  (We can move the top left coordinate
    3137                 :         // provided it is within the clipRect.), see bug 574583
    3138               0 :         plPaintRect.SetRect(0, 0, aRect.XMost(), aRect.YMost());
    3139                 :     }
    3140               0 :     if (mHelperSurface) {
    3141                 :         // On X11 we can paint to non Xlib surface only with HelperSurface
    3142                 : #if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6)
    3143                 :         // Don't use mHelperSurface if surface is image and mMaemoImageRendering is TRUE
    3144                 :         if (!mMaemoImageRendering ||
    3145                 :             renderSurface->GetType() != gfxASurface::SurfaceTypeImage)
    3146                 : #endif
    3147               0 :         renderSurface = mHelperSurface;
    3148                 :     }
    3149                 : #endif
    3150                 : 
    3151               0 :     if (mIsTransparent && !CanPaintOnBackground()) {
    3152                 :        // Clear surface content for transparent rendering
    3153               0 :        nsRefPtr<gfxContext> ctx = new gfxContext(renderSurface);
    3154               0 :        ctx->SetColor(aColor);
    3155               0 :        ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
    3156               0 :        ctx->Rectangle(GfxFromNsRect(plPaintRect));
    3157               0 :        ctx->Fill();
    3158                 :     }
    3159                 : 
    3160               0 :     PaintRectToPlatformSurface(plPaintRect, renderSurface);
    3161                 : 
    3162               0 :     if (renderSurface != aSurface) {
    3163                 :         // Copy helper surface content to target
    3164               0 :         nsRefPtr<gfxContext> ctx = new gfxContext(aSurface);
    3165               0 :         ctx->SetSource(renderSurface);
    3166               0 :         ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
    3167               0 :         ctx->Rectangle(GfxFromNsRect(aRect));
    3168               0 :         ctx->Fill();
    3169                 :     }
    3170               0 : }
    3171                 : 
    3172                 : void
    3173               0 : PluginInstanceChild::PaintRectWithAlphaExtraction(const nsIntRect& aRect,
    3174                 :                                                   gfxASurface* aSurface)
    3175                 : {
    3176               0 :     NS_ABORT_IF_FALSE(aSurface->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA,
    3177                 :                       "Refusing to pointlessly recover alpha");
    3178                 : 
    3179               0 :     nsIntRect rect(aRect);
    3180                 :     // If |aSurface| can be used to paint and can have alpha values
    3181                 :     // recovered directly to it, do that to save a tmp surface and
    3182                 :     // copy.
    3183               0 :     bool useSurfaceSubimageForBlack = false;
    3184               0 :     if (gfxASurface::SurfaceTypeImage == aSurface->GetType()) {
    3185                 :         gfxImageSurface* surfaceAsImage =
    3186               0 :             static_cast<gfxImageSurface*>(aSurface);
    3187                 :         useSurfaceSubimageForBlack =
    3188               0 :             (surfaceAsImage->Format() == gfxASurface::ImageFormatARGB32);
    3189                 :         // If we're going to use a subimage, nudge the rect so that we
    3190                 :         // can use optimal alpha recovery.  If we're not using a
    3191                 :         // subimage, the temporaries should automatically get
    3192                 :         // fast-path alpha recovery so we don't need to do anything.
    3193               0 :         if (useSurfaceSubimageForBlack) {
    3194                 :             rect =
    3195                 :                 gfxAlphaRecovery::AlignRectForSubimageRecovery(aRect,
    3196               0 :                                                                surfaceAsImage);
    3197                 :         }
    3198                 :     }
    3199                 : 
    3200               0 :     nsRefPtr<gfxImageSurface> whiteImage;
    3201               0 :     nsRefPtr<gfxImageSurface> blackImage;
    3202               0 :     gfxRect targetRect(rect.x, rect.y, rect.width, rect.height);
    3203               0 :     gfxIntSize targetSize(rect.width, rect.height);
    3204               0 :     gfxPoint deviceOffset = -targetRect.TopLeft();
    3205                 : 
    3206                 :     // We always use a temporary "white image"
    3207               0 :     whiteImage = new gfxImageSurface(targetSize, gfxASurface::ImageFormatRGB24);
    3208               0 :     if (whiteImage->CairoStatus()) {
    3209                 :         return;
    3210                 :     }
    3211                 : 
    3212                 : #ifdef XP_WIN
    3213                 :     // On windows, we need an HDC and so can't paint directly to
    3214                 :     // vanilla image surfaces.  Bifurcate this painting code so that
    3215                 :     // we don't accidentally attempt that.
    3216                 :     if (!SharedDIBSurface::IsSharedDIBSurface(aSurface))
    3217                 :         NS_RUNTIMEABORT("Expected SharedDIBSurface!");
    3218                 : 
    3219                 :     // Paint the plugin directly onto the target, with a white
    3220                 :     // background and copy the result
    3221                 :     PaintRectToSurface(rect, aSurface, gfxRGBA(1.0, 1.0, 1.0));
    3222                 :     {
    3223                 :         gfxRect copyRect(gfxPoint(0, 0), targetRect.Size());
    3224                 :         nsRefPtr<gfxContext> ctx = new gfxContext(whiteImage);
    3225                 :         ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
    3226                 :         ctx->SetSource(aSurface, deviceOffset);
    3227                 :         ctx->Rectangle(copyRect);
    3228                 :         ctx->Fill();
    3229                 :     }
    3230                 : 
    3231                 :     // Paint the plugin directly onto the target, with a black
    3232                 :     // background
    3233                 :     PaintRectToSurface(rect, aSurface, gfxRGBA(0.0, 0.0, 0.0));
    3234                 : 
    3235                 :     // Don't copy the result, just extract a subimage so that we can
    3236                 :     // recover alpha directly into the target
    3237                 :     gfxImageSurface *image = static_cast<gfxImageSurface*>(aSurface);
    3238                 :     blackImage = image->GetSubimage(targetRect);
    3239                 : 
    3240                 : #else
    3241                 :     // Paint onto white background
    3242               0 :     whiteImage->SetDeviceOffset(deviceOffset);
    3243               0 :     PaintRectToSurface(rect, whiteImage, gfxRGBA(1.0, 1.0, 1.0));
    3244                 : 
    3245               0 :     if (useSurfaceSubimageForBlack) {
    3246               0 :         gfxImageSurface *surface = static_cast<gfxImageSurface*>(aSurface);
    3247               0 :         blackImage = surface->GetSubimage(targetRect);
    3248                 :     } else {
    3249                 :         blackImage = new gfxImageSurface(targetSize,
    3250               0 :                                          gfxASurface::ImageFormatARGB32);
    3251                 :     }
    3252                 : 
    3253                 :     // Paint onto black background
    3254               0 :     blackImage->SetDeviceOffset(deviceOffset);
    3255               0 :     PaintRectToSurface(rect, blackImage, gfxRGBA(0.0, 0.0, 0.0));
    3256                 : #endif
    3257                 : 
    3258               0 :     NS_ABORT_IF_FALSE(whiteImage && blackImage, "Didn't paint enough!");
    3259                 : 
    3260                 :     // Extract alpha from black and white image and store to black
    3261                 :     // image
    3262               0 :     if (!gfxAlphaRecovery::RecoverAlpha(blackImage, whiteImage)) {
    3263                 :         return;
    3264                 :     }
    3265                 : 
    3266                 :     // If we had to use a temporary black surface, copy the pixels
    3267                 :     // with alpha back to the target
    3268               0 :     if (!useSurfaceSubimageForBlack) {
    3269               0 :         nsRefPtr<gfxContext> ctx = new gfxContext(aSurface);
    3270               0 :         ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
    3271               0 :         ctx->SetSource(blackImage);
    3272               0 :         ctx->Rectangle(targetRect);
    3273               0 :         ctx->Fill();
    3274                 :     }
    3275                 : }
    3276                 : 
    3277                 : bool
    3278               0 : PluginInstanceChild::CanPaintOnBackground()
    3279                 : {
    3280                 :     return (mBackground &&
    3281               0 :             mCurrentSurface &&
    3282               0 :             mCurrentSurface->GetSize() == mBackground->GetSize());
    3283                 : }
    3284                 : 
    3285                 : bool
    3286               0 : PluginInstanceChild::ShowPluginFrame()
    3287                 : {
    3288                 :     // mLayersRendering can be false if we somehow get here without
    3289                 :     // receiving AsyncSetWindow() first.  mPendingPluginCall is our
    3290                 :     // re-entrancy guard; we can't paint while nested inside another
    3291                 :     // paint.
    3292               0 :     if (!mLayersRendering || mPendingPluginCall) {
    3293               0 :         return false;
    3294                 :     }
    3295                 : 
    3296               0 :     AutoRestore<bool> pending(mPendingPluginCall);
    3297               0 :     mPendingPluginCall = true;
    3298                 : 
    3299               0 :     bool temporarilyMakeVisible = !IsVisible() && !mHasPainted;
    3300               0 :     if (temporarilyMakeVisible && mWindow.width && mWindow.height) {
    3301               0 :         mWindow.clipRect.right = mWindow.width;
    3302               0 :         mWindow.clipRect.bottom = mWindow.height;
    3303               0 :     } else if (!IsVisible()) {
    3304                 :         // If we're not visible, don't bother painting a <0,0,0,0>
    3305                 :         // rect.  If we're eventually made visible, the visibility
    3306                 :         // change will invalidate our window.
    3307               0 :         ClearCurrentSurface();
    3308               0 :         return true;
    3309                 :     }
    3310                 : 
    3311               0 :     if (!EnsureCurrentBuffer()) {
    3312               0 :         return false;
    3313                 :     }
    3314                 : 
    3315                 : #ifdef MOZ_WIDGET_COCOA
    3316                 :     // We can't use the thebes code with CoreAnimation so we will
    3317                 :     // take a different code path.
    3318                 :     if (mDrawingModel == NPDrawingModelCoreAnimation ||
    3319                 :         mDrawingModel == NPDrawingModelInvalidatingCoreAnimation ||
    3320                 :         mDrawingModel == NPDrawingModelCoreGraphics) {
    3321                 : 
    3322                 :         if (!IsVisible()) {
    3323                 :             return true;
    3324                 :         }
    3325                 : 
    3326                 :         if (!mDoubleBufferCARenderer.HasFrontSurface()) {
    3327                 :             NS_ERROR("CARenderer not initialized for rendering");
    3328                 :             return false;
    3329                 :         }
    3330                 : 
    3331                 :         // Clear accRect here to be able to pass
    3332                 :         // test_invalidate_during_plugin_paint  test
    3333                 :         nsIntRect rect = mAccumulatedInvalidRect;
    3334                 :         mAccumulatedInvalidRect.SetEmpty();
    3335                 : 
    3336                 :         // Fix up old invalidations that might have been made when our
    3337                 :         // surface was a different size
    3338                 :         rect.IntersectRect(rect,
    3339                 :                           nsIntRect(0, 0, 
    3340                 :                           mDoubleBufferCARenderer.GetFrontSurfaceWidth(), 
    3341                 :                           mDoubleBufferCARenderer.GetFrontSurfaceHeight()));
    3342                 : 
    3343                 :         if (mDrawingModel == NPDrawingModelCoreGraphics) {
    3344                 :             mozilla::plugins::PluginUtilsOSX::Repaint(mCGLayer, rect);
    3345                 :         }
    3346                 : 
    3347                 :         mDoubleBufferCARenderer.Render();
    3348                 : 
    3349                 :         NPRect r = { (uint16_t)rect.y, (uint16_t)rect.x,
    3350                 :                      (uint16_t)rect.YMost(), (uint16_t)rect.XMost() };
    3351                 :         SurfaceDescriptor currSurf;
    3352                 :         currSurf = IOSurfaceDescriptor(mDoubleBufferCARenderer.GetFrontSurfaceID());
    3353                 : 
    3354                 :         mHasPainted = true;
    3355                 : 
    3356                 :         SurfaceDescriptor returnSurf;
    3357                 : 
    3358                 :         if (!SendShow(r, currSurf, &returnSurf)) {
    3359                 :             return false;
    3360                 :         }
    3361                 : 
    3362                 :         SwapSurfaces();
    3363                 :         return true;
    3364                 :     } else {
    3365                 :         NS_ERROR("Unsupported drawing model for async layer rendering");
    3366                 :         return false;
    3367                 :     }
    3368                 : #endif
    3369                 : 
    3370               0 :     NS_ASSERTION(mWindow.width == (mWindow.clipRect.right - mWindow.clipRect.left) &&
    3371                 :                  mWindow.height == (mWindow.clipRect.bottom - mWindow.clipRect.top),
    3372                 :                  "Clip rect should be same size as window when using layers");
    3373                 : 
    3374                 :     // Clear accRect here to be able to pass
    3375                 :     // test_invalidate_during_plugin_paint  test
    3376               0 :     nsIntRect rect = mAccumulatedInvalidRect;
    3377               0 :     mAccumulatedInvalidRect.SetEmpty();
    3378                 : 
    3379                 :     // Fix up old invalidations that might have been made when our
    3380                 :     // surface was a different size
    3381               0 :     gfxIntSize surfaceSize = mCurrentSurface->GetSize();
    3382                 :     rect.IntersectRect(rect,
    3383               0 :                        nsIntRect(0, 0, surfaceSize.width, surfaceSize.height));
    3384                 : 
    3385               0 :     if (!ReadbackDifferenceRect(rect)) {
    3386                 :         // We couldn't read back the pixels that differ between the
    3387                 :         // current surface and last, so we have to invalidate the
    3388                 :         // entire window.
    3389               0 :         rect.SetRect(0, 0, mWindow.width, mWindow.height);
    3390                 :     }
    3391                 : 
    3392                 :     bool haveTransparentPixels =
    3393               0 :         gfxASurface::CONTENT_COLOR_ALPHA == mCurrentSurface->GetContentType();
    3394               0 :     PLUGIN_LOG_DEBUG(
    3395                 :         ("[InstanceChild][%p] Painting%s <x=%d,y=%d, w=%d,h=%d> on surface <w=%d,h=%d>",
    3396                 :          this, haveTransparentPixels ? " with alpha" : "",
    3397                 :          rect.x, rect.y, rect.width, rect.height,
    3398                 :          mCurrentSurface->GetSize().width, mCurrentSurface->GetSize().height));
    3399                 : 
    3400               0 :     if (CanPaintOnBackground()) {
    3401               0 :         PLUGIN_LOG_DEBUG(("  (on background)"));
    3402                 :         // Source the background pixels ...
    3403                 :         {
    3404                 :             nsRefPtr<gfxContext> ctx =
    3405               0 :                 new gfxContext(mHelperSurface ? mHelperSurface : mCurrentSurface);
    3406               0 :             ctx->SetSource(mBackground);
    3407               0 :             ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
    3408               0 :             ctx->Rectangle(gfxRect(rect.x, rect.y, rect.width, rect.height));
    3409               0 :             ctx->Fill();
    3410                 :         }
    3411                 :         // ... and hand off to the plugin
    3412                 :         // BEWARE: mBackground may die during this call
    3413               0 :         PaintRectToSurface(rect, mCurrentSurface, gfxRGBA(0.0, 0.0, 0.0, 0.0));
    3414               0 :     } else if (!temporarilyMakeVisible && mDoAlphaExtraction) {
    3415                 :         // We don't want to pay the expense of alpha extraction for
    3416                 :         // phony paints.
    3417               0 :         PLUGIN_LOG_DEBUG(("  (with alpha recovery)"));
    3418               0 :         PaintRectWithAlphaExtraction(rect, mCurrentSurface);
    3419                 :     } else {
    3420               0 :         PLUGIN_LOG_DEBUG(("  (onto opaque surface)"));
    3421                 : 
    3422                 :         // If we're on a platform that needs helper surfaces for
    3423                 :         // plugins, and we're forcing a throwaway paint of a
    3424                 :         // wmode=transparent plugin, then make sure to use the helper
    3425                 :         // surface here.
    3426                 :         nsRefPtr<gfxASurface> target =
    3427               0 :             (temporarilyMakeVisible && mHelperSurface) ?
    3428               0 :             mHelperSurface : mCurrentSurface;
    3429                 : 
    3430               0 :         PaintRectToSurface(rect, target, gfxRGBA(0.0, 0.0, 0.0, 0.0));
    3431                 :     }
    3432               0 :     mHasPainted = true;
    3433                 : 
    3434               0 :     if (temporarilyMakeVisible) {
    3435               0 :         mWindow.clipRect.right = mWindow.clipRect.bottom = 0;
    3436                 : 
    3437               0 :         PLUGIN_LOG_DEBUG(
    3438                 :             ("[InstanceChild][%p] Undoing temporary clipping w=<x=%d,y=%d, w=%d,h=%d>, clip=<l=%d,t=%d,r=%d,b=%d>",
    3439                 :              this, mWindow.x, mWindow.y, mWindow.width, mWindow.height,
    3440                 :              mWindow.clipRect.left, mWindow.clipRect.top, mWindow.clipRect.right, mWindow.clipRect.bottom));
    3441                 : 
    3442               0 :         if (mPluginIface->setwindow) {
    3443               0 :             mPluginIface->setwindow(&mData, &mWindow);
    3444                 :         }
    3445                 : 
    3446                 :         // Skip forwarding the results of the phony paint to the
    3447                 :         // browser.  We may have painted a transparent plugin using
    3448                 :         // the opaque-plugin path, which can result in wrong pixels.
    3449                 :         // We also don't want to pay the expense of forwarding the
    3450                 :         // surface for plugins that might really be invisible.
    3451               0 :         mAccumulatedInvalidRect.SetRect(0, 0, mWindow.width, mWindow.height);
    3452               0 :         return true;
    3453                 :     }
    3454                 : 
    3455                 :     NPRect r = { (uint16_t)rect.y, (uint16_t)rect.x,
    3456               0 :                  (uint16_t)rect.YMost(), (uint16_t)rect.XMost() };
    3457               0 :     SurfaceDescriptor currSurf;
    3458                 : #ifdef MOZ_X11
    3459               0 :     if (mCurrentSurface->GetType() == gfxASurface::SurfaceTypeXlib) {
    3460               0 :         gfxXlibSurface *xsurf = static_cast<gfxXlibSurface*>(mCurrentSurface.get());
    3461               0 :         currSurf = SurfaceDescriptorX11(xsurf);
    3462                 :         // Need to sync all pending x-paint requests
    3463                 :         // before giving drawable to another process
    3464               0 :         XSync(mWsInfo.display, False);
    3465                 :     } else
    3466                 : #endif
    3467                 : #ifdef XP_WIN
    3468                 :     if (SharedDIBSurface::IsSharedDIBSurface(mCurrentSurface)) {
    3469                 :         SharedDIBSurface* s = static_cast<SharedDIBSurface*>(mCurrentSurface.get());
    3470                 :         if (!mCurrentSurfaceActor) {
    3471                 :             base::SharedMemoryHandle handle = NULL;
    3472                 :             s->ShareToProcess(PluginModuleChild::current()->OtherProcess(), &handle);
    3473                 : 
    3474                 :             mCurrentSurfaceActor =
    3475                 :                 SendPPluginSurfaceConstructor(handle,
    3476                 :                                               mCurrentSurface->GetSize(),
    3477                 :                                               haveTransparentPixels);
    3478                 :         }
    3479                 :         currSurf = mCurrentSurfaceActor;
    3480                 :         s->Flush();
    3481                 :     } else
    3482                 : #endif
    3483               0 :     if (gfxSharedImageSurface::IsSharedImage(mCurrentSurface)) {
    3484               0 :         currSurf = static_cast<gfxSharedImageSurface*>(mCurrentSurface.get())->GetShmem();
    3485                 :     } else {
    3486               0 :         NS_RUNTIMEABORT("Surface type is not remotable");
    3487               0 :         return false;
    3488                 :     }
    3489                 : 
    3490                 :     // Unused, except to possibly return a shmem to us
    3491               0 :     SurfaceDescriptor returnSurf;
    3492                 : 
    3493               0 :     if (!SendShow(r, currSurf, &returnSurf)) {
    3494               0 :         return false;
    3495                 :     }
    3496                 : 
    3497               0 :     SwapSurfaces();
    3498               0 :     mSurfaceDifferenceRect = rect;
    3499               0 :     return true;
    3500                 : }
    3501                 : 
    3502                 : bool
    3503               0 : PluginInstanceChild::ReadbackDifferenceRect(const nsIntRect& rect)
    3504                 : {
    3505               0 :     if (!mBackSurface)
    3506               0 :         return false;
    3507                 : 
    3508                 :     // We can read safely from XSurface,SharedDIBSurface and Unsafe SharedMemory,
    3509                 :     // because PluginHost is not able to modify that surface
    3510                 : #if defined(MOZ_X11)
    3511               0 :     if (mBackSurface->GetType() != gfxASurface::SurfaceTypeXlib &&
    3512               0 :         !gfxSharedImageSurface::IsSharedImage(mBackSurface))
    3513               0 :         return false;
    3514                 : #elif defined(XP_WIN)
    3515                 :     if (!SharedDIBSurface::IsSharedDIBSurface(mBackSurface))
    3516                 :         return false;
    3517                 : #else
    3518                 :     return false;
    3519                 : #endif
    3520                 : 
    3521               0 :     if (mCurrentSurface->GetContentType() != mBackSurface->GetContentType())
    3522               0 :         return false;
    3523                 : 
    3524               0 :     if (mSurfaceDifferenceRect.IsEmpty())
    3525               0 :         return true;
    3526                 : 
    3527               0 :     PLUGIN_LOG_DEBUG(
    3528                 :         ("[InstanceChild][%p] Reading back part of <x=%d,y=%d, w=%d,h=%d>",
    3529                 :          this, mSurfaceDifferenceRect.x, mSurfaceDifferenceRect.y,
    3530                 :          mSurfaceDifferenceRect.width, mSurfaceDifferenceRect.height));
    3531                 : 
    3532                 :     // Read back previous content
    3533               0 :     nsRefPtr<gfxContext> ctx = new gfxContext(mCurrentSurface);
    3534               0 :     ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
    3535               0 :     ctx->SetSource(mBackSurface);
    3536                 :     // Subtract from mSurfaceDifferenceRect area which is overlapping with rect
    3537               0 :     nsIntRegion result;
    3538               0 :     result.Sub(mSurfaceDifferenceRect, nsIntRegion(rect));
    3539               0 :     nsIntRegionRectIterator iter(result);
    3540                 :     const nsIntRect* r;
    3541               0 :     while ((r = iter.Next()) != nsnull) {
    3542               0 :         ctx->Rectangle(GfxFromNsRect(*r));
    3543                 :     }
    3544               0 :     ctx->Fill();
    3545                 : 
    3546               0 :     return true;
    3547                 : }
    3548                 : 
    3549                 : void
    3550               0 : PluginInstanceChild::InvalidateRectDelayed(void)
    3551                 : {
    3552               0 :     if (!mCurrentInvalidateTask) {
    3553               0 :         return;
    3554                 :     }
    3555                 : 
    3556               0 :     mCurrentInvalidateTask = nsnull;
    3557               0 :     if (mAccumulatedInvalidRect.IsEmpty()) {
    3558               0 :         return;
    3559                 :     }
    3560                 : 
    3561               0 :     if (!ShowPluginFrame()) {
    3562               0 :         AsyncShowPluginFrame();
    3563                 :     }
    3564                 : }
    3565                 : 
    3566                 : void
    3567               0 : PluginInstanceChild::AsyncShowPluginFrame(void)
    3568                 : {
    3569               0 :     if (mCurrentInvalidateTask) {
    3570               0 :         return;
    3571                 :     }
    3572                 : 
    3573                 :     mCurrentInvalidateTask =
    3574               0 :         NewRunnableMethod(this, &PluginInstanceChild::InvalidateRectDelayed);
    3575               0 :     MessageLoop::current()->PostTask(FROM_HERE, mCurrentInvalidateTask);
    3576                 : }
    3577                 : 
    3578                 : void
    3579               0 : PluginInstanceChild::InvalidateRect(NPRect* aInvalidRect)
    3580                 : {
    3581               0 :     NS_ASSERTION(aInvalidRect, "Null pointer!");
    3582                 : 
    3583                 : #ifdef OS_WIN
    3584                 :     // Invalidate and draw locally for windowed plugins.
    3585                 :     if (mWindow.type == NPWindowTypeWindow) {
    3586                 :       NS_ASSERTION(IsWindow(mPluginWindowHWND), "Bad window?!");
    3587                 :       RECT rect = { aInvalidRect->left, aInvalidRect->top,
    3588                 :                     aInvalidRect->right, aInvalidRect->bottom };
    3589                 :       ::InvalidateRect(mPluginWindowHWND, &rect, FALSE);
    3590                 :       return;
    3591                 :     }
    3592                 : #endif
    3593                 : 
    3594               0 :     if (mLayersRendering) {
    3595                 :         nsIntRect r(aInvalidRect->left, aInvalidRect->top,
    3596                 :                     aInvalidRect->right - aInvalidRect->left,
    3597               0 :                     aInvalidRect->bottom - aInvalidRect->top);
    3598                 : 
    3599               0 :         mAccumulatedInvalidRect.UnionRect(r, mAccumulatedInvalidRect);
    3600                 :         // If we are able to paint and invalidate sent, then reset
    3601                 :         // accumulated rectangle
    3602               0 :         AsyncShowPluginFrame();
    3603               0 :         return;
    3604                 :     }
    3605                 : 
    3606                 :     // If we were going to use layers rendering but it's not set up
    3607                 :     // yet, and the plugin happens to call this first, we'll forward
    3608                 :     // the invalidation to the browser.  It's unclear whether
    3609                 :     // non-layers plugins need this rect forwarded when their window
    3610                 :     // width or height is 0, which it would be for layers plugins
    3611                 :     // before their first SetWindow().
    3612               0 :     SendNPN_InvalidateRect(*aInvalidRect);
    3613                 : }
    3614                 : 
    3615                 : bool
    3616               0 : PluginInstanceChild::RecvUpdateBackground(const SurfaceDescriptor& aBackground,
    3617                 :                                           const nsIntRect& aRect)
    3618                 : {
    3619               0 :     NS_ABORT_IF_FALSE(mIsTransparent, "Only transparent plugins use backgrounds");
    3620                 : 
    3621               0 :     if (!mBackground) {
    3622                 :         // XXX refactor me
    3623               0 :         switch (aBackground.type()) {
    3624                 : #ifdef MOZ_X11
    3625                 :         case SurfaceDescriptor::TSurfaceDescriptorX11: {
    3626               0 :             mBackground = aBackground.get_SurfaceDescriptorX11().OpenForeign();
    3627               0 :             break;
    3628                 :         }
    3629                 : #endif
    3630                 :         case SurfaceDescriptor::TShmem: {
    3631               0 :             mBackground = gfxSharedImageSurface::Open(aBackground.get_Shmem());
    3632               0 :             break;
    3633                 :         }
    3634                 :         default:
    3635               0 :             NS_RUNTIMEABORT("Unexpected background surface descriptor");
    3636                 :         }
    3637                 : 
    3638               0 :         if (!mBackground) {
    3639               0 :             return false;
    3640                 :         }
    3641                 : 
    3642               0 :         gfxIntSize bgSize = mBackground->GetSize();
    3643                 :         mAccumulatedInvalidRect.UnionRect(mAccumulatedInvalidRect,
    3644               0 :                                           nsIntRect(0, 0, bgSize.width, bgSize.height));
    3645               0 :         AsyncShowPluginFrame();
    3646               0 :         return true;
    3647                 :     }
    3648                 : 
    3649                 :     // XXX refactor me
    3650               0 :     mAccumulatedInvalidRect.UnionRect(aRect, mAccumulatedInvalidRect);
    3651                 : 
    3652                 :     // The browser is limping along with a stale copy of our pixels.
    3653                 :     // Try to repaint ASAP.  This will ClearCurrentBackground() if we
    3654                 :     // needed it.
    3655               0 :     if (!ShowPluginFrame()) {
    3656               0 :         NS_WARNING("Couldn't immediately repaint plugin instance");
    3657               0 :         AsyncShowPluginFrame();
    3658                 :     }
    3659                 : 
    3660               0 :     return true;
    3661                 : }
    3662                 : 
    3663                 : PPluginBackgroundDestroyerChild*
    3664               0 : PluginInstanceChild::AllocPPluginBackgroundDestroyer()
    3665                 : {
    3666               0 :     return new PluginBackgroundDestroyerChild();
    3667                 : }
    3668                 : 
    3669                 : bool
    3670               0 : PluginInstanceChild::RecvPPluginBackgroundDestroyerConstructor(
    3671                 :     PPluginBackgroundDestroyerChild* aActor)
    3672                 : {
    3673                 :     // Our background changed, so we have to invalidate the area
    3674                 :     // painted with the old background.  If the background was
    3675                 :     // destroyed because we have a new background, then we expect to
    3676                 :     // be notified of that "soon", before processing the asynchronous
    3677                 :     // invalidation here.  If we're *not* getting a new background,
    3678                 :     // our current front surface is stale and we want to repaint
    3679                 :     // "soon" so that we can hand the browser back a surface with
    3680                 :     // alpha values.  (We should be notified of that invalidation soon
    3681                 :     // too, but we don't assume that here.)
    3682               0 :     if (mBackground) {
    3683               0 :         gfxIntSize bgsize = mBackground->GetSize();
    3684                 :         mAccumulatedInvalidRect.UnionRect(
    3685               0 :             nsIntRect(0, 0, bgsize.width, bgsize.height), mAccumulatedInvalidRect);
    3686                 : 
    3687                 :         // NB: we don't have to XSync here because only ShowPluginFrame()
    3688                 :         // uses mBackground, and it always XSyncs after finishing.
    3689               0 :         mBackground = nsnull;
    3690               0 :         AsyncShowPluginFrame();
    3691                 :     }
    3692                 : 
    3693               0 :     return PPluginBackgroundDestroyerChild::Send__delete__(aActor);
    3694                 : }
    3695                 : 
    3696                 : bool
    3697               0 : PluginInstanceChild::DeallocPPluginBackgroundDestroyer(
    3698                 :     PPluginBackgroundDestroyerChild* aActor)
    3699                 : {
    3700               0 :     delete aActor;
    3701               0 :     return true;
    3702                 : }
    3703                 : 
    3704                 : uint32_t
    3705               0 : PluginInstanceChild::ScheduleTimer(uint32_t interval, bool repeat,
    3706                 :                                    TimerFunc func)
    3707                 : {
    3708               0 :     ChildTimer* t = new ChildTimer(this, interval, repeat, func);
    3709               0 :     if (0 == t->ID()) {
    3710               0 :         delete t;
    3711               0 :         return 0;
    3712                 :     }
    3713                 : 
    3714               0 :     mTimers.AppendElement(t);
    3715               0 :     return t->ID();
    3716                 : }
    3717                 : 
    3718                 : void
    3719               0 : PluginInstanceChild::UnscheduleTimer(uint32_t id)
    3720                 : {
    3721               0 :     if (0 == id)
    3722               0 :         return;
    3723                 : 
    3724               0 :     mTimers.RemoveElement(id, ChildTimer::IDComparator());
    3725                 : }
    3726                 : 
    3727                 : void
    3728               0 : PluginInstanceChild::AsyncCall(PluginThreadCallback aFunc, void* aUserData)
    3729                 : {
    3730               0 :     ChildAsyncCall* task = new ChildAsyncCall(this, aFunc, aUserData);
    3731                 : 
    3732                 :     {
    3733               0 :         MutexAutoLock lock(mAsyncCallMutex);
    3734               0 :         mPendingAsyncCalls.AppendElement(task);
    3735                 :     }
    3736               0 :     ProcessChild::message_loop()->PostTask(FROM_HERE, task);
    3737               0 : }
    3738                 : 
    3739                 : static PLDHashOperator
    3740               0 : InvalidateObject(DeletingObjectEntry* e, void* userArg)
    3741                 : {
    3742               0 :     NPObject* o = e->GetKey();
    3743               0 :     if (!e->mDeleted && o->_class && o->_class->invalidate)
    3744               0 :         o->_class->invalidate(o);
    3745                 : 
    3746               0 :     return PL_DHASH_NEXT;
    3747                 : }
    3748                 : 
    3749                 : static PLDHashOperator
    3750               0 : DeleteObject(DeletingObjectEntry* e, void* userArg)
    3751                 : {
    3752               0 :     NPObject* o = e->GetKey();
    3753               0 :     if (!e->mDeleted) {
    3754               0 :         e->mDeleted = true;
    3755                 : 
    3756                 : #ifdef NS_BUILD_REFCNT_LOGGING
    3757                 :         {
    3758               0 :             int32_t refcnt = o->referenceCount;
    3759               0 :             while (refcnt) {
    3760               0 :                 --refcnt;
    3761               0 :                 NS_LOG_RELEASE(o, refcnt, "NPObject");
    3762                 :             }
    3763                 :         }
    3764                 : #endif
    3765                 : 
    3766               0 :         PluginModuleChild::DeallocNPObject(o);
    3767                 :     }
    3768                 : 
    3769               0 :     return PL_DHASH_NEXT;
    3770                 : }
    3771                 : 
    3772                 : void
    3773               0 : PluginInstanceChild::SwapSurfaces()
    3774                 : {
    3775               0 :     nsRefPtr<gfxASurface> tmpsurf = mCurrentSurface;
    3776                 : #ifdef XP_WIN
    3777                 :     PPluginSurfaceChild* tmpactor = mCurrentSurfaceActor;
    3778                 : #endif
    3779                 : 
    3780               0 :     mCurrentSurface = mBackSurface;
    3781                 : #ifdef XP_WIN
    3782                 :     mCurrentSurfaceActor = mBackSurfaceActor;
    3783                 : #endif
    3784                 : 
    3785               0 :     mBackSurface = tmpsurf;
    3786                 : #ifdef XP_WIN
    3787                 :     mBackSurfaceActor = tmpactor;
    3788                 : #endif
    3789                 : 
    3790                 : #ifdef MOZ_WIDGET_COCOA
    3791                 :     mDoubleBufferCARenderer.SwapSurfaces();
    3792                 : 
    3793                 :     // Outdated back surface... not usable anymore due to changed plugin size.
    3794                 :     // Dropping obsolete surface
    3795                 :     if (mDoubleBufferCARenderer.HasFrontSurface() && 
    3796                 :         mDoubleBufferCARenderer.HasBackSurface() &&
    3797                 :         (mDoubleBufferCARenderer.GetFrontSurfaceWidth() != 
    3798                 :             mDoubleBufferCARenderer.GetBackSurfaceWidth() ||
    3799                 :         mDoubleBufferCARenderer.GetFrontSurfaceHeight() != 
    3800                 :             mDoubleBufferCARenderer.GetBackSurfaceHeight())) {
    3801                 : 
    3802                 :         mDoubleBufferCARenderer.ClearFrontSurface();
    3803                 :     }
    3804                 : #else
    3805               0 :     if (mCurrentSurface && mBackSurface &&
    3806               0 :         (mCurrentSurface->GetSize() != mBackSurface->GetSize() ||
    3807               0 :          mCurrentSurface->GetContentType() != mBackSurface->GetContentType())) {
    3808               0 :         ClearCurrentSurface();
    3809                 :     }
    3810                 : #endif
    3811               0 : }
    3812                 : 
    3813                 : void
    3814               0 : PluginInstanceChild::ClearCurrentSurface()
    3815                 : {
    3816               0 :     mCurrentSurface = nsnull;
    3817                 : #ifdef MOZ_WIDGET_COCOA
    3818                 :     if (mDoubleBufferCARenderer.HasFrontSurface()) {
    3819                 :         mDoubleBufferCARenderer.ClearFrontSurface();
    3820                 :     }
    3821                 : #endif
    3822                 : #ifdef XP_WIN
    3823                 :     if (mCurrentSurfaceActor) {
    3824                 :         PPluginSurfaceChild::Send__delete__(mCurrentSurfaceActor);
    3825                 :         mCurrentSurfaceActor = NULL;
    3826                 :     }
    3827                 : #endif
    3828               0 :     mHelperSurface = nsnull;
    3829               0 : }
    3830                 : 
    3831                 : void
    3832               0 : PluginInstanceChild::ClearAllSurfaces()
    3833                 : {
    3834               0 :     if (mBackSurface) {
    3835                 :         // Get last surface back, and drop it
    3836               0 :         SurfaceDescriptor temp = null_t();
    3837               0 :         NPRect r = { 0, 0, 1, 1 };
    3838               0 :         SendShow(r, temp, &temp);
    3839                 :     }
    3840                 : 
    3841               0 :     if (gfxSharedImageSurface::IsSharedImage(mCurrentSurface))
    3842               0 :         DeallocShmem(static_cast<gfxSharedImageSurface*>(mCurrentSurface.get())->GetShmem());
    3843               0 :     if (gfxSharedImageSurface::IsSharedImage(mBackSurface))
    3844               0 :         DeallocShmem(static_cast<gfxSharedImageSurface*>(mBackSurface.get())->GetShmem());
    3845               0 :     mCurrentSurface = nsnull;
    3846               0 :     mBackSurface = nsnull;
    3847                 : 
    3848                 : #ifdef XP_WIN
    3849                 :     if (mCurrentSurfaceActor) {
    3850                 :         PPluginSurfaceChild::Send__delete__(mCurrentSurfaceActor);
    3851                 :         mCurrentSurfaceActor = NULL;
    3852                 :     }
    3853                 :     if (mBackSurfaceActor) {
    3854                 :         PPluginSurfaceChild::Send__delete__(mBackSurfaceActor);
    3855                 :         mBackSurfaceActor = NULL;
    3856                 :     }
    3857                 : #endif
    3858                 : 
    3859                 : #ifdef MOZ_WIDGET_COCOA
    3860                 :     if (mDoubleBufferCARenderer.HasBackSurface()) {
    3861                 :         // Get last surface back, and drop it
    3862                 :         SurfaceDescriptor temp = null_t();
    3863                 :         NPRect r = { 0, 0, 1, 1 };
    3864                 :         SendShow(r, temp, &temp);
    3865                 :     }
    3866                 : 
    3867                 :     if (mCGLayer) {
    3868                 :         mozilla::plugins::PluginUtilsOSX::ReleaseCGLayer(mCGLayer);
    3869                 :         mCGLayer = nsnull;
    3870                 :     }
    3871                 : 
    3872                 :     mDoubleBufferCARenderer.ClearFrontSurface();
    3873                 :     mDoubleBufferCARenderer.ClearBackSurface();
    3874                 : #endif
    3875               0 : }
    3876                 : 
    3877                 : PLDHashOperator
    3878               0 : PluginInstanceChild::DeleteSurface(NPAsyncSurface* surf, nsAutoPtr<AsyncBitmapData> &data, void* userArg)
    3879                 : {
    3880               0 :     PluginInstanceChild *inst = static_cast<PluginInstanceChild*>(userArg);
    3881                 : 
    3882               0 :     inst->DeallocShmem(data->mShmem);
    3883                 : 
    3884               0 :     return PL_DHASH_REMOVE;
    3885                 : }
    3886                 : 
    3887                 : bool
    3888               0 : PluginInstanceChild::AnswerNPP_Destroy(NPError* aResult)
    3889                 : {
    3890               0 :     PLUGIN_LOG_DEBUG_METHOD;
    3891               0 :     AssertPluginThread();
    3892               0 :     *aResult = NPERR_NO_ERROR;
    3893                 : 
    3894                 : #if defined(OS_WIN)
    3895                 :     SetProp(mPluginWindowHWND, kPluginIgnoreSubclassProperty, (HANDLE)1);
    3896                 : #endif
    3897                 : 
    3898               0 :     InfallibleTArray<PBrowserStreamChild*> streams;
    3899               0 :     ManagedPBrowserStreamChild(streams);
    3900                 : 
    3901                 :     // First make sure none of these streams become deleted
    3902               0 :     for (PRUint32 i = 0; i < streams.Length(); ) {
    3903               0 :         if (static_cast<BrowserStreamChild*>(streams[i])->InstanceDying())
    3904               0 :             ++i;
    3905                 :         else
    3906               0 :             streams.RemoveElementAt(i);
    3907                 :     }
    3908               0 :     for (PRUint32 i = 0; i < streams.Length(); ++i)
    3909               0 :         static_cast<BrowserStreamChild*>(streams[i])->FinishDelivery();
    3910                 : 
    3911               0 :     mTimers.Clear();
    3912                 : 
    3913                 :     // NPP_Destroy() should be a synchronization point for plugin threads
    3914                 :     // calling NPN_AsyncCall: after this function returns, they are no longer
    3915                 :     // allowed to make async calls on this instance.
    3916               0 :     PluginModuleChild::current()->NPP_Destroy(this);
    3917               0 :     mData.ndata = 0;
    3918                 : 
    3919               0 :     if (mCurrentInvalidateTask) {
    3920               0 :         mCurrentInvalidateTask->Cancel();
    3921               0 :         mCurrentInvalidateTask = nsnull;
    3922                 :     }
    3923               0 :     if (mCurrentAsyncSetWindowTask) {
    3924               0 :         mCurrentAsyncSetWindowTask->Cancel();
    3925               0 :         mCurrentAsyncSetWindowTask = nsnull;
    3926                 :     }
    3927                 :     {
    3928               0 :         MutexAutoLock autoLock(mAsyncInvalidateMutex);
    3929               0 :         if (mAsyncInvalidateTask) {
    3930               0 :             mAsyncInvalidateTask->Cancel();
    3931               0 :             mAsyncInvalidateTask = nsnull;
    3932                 :         }
    3933                 :     }
    3934                 : 
    3935               0 :     ClearAllSurfaces();
    3936                 : 
    3937               0 :     mDeletingHash = new nsTHashtable<DeletingObjectEntry>;
    3938               0 :     mDeletingHash->Init();
    3939               0 :     PluginModuleChild::current()->FindNPObjectsForInstance(this);
    3940                 : 
    3941               0 :     mDeletingHash->EnumerateEntries(InvalidateObject, NULL);
    3942               0 :     mDeletingHash->EnumerateEntries(DeleteObject, NULL);
    3943                 : 
    3944                 :     // Null out our cached actors as they should have been killed in the
    3945                 :     // PluginInstanceDestroyed call above.
    3946               0 :     mCachedWindowActor = nsnull;
    3947               0 :     mCachedElementActor = nsnull;
    3948                 : 
    3949                 : #if defined(OS_WIN)
    3950                 :     SharedSurfaceRelease();
    3951                 :     DestroyWinlessPopupSurrogate();
    3952                 :     UnhookWinlessFlashThrottle();
    3953                 :     DestroyPluginWindow();
    3954                 : #endif
    3955                 : 
    3956                 :     // Pending async calls are discarded, not delivered. This matches the
    3957                 :     // in-process behavior.
    3958               0 :     for (PRUint32 i = 0; i < mPendingAsyncCalls.Length(); ++i)
    3959               0 :         mPendingAsyncCalls[i]->Cancel();
    3960                 : 
    3961               0 :     mPendingAsyncCalls.Clear();
    3962                 :     
    3963               0 :     if (mAsyncBitmaps.Count()) {
    3964               0 :         NS_ERROR("Not all AsyncBitmaps were finalized by a plugin!");
    3965               0 :         mAsyncBitmaps.Enumerate(DeleteSurface, this);
    3966                 :     }
    3967                 : 
    3968               0 :     return true;
    3969                 : }

Generated by: LCOV version 1.7