LCOV - app.info - dom/plugins/ipc/PluginInstanceChild.cpp

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-07-07 | 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