1 /* 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. 3 * Copyright (C) 2008 Collabora Ltd. All rights reserved. 4 * Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef PluginView_h 29 #define PluginView_h 30 31 #include "FrameLoadRequest.h" 32 #include "HaltablePlugin.h" 33 #include "IntRect.h" 34 #include "MediaCanStartListener.h" 35 #include "PluginViewBase.h" 36 #include "ResourceRequest.h" 37 #include "Timer.h" 38 #include <wtf/HashMap.h> 39 #include <wtf/HashSet.h> 40 #include <wtf/OwnPtr.h> 41 #include <wtf/PassRefPtr.h> 42 #include <wtf/RefPtr.h> 43 #include <wtf/Vector.h> 44 #include <wtf/text/CString.h> 45 46 #if ENABLE(NETSCAPE_PLUGIN_API) 47 #include "PluginStream.h" 48 #include "npruntime_internal.h" 49 #endif 50 51 // ANDROID 52 // TODO: Upstream to webkit.org 53 #ifdef PLUGIN_SCHEDULE_TIMER 54 #include "PluginTimer.h" 55 #endif 56 57 #if OS(WINDOWS) && (PLATFORM(QT) || PLATFORM(WX)) 58 typedef struct HWND__* HWND; 59 typedef HWND PlatformPluginWidget; 60 #elif defined(ANDROID_PLUGINS) 61 typedef struct PluginWidgetAndroid* PlatformPluginWidget; 62 #else 63 typedef PlatformWidget PlatformPluginWidget; 64 #if defined(XP_MACOSX) && PLATFORM(QT) 65 #include <QPixmap> 66 #endif 67 #endif 68 #if PLATFORM(QT) 69 #include <QGraphicsItem> 70 #include <QImage> 71 QT_BEGIN_NAMESPACE 72 class QPainter; 73 QT_END_NAMESPACE 74 #endif 75 #if PLATFORM(GTK) 76 typedef struct _GtkSocket GtkSocket; 77 #endif 78 79 #if USE(JSC) 80 namespace JSC { 81 namespace Bindings { 82 class Instance; 83 } 84 } 85 #endif 86 87 class NPObject; 88 89 namespace WebCore { 90 class Element; 91 class Frame; 92 class Image; 93 class KeyboardEvent; 94 class MouseEvent; 95 #ifdef ANDROID_PLUGINS 96 class TouchEvent; 97 #endif 98 class KURL; 99 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API) 100 class PluginMessageThrottlerWin; 101 #endif 102 class PluginPackage; 103 class PluginRequest; 104 class PluginStream; 105 class ResourceError; 106 class ResourceResponse; 107 108 enum PluginStatus { 109 PluginStatusCanNotFindPlugin, 110 PluginStatusCanNotLoadPlugin, 111 PluginStatusLoadedSuccessfully 112 }; 113 114 class PluginRequest { 115 WTF_MAKE_NONCOPYABLE(PluginRequest); WTF_MAKE_FAST_ALLOCATED; 116 public: PluginRequest(const FrameLoadRequest & frameLoadRequest,bool sendNotification,void * notifyData,bool shouldAllowPopups)117 PluginRequest(const FrameLoadRequest& frameLoadRequest, bool sendNotification, void* notifyData, bool shouldAllowPopups) 118 : m_frameLoadRequest(frameLoadRequest) 119 , m_notifyData(notifyData) 120 , m_sendNotification(sendNotification) 121 , m_shouldAllowPopups(shouldAllowPopups) { } 122 public: frameLoadRequest()123 const FrameLoadRequest& frameLoadRequest() const { return m_frameLoadRequest; } notifyData()124 void* notifyData() const { return m_notifyData; } sendNotification()125 bool sendNotification() const { return m_sendNotification; } shouldAllowPopups()126 bool shouldAllowPopups() const { return m_shouldAllowPopups; } 127 private: 128 FrameLoadRequest m_frameLoadRequest; 129 void* m_notifyData; 130 bool m_sendNotification; 131 bool m_shouldAllowPopups; 132 }; 133 134 class PluginManualLoader { 135 public: ~PluginManualLoader()136 virtual ~PluginManualLoader() {} 137 virtual void didReceiveResponse(const ResourceResponse&) = 0; 138 virtual void didReceiveData(const char*, int) = 0; 139 virtual void didFinishLoading() = 0; 140 virtual void didFail(const ResourceError&) = 0; 141 }; 142 143 class PluginView : public PluginViewBase 144 #if ENABLE(NETSCAPE_PLUGIN_API) 145 , private PluginStreamClient 146 #endif 147 , public PluginManualLoader 148 , private HaltablePlugin 149 , private MediaCanStartListener { 150 public: 151 static PassRefPtr<PluginView> create(Frame* parentFrame, const IntSize&, Element*, const KURL&, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually); 152 virtual ~PluginView(); 153 plugin()154 PluginPackage* plugin() const { return m_plugin.get(); } 155 #if ENABLE(NETSCAPE_PLUGIN_API) instance()156 NPP instance() const { return m_instance; } 157 #endif 158 159 void setNPWindowRect(const IntRect&); 160 static PluginView* currentPluginView(); 161 162 #if ENABLE(NETSCAPE_PLUGIN_API) 163 NPObject* npObject(); 164 #endif 165 #if USE(JSC) 166 PassRefPtr<JSC::Bindings::Instance> bindingInstance(); 167 #endif 168 status()169 PluginStatus status() const { return m_status; } 170 171 #if ENABLE(NETSCAPE_PLUGIN_API) 172 // NPN functions 173 NPError getURLNotify(const char* url, const char* target, void* notifyData); 174 NPError getURL(const char* url, const char* target); 175 NPError postURLNotify(const char* url, const char* target, uint32_t len, const char* but, NPBool file, void* notifyData); 176 NPError postURL(const char* url, const char* target, uint32_t len, const char* but, NPBool file); 177 NPError newStream(NPMIMEType type, const char* target, NPStream** stream); 178 int32_t write(NPStream* stream, int32_t len, void* buffer); 179 NPError destroyStream(NPStream* stream, NPReason reason); 180 #endif 181 const char* userAgent(); 182 #if ENABLE(NETSCAPE_PLUGIN_API) 183 static const char* userAgentStatic(); 184 #endif 185 void status(const char* message); 186 187 #if ENABLE(NETSCAPE_PLUGIN_API) 188 NPError getValue(NPNVariable variable, void* value); 189 static NPError getValueStatic(NPNVariable variable, void* value); 190 NPError setValue(NPPVariable variable, void* value); 191 NPError getValueForURL(NPNURLVariable variable, const char* url, char** value, uint32_t* len); 192 NPError setValueForURL(NPNURLVariable variable, const char* url, const char* value, uint32_t len); 193 NPError getAuthenticationInfo(const char* protocol, const char* host, int32_t port, const char* scheme, const char* realm, char** username, uint32_t* ulen, char** password, uint32_t* plen); 194 void invalidateRect(NPRect*); 195 void invalidateRegion(NPRegion); 196 #endif 197 void forceRedraw(); 198 void pushPopupsEnabledState(bool state); 199 void popPopupsEnabledState(); 200 #ifdef PLUGIN_SCHEDULE_TIMER 201 uint32_t scheduleTimer(NPP, uint32_t interval, bool repeat, 202 void (*timerFunc)(NPP, uint32_t timerID)); 203 void unscheduleTimer(NPP, uint32_t timerID); 204 #endif 205 NPObject* getNPObject(); 206 207 virtual void invalidateRect(const IntRect&); 208 209 bool arePopupsAllowed() const; 210 211 void setJavaScriptPaused(bool); 212 213 void privateBrowsingStateChanged(bool); 214 215 void disconnectStream(PluginStream*); streamDidFinishLoading(PluginStream * stream)216 void streamDidFinishLoading(PluginStream* stream) { disconnectStream(stream); } 217 218 // Widget functions 219 virtual void setFrameRect(const IntRect&); 220 virtual void frameRectsChanged(); 221 virtual void setFocus(bool); 222 virtual void show(); 223 virtual void hide(); 224 virtual void paint(GraphicsContext*, const IntRect&); 225 226 // This method is used by plugins on all platforms to obtain a clip rect that includes clips set by WebCore, 227 // e.g., in overflow:auto sections. The clip rects coordinates are in the containing window's coordinate space. 228 // This clip includes any clips that the widget itself sets up for its children. 229 IntRect windowClipRect() const; 230 231 virtual void handleEvent(Event*); 232 virtual void setParent(ScrollView*); 233 virtual void setParentVisible(bool); 234 isPluginView()235 virtual bool isPluginView() const { return true; } 236 parentFrame()237 Frame* parentFrame() const { return m_parentFrame.get(); } 238 239 void focusPluginElement(); 240 pluginsPage()241 const String& pluginsPage() const { return m_pluginsPage; } mimeType()242 const String& mimeType() const { return m_mimeType; } url()243 const KURL& url() const { return m_url; } 244 245 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API) 246 static LRESULT CALLBACK PluginViewWndProc(HWND, UINT, WPARAM, LPARAM); 247 LRESULT wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); pluginWndProc()248 WNDPROC pluginWndProc() const { return m_pluginWndProc; } 249 #endif 250 251 // Used for manual loading 252 void didReceiveResponse(const ResourceResponse&); 253 void didReceiveData(const char*, int); 254 void didFinishLoading(); 255 void didFail(const ResourceError&); 256 257 // HaltablePlugin 258 virtual void halt(); 259 virtual void restart(); 260 virtual Node* node() const; isWindowed()261 virtual bool isWindowed() const { return m_isWindowed; } 262 virtual String pluginName() const; 263 isHalted()264 bool isHalted() const { return m_isHalted; } hasBeenHalted()265 bool hasBeenHalted() const { return m_hasBeenHalted; } 266 267 static bool isCallingPlugin(); 268 269 #ifdef ANDROID_PLUGINS getElement()270 Element* getElement() const { return m_element; } 271 #endif 272 273 bool start(); 274 275 #if ENABLE(NETSCAPE_PLUGIN_API) 276 static void keepAlive(NPP); 277 #endif 278 void keepAlive(); 279 280 #if USE(ACCELERATED_COMPOSITING) 281 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API) && PLATFORM(QT) 282 virtual PlatformLayer* platformLayer() const; 283 #elif ENABLE(NETSCAPE_PLUGIN_API) && defined(ANDROID_PLUGINS) 284 virtual PlatformLayer* platformLayer() const; 285 #else platformLayer()286 virtual PlatformLayer* platformLayer() const { return 0; } 287 #endif 288 #endif 289 290 private: 291 PluginView(Frame* parentFrame, const IntSize&, PluginPackage*, Element*, const KURL&, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually); 292 293 void setParameters(const Vector<String>& paramNames, const Vector<String>& paramValues); 294 bool startOrAddToUnstartedList(); 295 void init(); 296 bool platformStart(); 297 void stop(); 298 void platformDestroy(); 299 static void setCurrentPluginView(PluginView*); 300 #if ENABLE(NETSCAPE_PLUGIN_API) 301 NPError load(const FrameLoadRequest&, bool sendNotification, void* notifyData); 302 NPError handlePost(const char* url, const char* target, uint32_t len, const char* buf, bool file, void* notifyData, bool sendNotification, bool allowHeaders); 303 NPError handlePostReadFile(Vector<char>& buffer, uint32_t len, const char* buf); 304 #endif 305 static void freeStringArray(char** stringArray, int length); 306 void setCallingPlugin(bool) const; 307 308 void invalidateWindowlessPluginRect(const IntRect&); 309 310 virtual void mediaCanStart(); 311 312 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API) 313 void paintWindowedPluginIntoContext(GraphicsContext*, const IntRect&); 314 static HDC WINAPI hookedBeginPaint(HWND, PAINTSTRUCT*); 315 static BOOL WINAPI hookedEndPaint(HWND, const PAINTSTRUCT*); 316 #endif 317 318 #if ENABLE(NETSCAPE_PLUGIN_API) 319 static bool platformGetValueStatic(NPNVariable variable, void* value, NPError* result); 320 bool platformGetValue(NPNVariable variable, void* value, NPError* result); 321 #endif 322 323 RefPtr<Frame> m_parentFrame; 324 RefPtr<PluginPackage> m_plugin; 325 Element* m_element; 326 bool m_isStarted; 327 KURL m_url; 328 KURL m_baseURL; 329 PluginStatus m_status; 330 Vector<IntRect> m_invalidRects; 331 332 void performRequest(PluginRequest*); 333 void scheduleRequest(PluginRequest*); 334 void requestTimerFired(Timer<PluginView>*); 335 void invalidateTimerFired(Timer<PluginView>*); 336 Timer<PluginView> m_requestTimer; 337 Timer<PluginView> m_invalidateTimer; 338 339 void popPopupsStateTimerFired(Timer<PluginView>*); 340 Timer<PluginView> m_popPopupsStateTimer; 341 342 void lifeSupportTimerFired(Timer<PluginView>*); 343 Timer<PluginView> m_lifeSupportTimer; 344 345 #ifndef NP_NO_CARBON 346 #if ENABLE(NETSCAPE_PLUGIN_API) 347 bool dispatchNPEvent(NPEvent&); 348 #endif // ENABLE(NETSCAPE_PLUGIN_API) 349 #endif 350 void updatePluginWidget(); 351 void paintMissingPluginIcon(GraphicsContext*, const IntRect&); 352 353 void handleKeyboardEvent(KeyboardEvent*); 354 void handleMouseEvent(MouseEvent*); 355 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API) 356 void handleFocusInEvent(); 357 void handleFocusOutEvent(); 358 #endif 359 360 #if OS(WINDOWS) 361 void paintIntoTransformedContext(HDC); 362 PassRefPtr<Image> snapshot(); 363 #endif 364 365 #ifdef ANDROID_PLUGINS 366 void handleFocusEvent(bool hasFocus); 367 void handleTouchEvent(TouchEvent*); 368 // called at the end of the base constructor 369 void platformInit(); 370 #endif 371 #ifdef PLUGIN_PLATFORM_SETVALUE 372 // called if the default setValue does not recognize the variable 373 NPError platformSetValue(NPPVariable variable, void* value); 374 #endif 375 376 int m_mode; 377 int m_paramCount; 378 char** m_paramNames; 379 char** m_paramValues; 380 String m_pluginsPage; 381 382 String m_mimeType; 383 WTF::CString m_userAgent; 384 385 #if ENABLE(NETSCAPE_PLUGIN_API) 386 NPP m_instance; 387 NPP_t m_instanceStruct; 388 NPWindow m_npWindow; 389 #endif 390 391 Vector<bool, 4> m_popupStateStack; 392 393 HashSet<RefPtr<PluginStream> > m_streams; 394 Vector<PluginRequest*> m_requests; 395 396 bool m_isWindowed; 397 bool m_isTransparent; 398 bool m_haveInitialized; 399 bool m_isWaitingToStart; 400 401 #if defined(XP_UNIX) 402 bool m_needsXEmbed; 403 #endif 404 405 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API) 406 OwnPtr<PluginMessageThrottlerWin> m_messageThrottler; 407 WNDPROC m_pluginWndProc; 408 unsigned m_lastMessage; 409 bool m_isCallingPluginWndProc; 410 HDC m_wmPrintHDC; 411 bool m_haveUpdatedPluginWidget; 412 #endif 413 414 // ANDROID 415 // TODO: Upstream to webkit.org 416 #ifdef PLUGIN_SCHEDULE_TIMER 417 PluginTimerList m_timerList; 418 #endif 419 420 #if ((PLATFORM(QT) || PLATFORM(WX)) && OS(WINDOWS)) || defined(XP_MACOSX) 421 // On Mac OSX and Qt/Windows the plugin does not have its own native widget, 422 // but is using the containing window as its reference for positioning/painting. 423 PlatformPluginWidget m_window; 424 public: platformPluginWidget()425 PlatformPluginWidget platformPluginWidget() const { return m_window; } setPlatformPluginWidget(PlatformPluginWidget widget)426 void setPlatformPluginWidget(PlatformPluginWidget widget) { m_window = widget; } 427 #elif defined(ANDROID_PLUGINS) 428 public: 429 PlatformPluginWidget m_window; platformPluginWidget()430 PlatformPluginWidget platformPluginWidget() const { return m_window; } // MANUAL MERGE FIXME 431 #else 432 public: setPlatformPluginWidget(PlatformPluginWidget widget)433 void setPlatformPluginWidget(PlatformPluginWidget widget) { setPlatformWidget(widget); } platformPluginWidget()434 PlatformPluginWidget platformPluginWidget() const { return platformWidget(); } 435 #endif 436 437 private: 438 439 #if defined(XP_UNIX) || OS(SYMBIAN) || PLATFORM(GTK) || defined(ANDROID_PLUGINS) 440 void setNPWindowIfNeeded(); 441 #elif defined(XP_MACOSX) 442 NP_CGContext m_npCgContext; 443 OwnPtr<Timer<PluginView> > m_nullEventTimer; 444 NPDrawingModel m_drawingModel; 445 NPEventModel m_eventModel; 446 CGContextRef m_contextRef; 447 WindowRef m_fakeWindow; 448 #if PLATFORM(QT) 449 QPixmap m_pixmap; 450 #endif 451 452 Point m_lastMousePos; 453 void setNPWindowIfNeeded(); 454 void nullEventTimerFired(Timer<PluginView>*); 455 Point globalMousePosForPlugin() const; 456 Point mousePosForPlugin(MouseEvent* event = 0) const; 457 #endif 458 459 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API) 460 bool m_hasPendingGeometryChange; 461 Pixmap m_drawable; 462 Visual* m_visual; 463 Colormap m_colormap; 464 Display* m_pluginDisplay; 465 466 void initXEvent(XEvent* event); 467 #endif 468 469 #if PLATFORM(QT) 470 #if defined(MOZ_PLATFORM_MAEMO) && (MOZ_PLATFORM_MAEMO >= 5) 471 QImage m_image; 472 bool m_renderToImage; 473 void paintUsingImageSurfaceExtension(QPainter* painter, const IntRect& exposedRect); 474 #endif 475 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API) 476 void paintUsingXPixmap(QPainter* painter, const QRect &exposedRect); 477 #if USE(ACCELERATED_COMPOSITING) 478 OwnPtr<PlatformLayer> m_platformLayer; 479 friend class PluginGraphicsLayerQt; 480 #endif // USE(ACCELERATED_COMPOSITING) 481 #endif 482 #endif // PLATFORM(QT) 483 484 #if PLATFORM(GTK) 485 static gboolean plugRemovedCallback(GtkSocket*, PluginView*); 486 static void plugAddedCallback(GtkSocket*, PluginView*); 487 bool m_plugAdded; 488 IntRect m_delayedAllocation; 489 #endif 490 491 IntRect m_clipRect; // The clip rect to apply to a windowed plug-in 492 IntRect m_windowRect; // Our window rect. 493 #ifdef ANDROID_PLUGINS 494 IntRect m_pageRect; // The rect in page coordinate system. 495 #endif 496 497 bool m_loadManually; 498 RefPtr<PluginStream> m_manualStream; 499 500 bool m_isJavaScriptPaused; 501 502 bool m_isHalted; 503 bool m_hasBeenHalted; 504 505 bool m_haveCalledSetWindow; 506 507 static PluginView* s_currentPluginView; 508 }; 509 510 } // namespace WebCore 511 512 #endif 513