xref: /reactos/dll/win32/mshtml/npplugin.c (revision 1734f297)
1 /*
2  * Copyright 2010 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18 
19 #include "mshtml_private.h"
20 
21 /* Parts of npapi.h */
22 
23 #define NP_VERSION_MAJOR 0
24 #define NP_VERSION_MINOR 25
25 
26 typedef unsigned char NPBool;
27 typedef INT16 NPError;
28 typedef INT16 NPReason;
29 typedef char *NPMIMEType;
30 
31 typedef struct _NPP {
32     void *pdata;
33     void *ndata;
34 } NPP_t, *NPP;
35 
36 typedef struct _NPStream {
37     void *pdata;
38     void *ndata;
39     const char *url;
40     UINT32 end;
41     UINT32 lastmodified;
42     void *notifyData;
43     const char *headers;
44 } NPStream;
45 
46 typedef struct _NPSavedData {
47     INT32 len;
48     void *buf;
49 } NPSavedData;
50 
51 typedef struct _NPRect {
52     UINT16 top;
53     UINT16 left;
54     UINT16 bottom;
55     UINT16 right;
56 } NPRect;
57 
58 typedef enum {
59     NPFocusNext = 0,
60     NPFocusPrevious = 1
61 } NPFocusDirection;
62 
63 #define NP_ABI_MASK 0
64 
65 typedef enum {
66     NPPVpluginNameString = 1,
67     NPPVpluginDescriptionString,
68     NPPVpluginWindowBool,
69     NPPVpluginTransparentBool,
70     NPPVjavaClass,
71     NPPVpluginWindowSize,
72     NPPVpluginTimerInterval,
73     NPPVpluginScriptableInstance = (10 | NP_ABI_MASK),
74     NPPVpluginScriptableIID = 11,
75     NPPVjavascriptPushCallerBool = 12,
76     NPPVpluginKeepLibraryInMemory = 13,
77     NPPVpluginNeedsXEmbed = 14,
78     NPPVpluginScriptableNPObject = 15,
79     NPPVformValue = 16,
80     NPPVpluginUrlRequestsDisplayedBool = 17,
81     NPPVpluginWantsAllNetworkStreams = 18,
82     NPPVpluginNativeAccessibleAtkPlugId = 19,
83     NPPVpluginCancelSrcStream = 20,
84     NPPVSupportsAdvancedKeyHandling = 21
85 } NPPVariable;
86 
87 typedef enum {
88     NPNVxDisplay = 1,
89     NPNVxtAppContext,
90     NPNVnetscapeWindow,
91     NPNVjavascriptEnabledBool,
92     NPNVasdEnabledBool,
93     NPNVisOfflineBool,
94     NPNVserviceManager = (10 | NP_ABI_MASK),
95     NPNVDOMElement     = (11 | NP_ABI_MASK),
96     NPNVDOMWindow      = (12 | NP_ABI_MASK),
97     NPNVToolkit        = (13 | NP_ABI_MASK),
98     NPNVSupportsXEmbedBool = 14,
99     NPNVWindowNPObject = 15,
100     NPNVPluginElementNPObject = 16,
101     NPNVSupportsWindowless = 17,
102     NPNVprivateModeBool = 18,
103     NPNVsupportsAdvancedKeyHandling = 21
104 } NPNVariable;
105 
106 typedef enum {
107     NPWindowTypeWindow = 1,
108     NPWindowTypeDrawable
109 } NPWindowType;
110 
111 typedef struct _NPWindow {
112     void *window;
113     INT32 x;
114     INT32 y;
115     UINT32 width;
116     UINT32 height;
117     NPRect clipRect;
118     NPWindowType type;
119 } NPWindow;
120 
121 typedef struct _NPFullPrint {
122     NPBool pluginPrinted;
123     NPBool printOne;
124     void *platformPrint;
125 } NPFullPrint;
126 
127 typedef struct _NPEmbedPrint {
128     NPWindow window;
129     void *platformPrint;
130 } NPEmbedPrint;
131 
132 typedef struct _NPPrint {
133     UINT16 mode;
134     union {
135         NPFullPrint fullPrint;
136         NPEmbedPrint embedPrint;
137     } print;
138 } NPPrint;
139 
140 typedef HRGN NPRegion;
141 
142 #define NPERR_BASE                         0
143 #define NPERR_NO_ERROR                    (NPERR_BASE + 0)
144 #define NPERR_GENERIC_ERROR               (NPERR_BASE + 1)
145 #define NPERR_INVALID_INSTANCE_ERROR      (NPERR_BASE + 2)
146 #define NPERR_INVALID_FUNCTABLE_ERROR     (NPERR_BASE + 3)
147 #define NPERR_MODULE_LOAD_FAILED_ERROR    (NPERR_BASE + 4)
148 #define NPERR_OUT_OF_MEMORY_ERROR         (NPERR_BASE + 5)
149 #define NPERR_INVALID_PLUGIN_ERROR        (NPERR_BASE + 6)
150 #define NPERR_INVALID_PLUGIN_DIR_ERROR    (NPERR_BASE + 7)
151 #define NPERR_INCOMPATIBLE_VERSION_ERROR  (NPERR_BASE + 8)
152 #define NPERR_INVALID_PARAM               (NPERR_BASE + 9)
153 #define NPERR_INVALID_URL                 (NPERR_BASE + 10)
154 #define NPERR_FILE_NOT_FOUND              (NPERR_BASE + 11)
155 #define NPERR_NO_DATA                     (NPERR_BASE + 12)
156 #define NPERR_STREAM_NOT_SEEKABLE         (NPERR_BASE + 13)
157 
158 /* Parts of npfunctions.h */
159 
160 typedef NPError (CDECL *NPP_NewProcPtr)(NPMIMEType,NPP,UINT16,INT16,char**,char**,NPSavedData*);
161 typedef NPError (CDECL *NPP_DestroyProcPtr)(NPP,NPSavedData**);
162 typedef NPError (CDECL *NPP_SetWindowProcPtr)(NPP,NPWindow*);
163 typedef NPError (CDECL *NPP_NewStreamProcPtr)(NPP,NPMIMEType,NPStream*,NPBool,UINT16*);
164 typedef NPError (CDECL *NPP_DestroyStreamProcPtr)(NPP,NPStream*,NPReason);
165 typedef INT32 (CDECL *NPP_WriteReadyProcPtr)(NPP,NPStream*);
166 typedef INT32 (CDECL *NPP_WriteProcPtr)(NPP,NPStream*,INT32,INT32,void*);
167 typedef void (CDECL *NPP_StreamAsFileProcPtr)(NPP,NPStream*,const char*);
168 typedef void (CDECL *NPP_PrintProcPtr)(NPP,NPPrint*);
169 typedef INT16 (CDECL *NPP_HandleEventProcPtr)(NPP,void*);
170 typedef void (CDECL *NPP_URLNotifyProcPtr)(NPP,const char*,NPReason,void*);
171 typedef NPError (CDECL *NPP_GetValueProcPtr)(NPP,NPPVariable,void*);
172 typedef NPError (CDECL *NPP_SetValueProcPtr)(NPP,NPNVariable,void*);
173 typedef NPBool (CDECL *NPP_GotFocusPtr)(NPP,NPFocusDirection);
174 typedef void (CDECL *NPP_LostFocusPtr)(NPP);
175 
176 typedef struct _NPPluginFuncs {
177     UINT16 size;
178     UINT16 version;
179     NPP_NewProcPtr newp;
180     NPP_DestroyProcPtr destroy;
181     NPP_SetWindowProcPtr setwindow;
182     NPP_NewStreamProcPtr newstream;
183     NPP_DestroyStreamProcPtr destroystream;
184     NPP_StreamAsFileProcPtr asfile;
185     NPP_WriteReadyProcPtr writeready;
186     NPP_WriteProcPtr write;
187     NPP_PrintProcPtr print;
188     NPP_HandleEventProcPtr event;
189     NPP_URLNotifyProcPtr urlnotify;
190     void *javaClass;
191     NPP_GetValueProcPtr getvalue;
192     NPP_SetValueProcPtr setvalue;
193     NPP_GotFocusPtr gotfocus;
194     NPP_LostFocusPtr lostfocus;
195 } NPPluginFuncs;
196 
197 static nsIDOMHTMLElement *get_dom_element(NPP instance)
198 {
199     nsISupports *instance_unk = (nsISupports*)instance->ndata;
200     nsIPluginInstance *plugin_instance;
201     nsIDOMHTMLElement *html_elem;
202     nsIDOMElement *elem;
203     nsresult nsres;
204 
205     nsres = nsISupports_QueryInterface(instance_unk, &IID_nsIPluginInstance, (void**)&plugin_instance);
206     if(NS_FAILED(nsres)) {
207         ERR("Could not get nsIPluginInstance interface: %08x\n", nsres);
208         return NULL;
209     }
210 
211     nsres = nsIPluginInstance_GetDOMElement(plugin_instance, &elem);
212     nsIPluginInstance_Release(plugin_instance);
213     if(NS_FAILED(nsres)) {
214         ERR("GetDOMElement failed: %08x\n", nsres);
215         return NULL;
216     }
217 
218     nsres = nsIDOMElement_QueryInterface(elem, &IID_nsIDOMHTMLElement, (void**)&html_elem);
219     nsIDOMElement_Release(elem);
220     if(NS_FAILED(nsres)) {
221         ERR("Could not get nsIDOMHTMLElement iface: %08x\n", nsres);
222         return NULL;
223     }
224 
225     return html_elem;
226 }
227 
228 static HTMLInnerWindow *get_elem_window(nsIDOMHTMLElement *elem)
229 {
230     nsIDOMWindow *nswindow;
231     nsIDOMDocument *nsdoc;
232     HTMLOuterWindow *window;
233     nsresult nsres;
234 
235     nsres = nsIDOMHTMLElement_GetOwnerDocument(elem, &nsdoc);
236     if(NS_FAILED(nsres))
237         return NULL;
238 
239     nsres = nsIDOMDocument_GetDefaultView(nsdoc, &nswindow);
240     nsIDOMDocument_Release(nsdoc);
241     if(NS_FAILED(nsres) || !nswindow)
242         return NULL;
243 
244     window = nswindow_to_window(nswindow);
245     nsIDOMWindow_Release(nswindow);
246 
247     return window->base.inner_window;
248 }
249 
250 static NPError CDECL NPP_New(NPMIMEType pluginType, NPP instance, UINT16 mode, INT16 argc, char **argn,
251         char **argv, NPSavedData *saved)
252 {
253     HTMLPluginContainer *container;
254     nsIDOMHTMLElement *nselem;
255     HTMLInnerWindow *window;
256     HTMLDOMNode *node;
257     NPError err = NPERR_NO_ERROR;
258     HRESULT hres;
259 
260     TRACE("(%s %p %x %d %p %p %p)\n", debugstr_a(pluginType), instance, mode, argc, argn, argv, saved);
261 
262     nselem = get_dom_element(instance);
263     if(!nselem) {
264         ERR("Could not get DOM element\n");
265         return NPERR_GENERIC_ERROR;
266     }
267 
268     window = get_elem_window(nselem);
269     if(!window) {
270         ERR("Could not get element's window object\n");
271         nsIDOMHTMLElement_Release(nselem);
272         return NPERR_GENERIC_ERROR;
273     }
274 
275     hres = get_node(window->doc, (nsIDOMNode*)nselem, TRUE, &node);
276     nsIDOMHTMLElement_Release(nselem);
277     if(FAILED(hres))
278         return NPERR_GENERIC_ERROR;
279 
280     hres = IHTMLDOMNode_QueryInterface(&node->IHTMLDOMNode_iface, &IID_HTMLPluginContainer,
281             (void**)&container);
282     node_release(node);
283     if(FAILED(hres)) {
284         ERR("Not an object element\n");
285         return NPERR_GENERIC_ERROR;
286     }
287 
288     if(!container->plugin_host) {
289         hres = create_plugin_host(window->doc, container);
290         if(FAILED(hres))
291             err = NPERR_GENERIC_ERROR;
292     }else {
293         TRACE("plugin host already associated.\n");
294     }
295 
296     instance->pdata = container->plugin_host;
297 
298     node_release(&container->element.node);
299     return err;
300 }
301 
302 static NPError CDECL NPP_Destroy(NPP instance, NPSavedData **save)
303 {
304     PluginHost *host = instance->pdata;
305 
306     TRACE("(%p %p)\n", instance, save);
307 
308     if(!host)
309         return NPERR_GENERIC_ERROR;
310 
311     detach_plugin_host(host);
312     IOleClientSite_Release(&host->IOleClientSite_iface);
313     instance->pdata = NULL;
314     return NPERR_NO_ERROR;
315 }
316 
317 static NPError CDECL NPP_SetWindow(NPP instance, NPWindow *window)
318 {
319     PluginHost *host = instance->pdata;
320     RECT pos_rect = {0, 0, window->width, window->height};
321 
322     TRACE("(%p %p)\n", instance, window);
323 
324     if(!host)
325         return NPERR_GENERIC_ERROR;
326 
327     update_plugin_window(host, window->window, &pos_rect);
328     return NPERR_NO_ERROR;
329 }
330 
331 static NPError CDECL NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, NPBool seekable, UINT16 *stype)
332 {
333     TRACE("\n");
334     return NPERR_GENERIC_ERROR;
335 }
336 
337 static NPError CDECL NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason)
338 {
339     TRACE("\n");
340     return NPERR_GENERIC_ERROR;
341 }
342 
343 static INT32 CDECL NPP_WriteReady(NPP instance, NPStream *stream)
344 {
345     TRACE("\n");
346     return NPERR_GENERIC_ERROR;
347 }
348 
349 static INT32 CDECL NPP_Write(NPP instance, NPStream *stream, INT32 offset, INT32 len, void *buffer)
350 {
351     TRACE("\n");
352     return NPERR_GENERIC_ERROR;
353 }
354 
355 static void CDECL NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname)
356 {
357     TRACE("\n");
358 }
359 
360 static void CDECL NPP_Print(NPP instance, NPPrint *platformPrint)
361 {
362     FIXME("\n");
363 }
364 
365 static INT16 CDECL NPP_HandleEvent(NPP instance, void *event)
366 {
367     TRACE("\n");
368     return NPERR_GENERIC_ERROR;
369 }
370 
371 static void CDECL NPP_URLNotify(NPP instance, const char *url, NPReason reason, void *notifyData)
372 {
373     TRACE("\n");
374 }
375 
376 static NPError CDECL NPP_GetValue(NPP instance, NPPVariable variable, void *ret_value)
377 {
378     TRACE("\n");
379     return NPERR_GENERIC_ERROR;
380 }
381 
382 static NPError CDECL NPP_SetValue(NPP instance, NPNVariable variable, void *value)
383 {
384     TRACE("\n");
385     return NPERR_GENERIC_ERROR;
386 }
387 
388 static NPBool CDECL NPP_GotFocus(NPP instance, NPFocusDirection direction)
389 {
390     FIXME("\n");
391     return NPERR_GENERIC_ERROR;
392 }
393 
394 static void CDECL NPP_LostFocus(NPP instance)
395 {
396     FIXME("\n");
397 }
398 
399 /***********************************************************************
400  *          NP_GetEntryPoints (mshtml.@)
401  */
402 NPError WINAPI NP_GetEntryPoints(NPPluginFuncs* funcs)
403 {
404     TRACE("(%p)\n", funcs);
405 
406     funcs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
407     funcs->newp = NPP_New;
408     funcs->destroy = NPP_Destroy;
409     funcs->setwindow = NPP_SetWindow;
410     funcs->newstream = NPP_NewStream;
411     funcs->destroystream = NPP_DestroyStream;
412     funcs->asfile = NPP_StreamAsFile;
413     funcs->writeready = NPP_WriteReady;
414     funcs->write = NPP_Write;
415     funcs->print = NPP_Print;
416     funcs->event = NPP_HandleEvent;
417     funcs->urlnotify = NPP_URLNotify;
418     funcs->javaClass = NULL;
419     funcs->getvalue = NPP_GetValue;
420     funcs->setvalue = NPP_SetValue;
421     funcs->gotfocus = NPP_GotFocus;
422     funcs->lostfocus = NPP_LostFocus;
423 
424     return NPERR_NO_ERROR;
425 }
426