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)) 57typedef struct HWND__* HWND; 58typedef HWND PlatformPluginWidget; 59#elif defined(ANDROID_PLUGINS) 60typedef struct PluginWidgetAndroid* PlatformPluginWidget; 61#else 62typedef PlatformWidget PlatformPluginWidget; 63#if defined(XP_MACOSX) && PLATFORM(QT) 64#include <QPixmap> 65#endif 66#endif 67 68#if USE(JSC) 69namespace JSC { 70 namespace Bindings { 71 class Instance; 72 } 73} 74#endif 75 76class NPObject; 77 78namespace 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: 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: 111 const FrameLoadRequest& frameLoadRequest() const { return m_frameLoadRequest; } 112 void* notifyData() const { return m_notifyData; } 113 bool sendNotification() const { return m_sendNotification; } 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: 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 136 PluginPackage* plugin() const { return m_plugin.get(); } 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 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*); 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 205 virtual bool isPluginView() const { return true; } 206 207 Frame* parentFrame() const { return m_parentFrame.get(); } 208 209 void focusPluginElement(); 210 211 const String& pluginsPage() const { return m_pluginsPage; } 212 const String& mimeType() const { return m_mimeType; } 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); 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; 231 virtual bool isWindowed() const { return m_isWindowed; } 232 virtual String pluginName() const; 233 234 bool isHalted() const { return m_isHalted; } 235 bool hasBeenHalted() const { return m_hasBeenHalted; } 236 237 static bool isCallingPlugin(); 238 239#ifdef ANDROID_PLUGINS 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; 370public: 371 PlatformPluginWidget platformPluginWidget() const { return m_window; } 372 void setPlatformPluginWidget(PlatformPluginWidget widget) { m_window = widget; } 373#elif defined(ANDROID_PLUGINS) 374public: 375 PlatformPluginWidget m_window; 376 PlatformPluginWidget platformPluginWidget() const { return m_window; } // MANUAL MERGE FIXME 377#else 378public: 379 void setPlatformPluginWidget(PlatformPluginWidget widget) { setPlatformWidget(widget); } 380 PlatformPluginWidget platformPluginWidget() const { return platformWidget(); } 381#endif 382 383private: 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