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@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 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 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 "IntRect.h" 33#include "MediaCanStartListener.h" 34#include "PluginViewBase.h" 35#include "ResourceRequest.h" 36#include "Timer.h" 37#include <wtf/HashMap.h> 38#include <wtf/HashSet.h> 39#include <wtf/OwnPtr.h> 40#include <wtf/PassRefPtr.h> 41#include <wtf/RefPtr.h> 42#include <wtf/Vector.h> 43#include <wtf/text/CString.h> 44 45#if ENABLE(NETSCAPE_PLUGIN_API) 46#include "PluginStream.h" 47#include "npruntime_internal.h" 48#endif 49 50#if OS(WINDOWS) && PLATFORM(GTK) 51typedef struct HWND__* HWND; 52typedef HWND PlatformPluginWidget; 53#else 54typedef PlatformWidget PlatformPluginWidget; 55#endif 56#if PLATFORM(GTK) 57typedef struct _GtkSocket GtkSocket; 58#endif 59 60#if PLATFORM(X11) 61typedef unsigned long Window; 62typedef struct _XDisplay Display; 63#endif 64 65namespace JSC { 66 namespace Bindings { 67 class Instance; 68 } 69} 70 71namespace WebCore { 72 class Frame; 73 class FrameView; 74 class Image; 75 class HTMLPlugInElement; 76 class KeyboardEvent; 77 class MouseEvent; 78 class URL; 79#if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API) 80 class PluginMessageThrottlerWin; 81#endif 82 class PluginPackage; 83 class PluginRequest; 84 class PluginStream; 85 class ResourceError; 86 class ResourceResponse; 87 class WheelEvent; 88 89 enum PluginStatus { 90 PluginStatusCanNotFindPlugin, 91 PluginStatusCanNotLoadPlugin, 92 PluginStatusLoadedSuccessfully 93 }; 94 95 class PluginRequest { 96 WTF_MAKE_NONCOPYABLE(PluginRequest); WTF_MAKE_FAST_ALLOCATED; 97 public: 98 PluginRequest(const FrameLoadRequest& frameLoadRequest, bool sendNotification, void* notifyData, bool shouldAllowPopups) 99 : m_frameLoadRequest(frameLoadRequest) 100 , m_notifyData(notifyData) 101 , m_sendNotification(sendNotification) 102 , m_shouldAllowPopups(shouldAllowPopups) { } 103 public: 104 const FrameLoadRequest& frameLoadRequest() const { return m_frameLoadRequest; } 105 void* notifyData() const { return m_notifyData; } 106 bool sendNotification() const { return m_sendNotification; } 107 bool shouldAllowPopups() const { return m_shouldAllowPopups; } 108 private: 109 FrameLoadRequest m_frameLoadRequest; 110 void* m_notifyData; 111 bool m_sendNotification; 112 bool m_shouldAllowPopups; 113 }; 114 115 class PluginManualLoader { 116 public: 117 virtual ~PluginManualLoader() {} 118 virtual void didReceiveResponse(const ResourceResponse&) = 0; 119 virtual void didReceiveData(const char*, int) = 0; 120 virtual void didFinishLoading() = 0; 121 virtual void didFail(const ResourceError&) = 0; 122 }; 123 124 class PluginView : public PluginViewBase 125#if ENABLE(NETSCAPE_PLUGIN_API) 126 , private PluginStreamClient 127#endif 128 , public PluginManualLoader 129 , private MediaCanStartListener { 130 public: 131 static PassRefPtr<PluginView> create(Frame* parentFrame, const IntSize&, HTMLPlugInElement*, const URL&, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually); 132 virtual ~PluginView(); 133 134 PluginPackage* plugin() const { return m_plugin.get(); } 135#if ENABLE(NETSCAPE_PLUGIN_API) 136 NPP instance() const { return m_instance; } 137#endif 138 139 void setNPWindowRect(const IntRect&); 140 static PluginView* currentPluginView(); 141 142#if ENABLE(NETSCAPE_PLUGIN_API) 143 NPObject* npObject(); 144#endif 145 PassRefPtr<JSC::Bindings::Instance> bindingInstance(); 146 147 PluginStatus status() const { return m_status; } 148 149#if ENABLE(NETSCAPE_PLUGIN_API) 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_t len, const char* but, NPBool file, void* notifyData); 154 NPError postURL(const char* url, const char* target, uint32_t len, const char* but, NPBool file); 155 NPError newStream(NPMIMEType type, const char* target, NPStream** stream); 156 int32_t write(NPStream* stream, int32_t len, void* buffer); 157 NPError destroyStream(NPStream* stream, NPReason reason); 158#endif 159 const char* userAgent(); 160#if ENABLE(NETSCAPE_PLUGIN_API) 161 static const char* userAgentStatic(); 162#endif 163 void status(const char* message); 164 165#if ENABLE(NETSCAPE_PLUGIN_API) 166 NPError getValue(NPNVariable variable, void* value); 167 static NPError getValueStatic(NPNVariable variable, void* value); 168 NPError setValue(NPPVariable variable, void* value); 169 NPError getValueForURL(NPNURLVariable variable, const char* url, char** value, uint32_t* len); 170 NPError setValueForURL(NPNURLVariable variable, const char* url, const char* value, uint32_t len); 171 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); 172 void invalidateRect(NPRect*); 173 void invalidateRegion(NPRegion); 174#endif 175 void forceRedraw(); 176 void pushPopupsEnabledState(bool state); 177 void popPopupsEnabledState(); 178 179 virtual void invalidateRect(const IntRect&); 180 181 bool arePopupsAllowed() const; 182 183 void setJavaScriptPaused(bool); 184 185 void privateBrowsingStateChanged(bool); 186 187 void disconnectStream(PluginStream*); 188 void streamDidFinishLoading(PluginStream* stream) { disconnectStream(stream); } 189 190 // Widget functions 191 virtual void setFrameRect(const IntRect&); 192 virtual void frameRectsChanged(); 193 virtual void setFocus(bool); 194 virtual void show(); 195 virtual void hide(); 196 virtual void paint(GraphicsContext*, const IntRect&); 197 virtual void clipRectChanged() override; 198 199 // This method is used by plugins on all platforms to obtain a clip rect that includes clips set by WebCore, 200 // e.g., in overflow:auto sections. The clip rects coordinates are in the containing window's coordinate space. 201 // This clip includes any clips that the widget itself sets up for its children. 202 IntRect windowClipRect() const; 203 204 virtual void handleEvent(Event*); 205 virtual void setParent(ScrollView*); 206 virtual void setParentVisible(bool); 207 208 virtual bool isPluginView() const override { return true; } 209 210 Frame* parentFrame() const { return m_parentFrame.get(); } 211 212 void focusPluginElement(); 213 214 const String& pluginsPage() const { return m_pluginsPage; } 215 const String& mimeType() const { return m_mimeType; } 216 const URL& url() const { return m_url; } 217 218#if defined(XP_MACOSX) && ENABLE(NETSCAPE_PLUGIN_API) 219 bool popUpContextMenu(NPMenu*); 220#endif 221 222#if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API) 223 static LRESULT CALLBACK PluginViewWndProc(HWND, UINT, WPARAM, LPARAM); 224 LRESULT wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); 225 WNDPROC pluginWndProc() const { return m_pluginWndProc; } 226#endif 227 228 // Used for manual loading 229 void didReceiveResponse(const ResourceResponse&); 230 void didReceiveData(const char*, int); 231 void didFinishLoading(); 232 void didFail(const ResourceError&); 233 234 static bool isCallingPlugin(); 235 236 bool start(); 237 238#if ENABLE(NETSCAPE_PLUGIN_API) 239 static void keepAlive(NPP); 240#endif 241 void keepAlive(); 242 243#if PLATFORM(X11) 244 static Display* getPluginDisplay(Frame*); 245 static Window getRootWindow(Frame* parentFrame); 246#endif 247 248 private: 249 PluginView(Frame* parentFrame, const IntSize&, PluginPackage*, HTMLPlugInElement*, const URL&, 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 init(); 254 bool platformStart(); 255 void stop(); 256 void platformDestroy(); 257 static void setCurrentPluginView(PluginView*); 258#if ENABLE(NETSCAPE_PLUGIN_API) 259 NPError load(const FrameLoadRequest&, bool sendNotification, void* notifyData); 260 NPError handlePost(const char* url, const char* target, uint32_t len, const char* buf, bool file, void* notifyData, bool sendNotification, bool allowHeaders); 261 NPError handlePostReadFile(Vector<char>& buffer, uint32_t len, const char* buf); 262#endif 263 static void freeStringArray(char** stringArray, int length); 264 void setCallingPlugin(bool) const; 265 266 void invalidateWindowlessPluginRect(const IntRect&); 267 268 virtual void mediaCanStart(); 269 270#if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API) 271 void paintWindowedPluginIntoContext(GraphicsContext*, const IntRect&); 272 static HDC WINAPI hookedBeginPaint(HWND, PAINTSTRUCT*); 273 static BOOL WINAPI hookedEndPaint(HWND, const PAINTSTRUCT*); 274#endif 275 276#if ENABLE(NETSCAPE_PLUGIN_API) 277 static bool platformGetValueStatic(NPNVariable variable, void* value, NPError* result); 278 bool platformGetValue(NPNVariable variable, void* value, NPError* result); 279#endif 280 281 RefPtr<Frame> m_parentFrame; 282 RefPtr<PluginPackage> m_plugin; 283 HTMLPlugInElement* m_element; 284 bool m_isStarted; 285 URL m_url; 286 PluginStatus m_status; 287 Vector<IntRect> m_invalidRects; 288 289 void performRequest(PluginRequest*); 290 void scheduleRequest(PassOwnPtr<PluginRequest>); 291 void requestTimerFired(Timer<PluginView>*); 292 void invalidateTimerFired(Timer<PluginView>*); 293 Timer<PluginView> m_requestTimer; 294 Timer<PluginView> m_invalidateTimer; 295 296 void popPopupsStateTimerFired(Timer<PluginView>*); 297 Timer<PluginView> m_popPopupsStateTimer; 298 299 void lifeSupportTimerFired(Timer<PluginView>*); 300 Timer<PluginView> m_lifeSupportTimer; 301 302#if ENABLE(NETSCAPE_PLUGIN_API) 303 bool dispatchNPEvent(NPEvent&); 304#endif 305#if defined(XP_MACOSX) && ENABLE(NETSCAPE_PLUGIN_API) 306 int16_t dispatchNPCocoaEvent(NPCocoaEvent&); 307 bool m_updatedCocoaTextInputRequested; 308 bool m_keyDownSent; 309 uint16_t m_disregardKeyUpCounter; 310#endif 311 312#if defined(XP_MACOSX) 313 void handleWheelEvent(WheelEvent*); 314#endif 315 void updatePluginWidget(); 316 void paintMissingPluginIcon(GraphicsContext*, const IntRect&); 317 318 void handleKeyboardEvent(KeyboardEvent*); 319 void handleMouseEvent(MouseEvent*); 320#if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API) 321 void handleFocusInEvent(); 322 void handleFocusOutEvent(); 323#endif 324 325#if OS(WINDOWS) 326 void paintIntoTransformedContext(HDC); 327 PassRefPtr<Image> snapshot(); 328#endif 329 330 int m_mode; 331 int m_paramCount; 332 char** m_paramNames; 333 char** m_paramValues; 334 String m_pluginsPage; 335 336 String m_mimeType; 337 WTF::CString m_userAgent; 338 339#if ENABLE(NETSCAPE_PLUGIN_API) 340 NPP m_instance; 341 NPP_t m_instanceStruct; 342 NPWindow m_npWindow; 343#endif 344 345 Vector<bool, 4> m_popupStateStack; 346 347 HashSet<RefPtr<PluginStream> > m_streams; 348 Vector<OwnPtr<PluginRequest> > m_requests; 349 350 bool m_isWindowed; 351 bool m_isTransparent; 352 bool m_haveInitialized; 353 bool m_isWaitingToStart; 354 355#if defined(XP_UNIX) 356 bool m_needsXEmbed; 357#endif 358 359#if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API) 360 OwnPtr<PluginMessageThrottlerWin> m_messageThrottler; 361 WNDPROC m_pluginWndProc; 362 unsigned m_lastMessage; 363 bool m_isCallingPluginWndProc; 364 HDC m_wmPrintHDC; 365 bool m_haveUpdatedPluginWidget; 366#endif 367 368#if (PLATFORM(GTK) && OS(WINDOWS)) || PLATFORM(EFL) 369 // On Mac OSX and Qt/Windows the plugin does not have its own native widget, 370 // but is using the containing window as its reference for positioning/painting. 371 PlatformPluginWidget m_window; 372public: 373 PlatformPluginWidget platformPluginWidget() const { return m_window; } 374 void setPlatformPluginWidget(PlatformPluginWidget widget) { m_window = widget; } 375#else 376public: 377 void setPlatformPluginWidget(PlatformPluginWidget widget) { setPlatformWidget(widget); } 378 PlatformPluginWidget platformPluginWidget() const { return platformWidget(); } 379#endif 380 381private: 382 383#if defined(XP_UNIX) || PLATFORM(GTK) 384 void setNPWindowIfNeeded(); 385#elif defined(XP_MACOSX) 386 NP_CGContext m_npCgContext; 387 CGContextRef m_contextRef; 388 389 void setNPWindowIfNeeded(); 390#endif 391 392#if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API) 393 bool m_hasPendingGeometryChange; 394 Pixmap m_drawable; 395 Visual* m_visual; 396 Colormap m_colormap; 397 Display* m_pluginDisplay; 398 399 void initXEvent(XEvent* event); 400#endif 401 402#if PLATFORM(GTK) 403 static gboolean plugRemovedCallback(GtkSocket*, PluginView*); 404 static void plugAddedCallback(GtkSocket*, PluginView*); 405 void updateWidgetAllocationAndClip(); 406 bool m_plugAdded; 407 IntRect m_delayedAllocation; 408#endif 409 410 IntRect m_clipRect; // The clip rect to apply to a windowed plug-in 411 IntRect m_windowRect; // Our window rect. 412 413 bool m_loadManually; 414 RefPtr<PluginStream> m_manualStream; 415 416 bool m_isJavaScriptPaused; 417 418 bool m_haveCalledSetWindow; 419 420 static PluginView* s_currentPluginView; 421 }; 422 423inline PluginView* toPluginView(Widget* widget) 424{ 425 ASSERT(!widget || widget->isPluginView()); 426 return static_cast<PluginView*>(widget); 427} 428 429inline const PluginView* toPluginView(const Widget* widget) 430{ 431 ASSERT(!widget || widget->isPluginView()); 432 return static_cast<const PluginView*>(widget); 433} 434 435// This will catch anyone doing an unnecessary cast. 436void toPluginView(const PluginView*); 437 438} // namespace WebCore 439 440#endif 441