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 (at) 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: 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: 123 const FrameLoadRequest& frameLoadRequest() const { return m_frameLoadRequest; } 124 void* notifyData() const { return m_notifyData; } 125 bool sendNotification() const { return m_sendNotification; } 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: 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 154 PluginPackage* plugin() const { return m_plugin.get(); } 155 #if ENABLE(NETSCAPE_PLUGIN_API) 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 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 #if USE(V8) 206 NPObject* getNPObject(); 207 #endif 208 209 virtual void invalidateRect(const IntRect&); 210 211 bool arePopupsAllowed() const; 212 213 void setJavaScriptPaused(bool); 214 215 void privateBrowsingStateChanged(bool); 216 217 void disconnectStream(PluginStream*); 218 void streamDidFinishLoading(PluginStream* stream) { disconnectStream(stream); } 219 220 // Widget functions 221 virtual void setFrameRect(const IntRect&); 222 virtual void frameRectsChanged(); 223 virtual void setFocus(bool); 224 virtual void show(); 225 virtual void hide(); 226 virtual void paint(GraphicsContext*, const IntRect&); 227 228 // This method is used by plugins on all platforms to obtain a clip rect that includes clips set by WebCore, 229 // e.g., in overflow:auto sections. The clip rects coordinates are in the containing window's coordinate space. 230 // This clip includes any clips that the widget itself sets up for its children. 231 IntRect windowClipRect() const; 232 233 virtual void handleEvent(Event*); 234 virtual void setParent(ScrollView*); 235 virtual void setParentVisible(bool); 236 237 virtual bool isPluginView() const { return true; } 238 239 Frame* parentFrame() const { return m_parentFrame.get(); } 240 241 void focusPluginElement(); 242 243 const String& pluginsPage() const { return m_pluginsPage; } 244 const String& mimeType() const { return m_mimeType; } 245 const KURL& url() const { return m_url; } 246 247 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API) 248 static LRESULT CALLBACK PluginViewWndProc(HWND, UINT, WPARAM, LPARAM); 249 LRESULT wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); 250 WNDPROC pluginWndProc() const { return m_pluginWndProc; } 251 #endif 252 253 // Used for manual loading 254 void didReceiveResponse(const ResourceResponse&); 255 void didReceiveData(const char*, int); 256 void didFinishLoading(); 257 void didFail(const ResourceError&); 258 259 // HaltablePlugin 260 virtual void halt(); 261 virtual void restart(); 262 virtual Node* node() const; 263 virtual bool isWindowed() const { return m_isWindowed; } 264 virtual String pluginName() const; 265 266 bool isHalted() const { return m_isHalted; } 267 bool hasBeenHalted() const { return m_hasBeenHalted; } 268 269 static bool isCallingPlugin(); 270 271 #ifdef ANDROID_PLUGINS 272 Element* getElement() const { return m_element; } 273 #endif 274 275 bool start(); 276 277 #if ENABLE(NETSCAPE_PLUGIN_API) 278 static void keepAlive(NPP); 279 #endif 280 void keepAlive(); 281 282 #if USE(ACCELERATED_COMPOSITING) 283 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API) && PLATFORM(QT) 284 virtual PlatformLayer* platformLayer() const; 285 #elif ENABLE(NETSCAPE_PLUGIN_API) && defined(ANDROID_PLUGINS) 286 virtual PlatformLayer* platformLayer() const; 287 #else 288 virtual PlatformLayer* platformLayer() const { return 0; } 289 #endif 290 #endif 291 292 private: 293 PluginView(Frame* parentFrame, const IntSize&, PluginPackage*, Element*, const KURL&, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually); 294 295 void setParameters(const Vector<String>& paramNames, const Vector<String>& paramValues); 296 bool startOrAddToUnstartedList(); 297 void init(); 298 bool platformStart(); 299 void stop(); 300 void platformDestroy(); 301 static void setCurrentPluginView(PluginView*); 302 #if ENABLE(NETSCAPE_PLUGIN_API) 303 NPError load(const FrameLoadRequest&, bool sendNotification, void* notifyData); 304 NPError handlePost(const char* url, const char* target, uint32_t len, const char* buf, bool file, void* notifyData, bool sendNotification, bool allowHeaders); 305 NPError handlePostReadFile(Vector<char>& buffer, uint32_t len, const char* buf); 306 #endif 307 static void freeStringArray(char** stringArray, int length); 308 void setCallingPlugin(bool) const; 309 310 void invalidateWindowlessPluginRect(const IntRect&); 311 312 virtual void mediaCanStart(); 313 314 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API) 315 void paintWindowedPluginIntoContext(GraphicsContext*, const IntRect&); 316 static HDC WINAPI hookedBeginPaint(HWND, PAINTSTRUCT*); 317 static BOOL WINAPI hookedEndPaint(HWND, const PAINTSTRUCT*); 318 #endif 319 320 #if ENABLE(NETSCAPE_PLUGIN_API) 321 static bool platformGetValueStatic(NPNVariable variable, void* value, NPError* result); 322 bool platformGetValue(NPNVariable variable, void* value, NPError* result); 323 #endif 324 325 RefPtr<Frame> m_parentFrame; 326 RefPtr<PluginPackage> m_plugin; 327 Element* m_element; 328 bool m_isStarted; 329 KURL m_url; 330 KURL m_baseURL; 331 PluginStatus m_status; 332 Vector<IntRect> m_invalidRects; 333 334 void performRequest(PluginRequest*); 335 void scheduleRequest(PluginRequest*); 336 void requestTimerFired(Timer<PluginView>*); 337 void invalidateTimerFired(Timer<PluginView>*); 338 Timer<PluginView> m_requestTimer; 339 Timer<PluginView> m_invalidateTimer; 340 341 void popPopupsStateTimerFired(Timer<PluginView>*); 342 Timer<PluginView> m_popPopupsStateTimer; 343 344 void lifeSupportTimerFired(Timer<PluginView>*); 345 Timer<PluginView> m_lifeSupportTimer; 346 347 #ifndef NP_NO_CARBON 348 #if ENABLE(NETSCAPE_PLUGIN_API) 349 bool dispatchNPEvent(NPEvent&); 350 #endif // ENABLE(NETSCAPE_PLUGIN_API) 351 #endif 352 void updatePluginWidget(); 353 void paintMissingPluginIcon(GraphicsContext*, const IntRect&); 354 355 void handleKeyboardEvent(KeyboardEvent*); 356 void handleMouseEvent(MouseEvent*); 357 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API) 358 void handleFocusInEvent(); 359 void handleFocusOutEvent(); 360 #endif 361 362 #if OS(WINDOWS) 363 void paintIntoTransformedContext(HDC); 364 PassRefPtr<Image> snapshot(); 365 #endif 366 367 #ifdef ANDROID_PLUGINS 368 void handleFocusEvent(bool hasFocus); 369 void handleTouchEvent(TouchEvent*); 370 // called at the end of the base constructor 371 void platformInit(); 372 #endif 373 #ifdef PLUGIN_PLATFORM_SETVALUE 374 // called if the default setValue does not recognize the variable 375 NPError platformSetValue(NPPVariable variable, void* value); 376 #endif 377 378 int m_mode; 379 int m_paramCount; 380 char** m_paramNames; 381 char** m_paramValues; 382 String m_pluginsPage; 383 384 String m_mimeType; 385 WTF::CString m_userAgent; 386 387 #if ENABLE(NETSCAPE_PLUGIN_API) 388 NPP m_instance; 389 NPP_t m_instanceStruct; 390 NPWindow m_npWindow; 391 #endif 392 393 Vector<bool, 4> m_popupStateStack; 394 395 HashSet<RefPtr<PluginStream> > m_streams; 396 Vector<PluginRequest*> m_requests; 397 398 bool m_isWindowed; 399 bool m_isTransparent; 400 bool m_haveInitialized; 401 bool m_isWaitingToStart; 402 403 #if defined(XP_UNIX) 404 bool m_needsXEmbed; 405 #endif 406 407 #if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API) 408 OwnPtr<PluginMessageThrottlerWin> m_messageThrottler; 409 WNDPROC m_pluginWndProc; 410 unsigned m_lastMessage; 411 bool m_isCallingPluginWndProc; 412 HDC m_wmPrintHDC; 413 bool m_haveUpdatedPluginWidget; 414 #endif 415 416 // ANDROID 417 // TODO: Upstream to webkit.org 418 #ifdef PLUGIN_SCHEDULE_TIMER 419 PluginTimerList m_timerList; 420 #endif 421 422 #if ((PLATFORM(QT) || PLATFORM(WX)) && OS(WINDOWS)) || defined(XP_MACOSX) 423 // On Mac OSX and Qt/Windows the plugin does not have its own native widget, 424 // but is using the containing window as its reference for positioning/painting. 425 PlatformPluginWidget m_window; 426 public: 427 PlatformPluginWidget platformPluginWidget() const { return m_window; } 428 void setPlatformPluginWidget(PlatformPluginWidget widget) { m_window = widget; } 429 #elif defined(ANDROID_PLUGINS) 430 public: 431 PlatformPluginWidget m_window; 432 PlatformPluginWidget platformPluginWidget() const { return m_window; } // MANUAL MERGE FIXME 433 #else 434 public: 435 void setPlatformPluginWidget(PlatformPluginWidget widget) { setPlatformWidget(widget); } 436 PlatformPluginWidget platformPluginWidget() const { return platformWidget(); } 437 #endif 438 439 private: 440 441 #if defined(XP_UNIX) || OS(SYMBIAN) || PLATFORM(GTK) || defined(ANDROID_PLUGINS) 442 void setNPWindowIfNeeded(); 443 #elif defined(XP_MACOSX) 444 NP_CGContext m_npCgContext; 445 OwnPtr<Timer<PluginView> > m_nullEventTimer; 446 NPDrawingModel m_drawingModel; 447 NPEventModel m_eventModel; 448 CGContextRef m_contextRef; 449 WindowRef m_fakeWindow; 450 #if PLATFORM(QT) 451 QPixmap m_pixmap; 452 #endif 453 454 Point m_lastMousePos; 455 void setNPWindowIfNeeded(); 456 void nullEventTimerFired(Timer<PluginView>*); 457 Point globalMousePosForPlugin() const; 458 Point mousePosForPlugin(MouseEvent* event = 0) const; 459 #endif 460 461 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API) 462 bool m_hasPendingGeometryChange; 463 Pixmap m_drawable; 464 Visual* m_visual; 465 Colormap m_colormap; 466 Display* m_pluginDisplay; 467 468 void initXEvent(XEvent* event); 469 #endif 470 471 #if PLATFORM(QT) 472 #if defined(MOZ_PLATFORM_MAEMO) && (MOZ_PLATFORM_MAEMO >= 5) 473 QImage m_image; 474 bool m_renderToImage; 475 void paintUsingImageSurfaceExtension(QPainter* painter, const IntRect& exposedRect); 476 #endif 477 #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API) 478 void paintUsingXPixmap(QPainter* painter, const QRect &exposedRect); 479 #if USE(ACCELERATED_COMPOSITING) 480 OwnPtr<PlatformLayer> m_platformLayer; 481 friend class PluginGraphicsLayerQt; 482 #endif // USE(ACCELERATED_COMPOSITING) 483 #endif 484 #endif // PLATFORM(QT) 485 486 #if PLATFORM(GTK) 487 static gboolean plugRemovedCallback(GtkSocket*, PluginView*); 488 static void plugAddedCallback(GtkSocket*, PluginView*); 489 bool m_plugAdded; 490 IntRect m_delayedAllocation; 491 #endif 492 493 IntRect m_clipRect; // The clip rect to apply to a windowed plug-in 494 IntRect m_windowRect; // Our window rect. 495 #ifdef ANDROID_PLUGINS 496 IntRect m_pageRect; // The rect in page coordinate system. 497 #endif 498 499 bool m_loadManually; 500 RefPtr<PluginStream> m_manualStream; 501 502 bool m_isJavaScriptPaused; 503 504 bool m_isHalted; 505 bool m_hasBeenHalted; 506 507 bool m_haveCalledSetWindow; 508 509 static PluginView* s_currentPluginView; 510 }; 511 512 } // namespace WebCore 513 514 #endif 515