1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 // vim:set ts=2 sts=2 sw=2 et cin: 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef nsPluginInstanceOwner_h_ 8 #define nsPluginInstanceOwner_h_ 9 10 #include "mozilla/Attributes.h" 11 #include "mozilla/StaticPtr.h" 12 #include "npapi.h" 13 #include "nsCOMPtr.h" 14 #include "nsIKeyEventInPluginCallback.h" 15 #include "nsIPluginInstanceOwner.h" 16 #include "nsIPrivacyTransitionObserver.h" 17 #include "nsIDOMEventListener.h" 18 #include "nsPluginHost.h" 19 #include "nsPluginNativeWindow.h" 20 #include "nsWeakReference.h" 21 #include "gfxRect.h" 22 23 #ifdef XP_MACOSX 24 #include "mozilla/gfx/QuartzSupport.h" 25 #include <ApplicationServices/ApplicationServices.h> 26 #endif 27 28 class nsIInputStream; 29 class nsPluginDOMContextMenuListener; 30 class nsPluginFrame; 31 class nsDisplayListBuilder; 32 33 #if defined(MOZ_X11) 34 class gfxContext; 35 #endif 36 37 namespace mozilla { 38 class TextComposition; 39 namespace dom { 40 struct MozPluginParameter; 41 } // namespace dom 42 namespace widget { 43 class PuppetWidget; 44 } // namespace widget 45 } // namespace mozilla 46 47 using mozilla::widget::PuppetWidget; 48 49 #ifdef MOZ_X11 50 #include "gfxXlibNativeRenderer.h" 51 #endif 52 53 class nsPluginInstanceOwner final : public nsIPluginInstanceOwner, 54 public nsIDOMEventListener, 55 public nsIPrivacyTransitionObserver, 56 public nsIKeyEventInPluginCallback, 57 public nsSupportsWeakReference { 58 public: 59 typedef mozilla::gfx::DrawTarget DrawTarget; 60 61 nsPluginInstanceOwner(); 62 63 NS_DECL_ISUPPORTS 64 NS_DECL_NSIPLUGININSTANCEOWNER 65 NS_DECL_NSIPRIVACYTRANSITIONOBSERVER 66 67 NS_IMETHOD GetURL(const char* aURL, const char* aTarget, 68 nsIInputStream* aPostStream, void* aHeadersData, 69 uint32_t aHeadersDataLen, 70 bool aDoCheckLoadURIChecks) override; 71 72 NPBool ConvertPoint(double sourceX, double sourceY, 73 NPCoordinateSpace sourceSpace, double* destX, 74 double* destY, NPCoordinateSpace destSpace) override; 75 76 NPError InitAsyncSurface(NPSize* size, NPImageFormat format, void* initData, 77 NPAsyncSurface* surface) override; 78 NPError FinalizeAsyncSurface(NPAsyncSurface* surface) override; 79 void SetCurrentAsyncSurface(NPAsyncSurface* surface, 80 NPRect* changed) override; 81 82 /** 83 * Get the type of the HTML tag that was used ot instantiate this 84 * plugin. Currently supported tags are EMBED or OBJECT. 85 */ 86 NS_IMETHOD GetTagType(nsPluginTagType* aResult); 87 88 void GetParameters(nsTArray<mozilla::dom::MozPluginParameter>& parameters); 89 void GetAttributes(nsTArray<mozilla::dom::MozPluginParameter>& attributes); 90 91 /** 92 * Returns the DOM element corresponding to the tag which references 93 * this plugin in the document. 94 * 95 * @param aDOMElement - resulting DOM element 96 * @result - NS_OK if this operation was successful 97 */ 98 NS_IMETHOD GetDOMElement(nsIDOMElement** aResult); 99 100 // nsIDOMEventListener interfaces 101 NS_DECL_NSIDOMEVENTLISTENER 102 103 nsresult ProcessMouseDown(nsIDOMEvent* aKeyEvent); 104 nsresult ProcessKeyPress(nsIDOMEvent* aKeyEvent); 105 nsresult Destroy(); 106 107 #ifdef XP_WIN 108 void Paint(const RECT& aDirty, HDC aDC); 109 #elif defined(XP_MACOSX) 110 void Paint(const gfxRect& aDirtyRect, CGContextRef cgContext); 111 void RenderCoreAnimation(CGContextRef aCGContext, int aWidth, int aHeight); 112 void DoCocoaEventDrawRect(const gfxRect& aDrawRect, CGContextRef cgContext); 113 #elif defined(MOZ_X11) 114 void Paint(gfxContext* aContext, const gfxRect& aFrameRect, 115 const gfxRect& aDirtyRect); 116 #endif 117 118 // locals 119 120 nsresult Init(nsIContent* aContent); 121 122 void* GetPluginPort(); 123 void ReleasePluginPort(void* pluginPort); 124 125 nsEventStatus ProcessEvent(const mozilla::WidgetGUIEvent& anEvent); 126 127 static void GeneratePluginEvent( 128 const mozilla::WidgetCompositionEvent* aSrcCompositionEvent, 129 mozilla::WidgetCompositionEvent* aDistCompositionEvent); 130 131 #if defined(XP_WIN) 132 void SetWidgetWindowAsParent(HWND aWindowToAdopt); 133 nsresult SetNetscapeWindowAsParent(HWND aWindowToAdopt); 134 #endif 135 136 #ifdef XP_MACOSX 137 enum {ePluginPaintEnable, ePluginPaintDisable}; 138 139 void WindowFocusMayHaveChanged(); 140 141 bool WindowIsActive(); 142 void SendWindowFocusChanged(bool aIsActive); 143 NPDrawingModel GetDrawingModel(); 144 bool IsRemoteDrawingCoreAnimation(); 145 146 NPEventModel GetEventModel(); 147 static void CARefresh(nsITimer* aTimer, void* aClosure); 148 void AddToCARefreshTimer(); 149 void RemoveFromCARefreshTimer(); 150 // This calls into the plugin (NPP_SetWindow) and can run script. 151 void FixUpPluginWindow(int32_t inPaintState); 152 void HidePluginWindow(); 153 // Set plugin port info in the plugin (in the 'window' member of the 154 // NPWindow structure passed to the plugin by SetWindow()). 155 void SetPluginPort(); 156 #else // XP_MACOSX 157 void UpdateWindowPositionAndClipRect(bool aSetWindow); 158 void UpdateWindowVisibility(bool aVisible); 159 #endif // XP_MACOSX 160 161 void ResolutionMayHaveChanged(); 162 #if defined(XP_MACOSX) || defined(XP_WIN) 163 nsresult ContentsScaleFactorChanged(double aContentsScaleFactor); 164 #endif 165 166 void UpdateDocumentActiveState(bool aIsActive); 167 168 void SetFrame(nsPluginFrame* aFrame); 169 nsPluginFrame* GetFrame(); 170 GetLastEventloopNestingLevel()171 uint32_t GetLastEventloopNestingLevel() const { 172 return mLastEventloopNestingLevel; 173 } 174 175 static uint32_t GetEventloopNestingLevel(); 176 ConsiderNewEventloopNestingLevel()177 void ConsiderNewEventloopNestingLevel() { 178 uint32_t currentLevel = GetEventloopNestingLevel(); 179 180 if (currentLevel < mLastEventloopNestingLevel) { 181 mLastEventloopNestingLevel = currentLevel; 182 } 183 } 184 GetPluginName()185 const char* GetPluginName() { 186 if (mInstance && mPluginHost) { 187 const char* name = nullptr; 188 if (NS_SUCCEEDED(mPluginHost->GetPluginName(mInstance, &name)) && name) 189 return name; 190 } 191 return ""; 192 } 193 194 #ifdef MOZ_X11 GetPluginDescription(nsACString & aDescription)195 void GetPluginDescription(nsACString& aDescription) { 196 aDescription.Truncate(); 197 if (mInstance && mPluginHost) { 198 nsCOMPtr<nsIPluginTag> pluginTag; 199 200 mPluginHost->GetPluginTagForInstance(mInstance, 201 getter_AddRefs(pluginTag)); 202 if (pluginTag) { 203 pluginTag->GetDescription(aDescription); 204 } 205 } 206 } 207 #endif 208 SendNativeEvents()209 bool SendNativeEvents() { 210 #ifdef XP_WIN 211 // XXX we should remove the plugin name check 212 return mPluginWindow->type == NPWindowTypeDrawable && 213 (MatchPluginName("Shockwave Flash") || 214 MatchPluginName("Test Plug-in")); 215 #elif defined(MOZ_X11) || defined(XP_MACOSX) 216 return true; 217 #else 218 return false; 219 #endif 220 } 221 MatchPluginName(const char * aPluginName)222 bool MatchPluginName(const char* aPluginName) { 223 return strncmp(GetPluginName(), aPluginName, strlen(aPluginName)) == 0; 224 } 225 226 void NotifyPaintWaiter(nsDisplayListBuilder* aBuilder); 227 228 // Returns the image container that has our currently displayed image. 229 already_AddRefed<mozilla::layers::ImageContainer> GetImageContainer(); 230 // Returns true if this is windowed plugin that can return static captures 231 // for scroll operations. 232 bool NeedsScrollImageLayer(); 233 234 void DidComposite(); 235 236 /** 237 * Returns the bounds of the current async-rendered surface. This can only 238 * change in response to messages received by the event loop (i.e. not during 239 * painting). 240 */ 241 nsIntSize GetCurrentImageSize(); 242 243 // Methods to update the background image we send to async plugins. 244 // The eventual target of these operations is PluginInstanceParent, 245 // but it takes several hops to get there. 246 void SetBackgroundUnknown(); 247 already_AddRefed<DrawTarget> BeginUpdateBackground(const nsIntRect& aRect); 248 void EndUpdateBackground(const nsIntRect& aRect); 249 250 bool UseAsyncRendering(); 251 252 already_AddRefed<nsIURI> GetBaseURI() const; 253 254 bool GetCompositionString(uint32_t aIndex, nsTArray<uint8_t>* aString, 255 int32_t* aLength); 256 bool SetCandidateWindow( 257 const mozilla::widget::CandidateWindowPosition& aPosition); 258 bool RequestCommitOrCancel(bool aCommitted); 259 bool EnableIME(bool aEnable); 260 261 // See nsIKeyEventInPluginCallback 262 virtual void HandledWindowedPluginKeyEvent( 263 const mozilla::NativeEventData& aKeyEventData, bool aIsConsumed) override; 264 265 /** 266 * OnWindowedPluginKeyEvent() is called when the plugin process receives 267 * native key event directly. 268 * 269 * @param aNativeKeyData The key event which was received by the 270 * plugin process directly. 271 */ 272 void OnWindowedPluginKeyEvent(const mozilla::NativeEventData& aNativeKeyData); 273 274 void GetCSSZoomFactor(float* result); 275 276 private: 277 virtual ~nsPluginInstanceOwner(); 278 279 // return FALSE if LayerSurface dirty (newly created and don't have valid 280 // plugin content yet) IsUpToDate()281 bool IsUpToDate() { 282 nsIntSize size; 283 return NS_SUCCEEDED(mInstance->GetImageSize(&size)) && 284 size == nsIntSize(mPluginWindow->width, mPluginWindow->height); 285 } 286 287 #if defined(XP_WIN) 288 nsIWidget* GetContainingWidgetIfOffset(); 289 already_AddRefed<mozilla::TextComposition> GetTextComposition(); 290 void HandleNoConsumedCompositionMessage( 291 mozilla::WidgetCompositionEvent* aCompositionEvent, 292 const NPEvent* aPluginEvent); 293 bool mGotCompositionData; 294 bool mSentStartComposition; 295 bool mPluginDidNotHandleIMEComposition; 296 #endif 297 298 nsPluginNativeWindow* mPluginWindow; 299 RefPtr<nsNPAPIPluginInstance> mInstance; 300 nsPluginFrame* mPluginFrame; 301 nsWeakPtr mContent; // WEAK, content owns us 302 nsCString mDocumentBase; 303 bool mWidgetCreationComplete; 304 nsCOMPtr<nsIWidget> mWidget; 305 RefPtr<nsPluginHost> mPluginHost; 306 307 #ifdef XP_MACOSX 308 static mozilla::StaticRefPtr<nsITimer> sCATimer; 309 static nsTArray<nsPluginInstanceOwner*>* sCARefreshListeners; 310 bool mSentInitialTopLevelWindowEvent; 311 bool mLastWindowIsActive; 312 bool mLastContentFocused; 313 // True if, the next time the window is activated, we should blur ourselves. 314 bool mShouldBlurOnActivate; 315 #endif 316 double mLastScaleFactor; 317 double mLastCSSZoomFactor; 318 // Initially, the event loop nesting level we were created on, it's updated 319 // if we detect the appshell is on a lower level as long as we're not stopped. 320 // We delay DoStopPlugin() until the appshell reaches this level or lower. 321 uint32_t mLastEventloopNestingLevel; 322 bool mContentFocused; 323 bool mWidgetVisible; // used on Mac to store our widget's visible state 324 #ifdef MOZ_X11 325 // Used with windowless plugins only, initialized in CreateWidget(). 326 bool mFlash10Quirks; 327 #endif 328 bool mPluginWindowVisible; 329 bool mPluginDocumentActiveState; 330 331 #ifdef XP_MACOSX 332 NPEventModel mEventModel; 333 // This is a hack! UseAsyncRendering() can incorrectly return false 334 // when we don't have an object frame (possible as of bug 90268). 335 // We hack around this by always returning true if we've ever 336 // returned true. 337 bool mUseAsyncRendering; 338 #endif 339 340 // pointer to wrapper for nsIDOMContextMenuListener 341 RefPtr<nsPluginDOMContextMenuListener> mCXMenuListener; 342 343 nsresult DispatchKeyToPlugin(nsIDOMEvent* aKeyEvent); 344 nsresult DispatchMouseToPlugin(nsIDOMEvent* aMouseEvent, 345 bool aAllowPropagate = false); 346 nsresult DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent); 347 nsresult DispatchCompositionToPlugin(nsIDOMEvent* aEvent); 348 349 #ifdef XP_WIN 350 void CallDefaultProc(const mozilla::WidgetGUIEvent* aEvent); 351 #endif 352 353 #ifdef XP_MACOSX 354 static NPBool ConvertPointPuppet(PuppetWidget* widget, 355 nsPluginFrame* pluginFrame, double sourceX, 356 double sourceY, 357 NPCoordinateSpace sourceSpace, double* destX, 358 double* destY, NPCoordinateSpace destSpace); 359 static NPBool ConvertPointNoPuppet(nsIWidget* widget, 360 nsPluginFrame* pluginFrame, double sourceX, 361 double sourceY, 362 NPCoordinateSpace sourceSpace, 363 double* destX, double* destY, 364 NPCoordinateSpace destSpace); 365 void PerformDelayedBlurs(); 366 #endif // XP_MACOSX 367 368 int mLastMouseDownButtonType; 369 370 #ifdef MOZ_X11 371 class Renderer : public gfxXlibNativeRenderer { 372 public: Renderer(NPWindow * aWindow,nsPluginInstanceOwner * aInstanceOwner,const nsIntSize & aPluginSize,const nsIntRect & aDirtyRect)373 Renderer(NPWindow* aWindow, nsPluginInstanceOwner* aInstanceOwner, 374 const nsIntSize& aPluginSize, const nsIntRect& aDirtyRect) 375 : mWindow(aWindow), 376 mInstanceOwner(aInstanceOwner), 377 mPluginSize(aPluginSize), 378 mDirtyRect(aDirtyRect) {} 379 virtual nsresult DrawWithXlib(cairo_surface_t* surface, nsIntPoint offset, 380 nsIntRect* clipRects, 381 uint32_t numClipRects) override; 382 383 private: 384 NPWindow* mWindow; 385 nsPluginInstanceOwner* mInstanceOwner; 386 const nsIntSize& mPluginSize; 387 const nsIntRect& mDirtyRect; 388 }; 389 #endif 390 391 bool mWaitingForPaint; 392 }; 393 394 #endif // nsPluginInstanceOwner_h_ 395