1/*
2 * Copyright (C) 2010 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef NetscapePlugin_h
27#define NetscapePlugin_h
28
29#if ENABLE(NETSCAPE_PLUGIN_API)
30
31#include "NetscapePluginModule.h"
32#include "Plugin.h"
33#include <WebCore/AffineTransform.h>
34#include <WebCore/GraphicsLayer.h>
35#include <WebCore/IntRect.h>
36#include <WebCore/RunLoop.h>
37#include <wtf/HashMap.h>
38#include <wtf/text/CString.h>
39#include <wtf/text/StringHash.h>
40
41namespace WebCore {
42    class HTTPHeaderMap;
43    class ProtectionSpace;
44    class SharedBuffer;
45}
46
47OBJC_CLASS WKNPAPIPlugInContainer;
48
49namespace WebKit {
50
51class NetscapePluginStream;
52
53class NetscapePlugin : public Plugin {
54public:
55    static PassRefPtr<NetscapePlugin> create(PassRefPtr<NetscapePluginModule> pluginModule);
56    virtual ~NetscapePlugin();
57
58    static PassRefPtr<NetscapePlugin> fromNPP(NPP);
59
60    // In-process NetscapePlugins don't support asynchronous initialization.
61    virtual bool isBeingAsynchronouslyInitialized() const { return false; }
62
63#if PLATFORM(MAC)
64    NPError setDrawingModel(NPDrawingModel);
65    NPError setEventModel(NPEventModel);
66    NPBool convertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double& destX, double& destY, NPCoordinateSpace destSpace);
67    NPError popUpContextMenu(NPMenu*);
68
69    void setPluginReturnsNonretainedLayer(bool pluginReturnsNonretainedLayer) { m_pluginReturnsNonretainedLayer = pluginReturnsNonretainedLayer; }
70    void setPluginWantsLegacyCocoaTextInput(bool pluginWantsLegacyCocoaTextInput) { m_pluginWantsLegacyCocoaTextInput = pluginWantsLegacyCocoaTextInput; }
71
72    bool hasHandledAKeyDownEvent() const { return m_hasHandledAKeyDownEvent; }
73
74    mach_port_t compositingRenderServerPort();
75    void openPluginPreferencePane();
76
77    // Computes an affine transform from the given coordinate space to the screen coordinate space.
78    bool getScreenTransform(NPCoordinateSpace sourceSpace, WebCore::AffineTransform&);
79
80    WKNPAPIPlugInContainer* plugInContainer();
81
82#ifndef NP_NO_CARBON
83    WindowRef windowRef() const;
84    bool isWindowActive() const { return m_windowHasFocus; }
85    void updateFakeWindowBounds();
86
87    static NetscapePlugin* netscapePluginFromWindow(WindowRef);
88    static unsigned buttonState();
89#endif
90
91#endif
92
93    PluginQuirks quirks() const { return m_pluginModule->pluginQuirks(); }
94
95    void invalidate(const NPRect*);
96    static const char* userAgent(NPP);
97    void loadURL(const String& method, const String& urlString, const String& target, const WebCore::HTTPHeaderMap& headerFields,
98                 const Vector<uint8_t>& httpBody, bool sendNotification, void* notificationData);
99    NPError destroyStream(NPStream*, NPReason);
100    void setIsWindowed(bool);
101    void setIsTransparent(bool);
102    void setStatusbarText(const String&);
103    static void setException(const String&);
104    bool evaluate(NPObject*, const String&scriptString, NPVariant* result);
105    bool isPrivateBrowsingEnabled();
106
107    static void setSetExceptionFunction(void (*)(const String&));
108
109    // These return retained objects.
110    NPObject* windowScriptNPObject();
111    NPObject* pluginElementNPObject();
112
113    void cancelStreamLoad(NetscapePluginStream*);
114    void removePluginStream(NetscapePluginStream*);
115
116    bool isAcceleratedCompositingEnabled();
117
118    void pushPopupsEnabledState(bool enabled);
119    void popPopupsEnabledState();
120
121    void pluginThreadAsyncCall(void (*function)(void*), void* userData);
122
123    // Called on the plug-in run loop (which is currently the main thread run loop).
124    void handlePluginThreadAsyncCall(void (*function)(void*), void* userData);
125
126    unsigned scheduleTimer(unsigned interval, bool repeat, void (*timerFunc)(NPP, unsigned timerID));
127    void unscheduleTimer(unsigned timerID);
128
129    double contentsScaleFactor();
130    String proxiesForURL(const String& urlString);
131    String cookiesForURL(const String& urlString);
132    void setCookiesForURL(const String& urlString, const String& cookieString);
133    bool getAuthenticationInfo(const WebCore::ProtectionSpace&, String& username, String& password);
134
135    // Member functions for calling into the plug-in.
136    NPError NPP_New(NPMIMEType pluginType, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData*);
137    NPError NPP_Destroy(NPSavedData**);
138    NPError NPP_SetWindow(NPWindow*);
139    NPError NPP_NewStream(NPMIMEType, NPStream*, NPBool seekable, uint16_t* stype);
140    NPError NPP_DestroyStream(NPStream*, NPReason);
141    void NPP_StreamAsFile(NPStream*, const char* filename);
142    int32_t NPP_WriteReady(NPStream*);
143    int32_t NPP_Write(NPStream*, int32_t offset, int32_t len, void* buffer);
144    int16_t NPP_HandleEvent(void* event);
145    void NPP_URLNotify(const char* url, NPReason, void* notifyData);
146    NPError NPP_GetValue(NPPVariable, void *value);
147    NPError NPP_SetValue(NPNVariable, void *value);
148
149private:
150    NetscapePlugin(PassRefPtr<NetscapePluginModule> pluginModule);
151
152    void callSetWindow();
153    void callSetWindowInvisible();
154    bool shouldLoadSrcURL();
155    NetscapePluginStream* streamFromID(uint64_t streamID);
156    void stopAllStreams();
157    bool allowPopups() const;
158
159    const char* userAgent();
160
161    void platformPreInitialize();
162    bool platformPostInitialize();
163    void platformDestroy();
164    bool platformInvalidate(const WebCore::IntRect&);
165    void platformGeometryDidChange();
166    void platformVisibilityDidChange();
167    void platformPaint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect, bool isSnapshot = false);
168
169    bool platformHandleMouseEvent(const WebMouseEvent&);
170    bool platformHandleWheelEvent(const WebWheelEvent&);
171    bool platformHandleMouseEnterEvent(const WebMouseEvent&);
172    bool platformHandleMouseLeaveEvent(const WebMouseEvent&);
173    bool platformHandleKeyboardEvent(const WebKeyboardEvent&);
174    void platformSetFocus(bool);
175
176    static bool wantsPluginRelativeNPWindowCoordinates();
177
178    // Plugin
179    virtual bool initialize(const Parameters&);
180    virtual void destroy();
181    virtual void paint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect);
182    virtual PassRefPtr<ShareableBitmap> snapshot();
183#if PLATFORM(MAC)
184    virtual PlatformLayer* pluginLayer();
185#endif
186    virtual bool isTransparent();
187    virtual bool wantsWheelEvents() OVERRIDE;
188    virtual void geometryDidChange(const WebCore::IntSize& pluginSize, const WebCore::IntRect& clipRect, const WebCore::AffineTransform& pluginToRootViewTransform);
189    virtual void visibilityDidChange();
190    virtual void frameDidFinishLoading(uint64_t requestID);
191    virtual void frameDidFail(uint64_t requestID, bool wasCancelled);
192    virtual void didEvaluateJavaScript(uint64_t requestID, const String& result);
193    virtual void streamDidReceiveResponse(uint64_t streamID, const WebCore::KURL& responseURL, uint32_t streamLength,
194                                          uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& suggestedFileName);
195    virtual void streamDidReceiveData(uint64_t streamID, const char* bytes, int length);
196    virtual void streamDidFinishLoading(uint64_t streamID);
197    virtual void streamDidFail(uint64_t streamID, bool wasCancelled);
198    virtual void manualStreamDidReceiveResponse(const WebCore::KURL& responseURL, uint32_t streamLength,
199                                                uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& suggestedFileName);
200    virtual void manualStreamDidReceiveData(const char* bytes, int length);
201    virtual void manualStreamDidFinishLoading();
202    virtual void manualStreamDidFail(bool wasCancelled);
203
204    virtual bool handleMouseEvent(const WebMouseEvent&);
205    virtual bool handleWheelEvent(const WebWheelEvent&);
206    virtual bool handleMouseEnterEvent(const WebMouseEvent&);
207    virtual bool handleMouseLeaveEvent(const WebMouseEvent&);
208    virtual bool handleContextMenuEvent(const WebMouseEvent&);
209    virtual bool handleKeyboardEvent(const WebKeyboardEvent&);
210    virtual void setFocus(bool);
211
212    virtual bool handleEditingCommand(const String& commandName, const String& argument) OVERRIDE;
213    virtual bool isEditingCommandEnabled(const String&) OVERRIDE;
214
215    virtual bool shouldAllowScripting() OVERRIDE;
216    virtual bool shouldAllowNavigationFromDrags() OVERRIDE;
217
218    virtual bool handlesPageScaleFactor() OVERRIDE;
219
220    virtual NPObject* pluginScriptableNPObject();
221
222    virtual unsigned countFindMatches(const String&, WebCore::FindOptions, unsigned maxMatchCount) OVERRIDE;
223    virtual bool findString(const String&, WebCore::FindOptions, unsigned maxMatchCount) OVERRIDE;
224
225#if PLATFORM(MAC)
226    virtual void windowFocusChanged(bool);
227    virtual void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates);
228    virtual void windowVisibilityChanged(bool);
229
230    virtual uint64_t pluginComplexTextInputIdentifier() const;
231    virtual void sendComplexTextInput(const String& textInput);
232    virtual void setLayerHostingMode(LayerHostingMode) OVERRIDE;
233
234    void pluginFocusOrWindowFocusChanged();
235    void setComplexTextInputEnabled(bool);
236
237    void updatePluginLayer();
238#endif
239
240    virtual void contentsScaleFactorChanged(float);
241    virtual void storageBlockingStateChanged(bool);
242    virtual void privateBrowsingStateChanged(bool);
243    virtual bool getFormValue(String& formValue);
244    virtual bool handleScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity);
245    virtual WebCore::Scrollbar* horizontalScrollbar();
246    virtual WebCore::Scrollbar* verticalScrollbar();
247
248    virtual bool supportsSnapshotting() const;
249
250    // Convert the given point from plug-in coordinates to root view coordinates.
251    virtual WebCore::IntPoint convertToRootView(const WebCore::IntPoint&) const OVERRIDE;
252
253    // Convert the given point from root view coordinates to plug-in coordinates. Returns false if the point can't be
254    // converted (if the transformation matrix isn't invertible).
255    bool convertFromRootView(const WebCore::IntPoint& pointInRootViewCoordinates, WebCore::IntPoint& pointInPluginCoordinates);
256
257    virtual PassRefPtr<WebCore::SharedBuffer> liveResourceData() const OVERRIDE;
258
259    virtual bool performDictionaryLookupAtLocation(const WebCore::FloatPoint&) OVERRIDE { return false; }
260
261    virtual String getSelectionString() const OVERRIDE { return String(); }
262
263    void updateNPNPrivateMode();
264
265#if PLUGIN_ARCHITECTURE(WIN)
266    static BOOL WINAPI hookedTrackPopupMenu(HMENU, UINT uFlags, int x, int y, int nReserved, HWND, const RECT*);
267    void scheduleWindowedGeometryUpdate();
268#endif
269
270#if PLUGIN_ARCHITECTURE(X11)
271    bool platformPostInitializeWindowed(bool needsXEmbed, uint64_t windowID);
272    bool platformPostInitializeWindowless();
273#endif
274
275    uint64_t m_nextRequestID;
276
277    typedef HashMap<uint64_t, std::pair<String, void*>> PendingURLNotifyMap;
278    PendingURLNotifyMap m_pendingURLNotifications;
279
280    typedef HashMap<uint64_t, RefPtr<NetscapePluginStream>> StreamsMap;
281    StreamsMap m_streams;
282
283    RefPtr<NetscapePluginModule> m_pluginModule;
284    NPP_t m_npp;
285    NPWindow m_npWindow;
286
287    WebCore::IntSize m_pluginSize;
288
289    // The clip rect in plug-in coordinates.
290    WebCore::IntRect m_clipRect;
291
292    // A transform that can be used to convert from root view coordinates to plug-in coordinates.
293    WebCore::AffineTransform m_pluginToRootViewTransform;
294
295    // FIXME: Get rid of these.
296    WebCore::IntRect m_frameRectInWindowCoordinates;
297
298    CString m_userAgent;
299
300    bool m_isStarted;
301    bool m_isWindowed;
302    bool m_isTransparent;
303    bool m_inNPPNew;
304    bool m_shouldUseManualLoader;
305    bool m_hasCalledSetWindow;
306
307    RefPtr<NetscapePluginStream> m_manualStream;
308    Vector<bool, 8> m_popupEnabledStates;
309
310    class Timer {
311        WTF_MAKE_NONCOPYABLE(Timer);
312
313    public:
314        typedef void (*TimerFunc)(NPP, uint32_t timerID);
315
316        static PassOwnPtr<Timer> create(NetscapePlugin*, unsigned timerID, unsigned interval, bool repeat, TimerFunc);
317        ~Timer();
318
319        void start();
320        void stop();
321
322    private:
323        Timer(NetscapePlugin*, unsigned timerID, unsigned interval, bool repeat, TimerFunc);
324
325        void timerFired();
326
327        // This is a weak pointer since Timer objects are destroyed before the NetscapePlugin object itself is destroyed.
328        NetscapePlugin* m_netscapePlugin;
329
330        unsigned m_timerID;
331        unsigned m_interval;
332        bool m_repeat;
333        TimerFunc m_timerFunc;
334
335        WebCore::RunLoop::Timer<Timer> m_timer;
336    };
337    typedef HashMap<unsigned, OwnPtr<Timer>> TimerMap;
338    TimerMap m_timers;
339    unsigned m_nextTimerID;
340
341    bool m_privateBrowsingState;
342    bool m_storageBlockingState;
343
344#if PLUGIN_ARCHITECTURE(MAC)
345    NPDrawingModel m_drawingModel;
346    NPEventModel m_eventModel;
347
348    RetainPtr<PlatformLayer> m_pluginLayer;
349    bool m_pluginReturnsNonretainedLayer;
350    LayerHostingMode m_layerHostingMode;
351
352    NPCocoaEvent* m_currentMouseEvent;
353
354    bool m_pluginHasFocus;
355    bool m_windowHasFocus;
356
357    // Whether the plug-in wants to use the legacy Cocoa text input handling that
358    // existed in WebKit1, or the updated Cocoa text input handling specified on
359    // https://wiki.mozilla.org/NPAPI:CocoaEventModel#Text_Input
360    bool m_pluginWantsLegacyCocoaTextInput;
361
362    // Whether complex text input is enabled.
363    bool m_isComplexTextInputEnabled;
364
365    // Whether the plug-in has handled a keydown event. This is used to determine
366    // if we can tell the plug-in that we support the updated Cocoa text input specification.
367    bool m_hasHandledAKeyDownEvent;
368
369    // The number of NPCocoaEventKeyUp events that  should be ignored.
370    unsigned m_ignoreNextKeyUpEventCounter;
371
372    WebCore::IntRect m_windowFrameInScreenCoordinates;
373    WebCore::IntRect m_viewFrameInWindowCoordinates;
374
375    RetainPtr<WKNPAPIPlugInContainer> m_plugInContainer;
376
377#ifndef NP_NO_CARBON
378    void nullEventTimerFired();
379
380    // FIXME: It's a bit wasteful to have one null event timer per plug-in.
381    // We should investigate having one per window.
382    WebCore::RunLoop::Timer<NetscapePlugin> m_nullEventTimer;
383    NP_CGContext m_npCGContext;
384#endif
385#elif PLUGIN_ARCHITECTURE(WIN)
386    HWND m_window;
387    HWND m_contextMenuOwnerWindow;
388#elif PLUGIN_ARCHITECTURE(X11)
389    Pixmap m_drawable;
390    Display* m_pluginDisplay;
391#if PLATFORM(GTK)
392    GtkWidget* m_platformPluginWidget;
393#endif
394
395public: // Need to call it in the NPN_GetValue browser callback.
396    static Display* x11HostDisplay();
397#endif
398};
399
400} // namespace WebKit
401
402#endif // ENABLE(NETSCAPE_PLUGIN_API)
403
404#endif // NetscapePlugin_h
405