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