1 2 /* 3 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. 4 * Copyright (C) 2008 Collabora Ltd. All rights reserved. 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 "CString.h" 32 #include "FrameLoadRequest.h" 33 #include "IntRect.h" 34 #include "KURL.h" 35 #include "PlatformString.h" 36 #include "PluginStream.h" 37 #include "ResourceRequest.h" 38 #include "Timer.h" 39 #include "Widget.h" 40 #include "npruntime_internal.h" 41 #include <wtf/HashMap.h> 42 #include <wtf/HashSet.h> 43 #include <wtf/OwnPtr.h> 44 #include <wtf/PassRefPtr.h> 45 #include <wtf/RefPtr.h> 46 #include <wtf/Vector.h> 47 48 #ifdef PLUGIN_SCHEDULE_TIMER 49 #include "PluginTimer.h" 50 #endif 51 52 #if PLATFORM(WIN_OS) && PLATFORM(QT) 53 typedef struct HWND__* HWND; 54 typedef HWND PlatformPluginWidget; 55 #elif defined(ANDROID_PLUGINS) 56 typedef struct PluginWidgetAndroid* PlatformPluginWidget; 57 #else 58 typedef PlatformWidget PlatformPluginWidget; 59 #endif 60 61 #if USE(JSC) 62 namespace JSC { 63 namespace Bindings { 64 class Instance; 65 } 66 } 67 #endif 68 69 class NPObject; 70 71 namespace WebCore { 72 class Element; 73 class Frame; 74 class KeyboardEvent; 75 class MouseEvent; 76 #ifdef ANDROID_PLUGINS 77 class TouchEvent; 78 #endif 79 class KURL; 80 #if PLATFORM(WIN_OS) && !PLATFORM(WX) && ENABLE(NETSCAPE_PLUGIN_API) 81 class PluginMessageThrottlerWin; 82 #endif 83 class PluginPackage; 84 class PluginRequest; 85 class PluginStream; 86 class ResourceError; 87 class ResourceResponse; 88 89 enum PluginStatus { 90 PluginStatusCanNotFindPlugin, 91 PluginStatusCanNotLoadPlugin, 92 PluginStatusLoadedSuccessfully 93 }; 94 95 class PluginRequest { 96 public: PluginRequest(const FrameLoadRequest & frameLoadRequest,bool sendNotification,void * notifyData,bool shouldAllowPopups)97 PluginRequest(const FrameLoadRequest& frameLoadRequest, bool sendNotification, void* notifyData, bool shouldAllowPopups) 98 : m_frameLoadRequest(frameLoadRequest) 99 , m_notifyData(notifyData) 100 , m_sendNotification(sendNotification) 101 , m_shouldAllowPopups(shouldAllowPopups) { } 102 public: frameLoadRequest()103 const FrameLoadRequest& frameLoadRequest() const { return m_frameLoadRequest; } notifyData()104 void* notifyData() const { return m_notifyData; } sendNotification()105 bool sendNotification() const { return m_sendNotification; } shouldAllowPopups()106 bool shouldAllowPopups() const { return m_shouldAllowPopups; } 107 private: 108 FrameLoadRequest m_frameLoadRequest; 109 void* m_notifyData; 110 bool m_sendNotification; 111 bool m_shouldAllowPopups; 112 }; 113 114 class PluginManualLoader { 115 public: ~PluginManualLoader()116 virtual ~PluginManualLoader() {} 117 virtual void didReceiveResponse(const ResourceResponse&) = 0; 118 virtual void didReceiveData(const char*, int) = 0; 119 virtual void didFinishLoading() = 0; 120 virtual void didFail(const ResourceError&) = 0; 121 }; 122 123 class PluginView : public Widget, private PluginStreamClient, public PluginManualLoader { 124 public: 125 static PassRefPtr<PluginView> create(Frame* parentFrame, const IntSize&, Element*, const KURL&, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually); 126 virtual ~PluginView(); 127 plugin()128 PluginPackage* plugin() const { return m_plugin.get(); } instance()129 NPP instance() const { return m_instance; } 130 131 void setNPWindowRect(const IntRect&); 132 static PluginView* currentPluginView(); 133 134 #if USE(JSC) 135 PassRefPtr<JSC::Bindings::Instance> bindingInstance(); 136 #elif USE(V8) 137 NPObject* getNPObject(); 138 #endif 139 status()140 PluginStatus status() const { return m_status; } 141 142 // NPN functions 143 NPError getURLNotify(const char* url, const char* target, void* notifyData); 144 NPError getURL(const char* url, const char* target); 145 NPError postURLNotify(const char* url, const char* target, uint32 len, const char* but, NPBool file, void* notifyData); 146 NPError postURL(const char* url, const char* target, uint32 len, const char* but, NPBool file); 147 NPError newStream(NPMIMEType type, const char* target, NPStream** stream); 148 int32 write(NPStream* stream, int32 len, void* buffer); 149 NPError destroyStream(NPStream* stream, NPReason reason); 150 const char* userAgent(); 151 #if ENABLE(NETSCAPE_PLUGIN_API) 152 static const char* userAgentStatic(); 153 #endif 154 void status(const char* message); 155 NPError getValue(NPNVariable variable, void* value); 156 #if ENABLE(NETSCAPE_PLUGIN_API) 157 static NPError getValueStatic(NPNVariable variable, void* value); 158 #endif 159 NPError setValue(NPPVariable variable, void* value); 160 void invalidateRect(NPRect*); 161 void invalidateRegion(NPRegion); 162 void forceRedraw(); 163 void pushPopupsEnabledState(bool state); 164 void popPopupsEnabledState(); 165 #ifdef PLUGIN_SCHEDULE_TIMER 166 uint32 scheduleTimer(NPP, uint32 interval, bool repeat, 167 void (*timerFunc)(NPP, uint32 timerID)); 168 void unscheduleTimer(NPP, uint32 timerID); 169 #endif 170 171 virtual void invalidateRect(const IntRect&); 172 173 bool arePopupsAllowed() const; 174 175 void setJavaScriptPaused(bool); 176 177 void disconnectStream(PluginStream*); streamDidFinishLoading(PluginStream * stream)178 void streamDidFinishLoading(PluginStream* stream) { disconnectStream(stream); } 179 180 // Widget functions 181 virtual void setFrameRect(const IntRect&); 182 virtual void frameRectsChanged(); 183 virtual void setFocus(); 184 virtual void show(); 185 virtual void hide(); 186 virtual void paint(GraphicsContext*, const IntRect&); 187 188 // This method is used by plugins on all platforms to obtain a clip rect that includes clips set by WebCore, 189 // e.g., in overflow:auto sections. The clip rects coordinates are in the containing window's coordinate space. 190 // This clip includes any clips that the widget itself sets up for its children. 191 IntRect windowClipRect() const; 192 193 virtual void handleEvent(Event*); 194 virtual void setParent(ScrollView*); 195 virtual void setParentVisible(bool); 196 isPluginView()197 virtual bool isPluginView() const { return true; } 198 parentFrame()199 Frame* parentFrame() const { return m_parentFrame; } 200 201 void focusPluginElement(); 202 pluginsPage()203 const String& pluginsPage() const { return m_pluginsPage; } mimeType()204 const String& mimeType() const { return m_mimeType; } url()205 const KURL& url() const { return m_url; } 206 207 #if PLATFORM(WIN_OS) && !PLATFORM(WX) && ENABLE(NETSCAPE_PLUGIN_API) 208 static LRESULT CALLBACK PluginViewWndProc(HWND, UINT, WPARAM, LPARAM); 209 LRESULT wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); pluginWndProc()210 WNDPROC pluginWndProc() const { return m_pluginWndProc; } 211 #endif 212 213 // Used for manual loading 214 void didReceiveResponse(const ResourceResponse&); 215 void didReceiveData(const char*, int); 216 void didFinishLoading(); 217 void didFail(const ResourceError&); 218 219 static bool isCallingPlugin(); 220 221 #ifdef ANDROID_PLUGINS getParentFrame()222 Frame* getParentFrame() const { return m_parentFrame; } getElement()223 Element* getElement() const { return m_element; } 224 #endif 225 226 bool start(); 227 228 private: 229 PluginView(Frame* parentFrame, const IntSize&, PluginPackage*, Element*, const KURL&, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually); 230 231 void setParameters(const Vector<String>& paramNames, const Vector<String>& paramValues); 232 bool startOrAddToUnstartedList(); 233 void removeFromUnstartedListIfNecessary(); 234 void init(); 235 void platformStart(); 236 void stop(); 237 static void setCurrentPluginView(PluginView*); 238 NPError load(const FrameLoadRequest&, bool sendNotification, void* notifyData); 239 NPError handlePost(const char* url, const char* target, uint32 len, const char* buf, bool file, void* notifyData, bool sendNotification, bool allowHeaders); 240 NPError handlePostReadFile(Vector<char>& buffer, uint32 len, const char* buf); 241 static void freeStringArray(char** stringArray, int length); 242 void setCallingPlugin(bool) const; 243 244 void invalidateWindowlessPluginRect(const IntRect&); 245 246 #if PLATFORM(WIN_OS) && !PLATFORM(WX) && ENABLE(NETSCAPE_PLUGIN_API) 247 void paintWindowedPluginIntoContext(GraphicsContext*, const IntRect&) const; 248 static HDC WINAPI hookedBeginPaint(HWND, PAINTSTRUCT*); 249 static BOOL WINAPI hookedEndPaint(HWND, const PAINTSTRUCT*); 250 #endif 251 252 Frame* m_parentFrame; 253 RefPtr<PluginPackage> m_plugin; 254 Element* m_element; 255 bool m_isStarted; 256 KURL m_url; 257 KURL m_baseURL; 258 PluginStatus m_status; 259 Vector<IntRect> m_invalidRects; 260 261 void performRequest(PluginRequest*); 262 void scheduleRequest(PluginRequest*); 263 void requestTimerFired(Timer<PluginView>*); 264 void invalidateTimerFired(Timer<PluginView>*); 265 Timer<PluginView> m_requestTimer; 266 Timer<PluginView> m_invalidateTimer; 267 268 void popPopupsStateTimerFired(Timer<PluginView>*); 269 Timer<PluginView> m_popPopupsStateTimer; 270 271 #ifndef NP_NO_CARBON 272 bool dispatchNPEvent(NPEvent&); 273 #endif 274 void updatePluginWidget(); 275 void paintMissingPluginIcon(GraphicsContext*, const IntRect&); 276 277 void handleKeyboardEvent(KeyboardEvent*); 278 void handleMouseEvent(MouseEvent*); 279 280 #ifdef ANDROID_PLUGINS 281 void handleTouchEvent(TouchEvent*); 282 // called at the end of the base constructor 283 void platformInit(); 284 #endif 285 #ifdef PLUGIN_PLATFORM_SETVALUE 286 // called if the default setValue does not recognize the variable 287 NPError platformSetValue(NPPVariable variable, void* value); 288 #endif 289 290 int m_mode; 291 int m_paramCount; 292 char** m_paramNames; 293 char** m_paramValues; 294 String m_pluginsPage; 295 296 String m_mimeType; 297 CString m_userAgent; 298 299 NPP m_instance; 300 NPP_t m_instanceStruct; 301 NPWindow m_npWindow; 302 303 Vector<bool, 4> m_popupStateStack; 304 305 HashSet<RefPtr<PluginStream> > m_streams; 306 Vector<PluginRequest*> m_requests; 307 308 bool m_isWindowed; 309 bool m_isTransparent; 310 bool m_haveInitialized; 311 bool m_isWaitingToStart; 312 313 #if PLATFORM(GTK) || defined(Q_WS_X11) 314 bool m_needsXEmbed; 315 #endif 316 317 #if PLATFORM(WIN_OS) && !PLATFORM(WX) && ENABLE(NETSCAPE_PLUGIN_API) 318 OwnPtr<PluginMessageThrottlerWin> m_messageThrottler; 319 WNDPROC m_pluginWndProc; 320 unsigned m_lastMessage; 321 bool m_isCallingPluginWndProc; 322 HDC m_wmPrintHDC; 323 bool m_haveUpdatedPluginWidget; 324 #endif 325 326 #ifdef PLUGIN_SCHEDULE_TIMER 327 PluginTimerList m_timerList; 328 #endif 329 330 #if (PLATFORM(QT) && PLATFORM(WIN_OS)) || defined(XP_MACOSX) 331 // On Mac OSX and Qt/Windows the plugin does not have its own native widget, 332 // but is using the containing window as its reference for positioning/painting. 333 PlatformPluginWidget m_window; 334 public: platformPluginWidget()335 PlatformPluginWidget platformPluginWidget() const { return m_window; } setPlatformPluginWidget(PlatformPluginWidget widget)336 void setPlatformPluginWidget(PlatformPluginWidget widget) { m_window = widget; } 337 #elif defined(ANDROID_PLUGINS) 338 public: 339 PlatformPluginWidget m_window; platformPluginWidget()340 PlatformPluginWidget platformPluginWidget() const { return m_window; } // MANUAL MERGE FIXME 341 #else 342 public: platformPluginWidget()343 PlatformPluginWidget platformPluginWidget() const { return platformWidget(); } 344 #endif 345 346 private: 347 348 #if PLATFORM(GTK) || defined(Q_WS_X11) 349 void setNPWindowIfNeeded(); 350 #elif defined(XP_MACOSX) 351 NP_CGContext m_npCgContext; 352 OwnPtr<Timer<PluginView> > m_nullEventTimer; 353 NPDrawingModel m_drawingModel; 354 NPEventModel m_eventModel; 355 356 void setNPWindowIfNeeded(); 357 void nullEventTimerFired(Timer<PluginView>*); 358 Point globalMousePosForPlugin() const; 359 #endif 360 361 #if defined(Q_WS_X11) 362 bool m_hasPendingGeometryChange; 363 #endif 364 365 IntRect m_clipRect; // The clip rect to apply to a windowed plug-in 366 IntRect m_windowRect; // Our window rect. 367 368 bool m_loadManually; 369 RefPtr<PluginStream> m_manualStream; 370 371 bool m_isJavaScriptPaused; 372 373 static PluginView* s_currentPluginView; 374 }; 375 376 } // namespace WebCore 377 378 #endif 379