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