| /* |
| * Copyright 2010 Jacek Caban for CodeWeavers |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| */ |
| |
| #include "config.h" |
| |
| #include <stdarg.h> |
| |
| #define COBJMACROS |
| |
| #include "windef.h" |
| #include "winbase.h" |
| #include "winuser.h" |
| #include "ole2.h" |
| #include "shlobj.h" |
| |
| #include "mshtml_private.h" |
| #include "pluginhost.h" |
| |
| #include "wine/debug.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(mshtml); |
| |
| /* Parts of npapi.h */ |
| |
| #define NP_VERSION_MAJOR 0 |
| #define NP_VERSION_MINOR 25 |
| |
| typedef unsigned char NPBool; |
| typedef INT16 NPError; |
| typedef INT16 NPReason; |
| typedef char *NPMIMEType; |
| |
| typedef struct _NPP { |
| void *pdata; |
| void *ndata; |
| } NPP_t, *NPP; |
| |
| typedef struct _NPStream { |
| void *pdata; |
| void *ndata; |
| const char *url; |
| UINT32 end; |
| UINT32 lastmodified; |
| void *notifyData; |
| const char *headers; |
| } NPStream; |
| |
| typedef struct _NPSavedData { |
| INT32 len; |
| void *buf; |
| } NPSavedData; |
| |
| typedef struct _NPRect { |
| UINT16 top; |
| UINT16 left; |
| UINT16 bottom; |
| UINT16 right; |
| } NPRect; |
| |
| typedef enum { |
| NPFocusNext = 0, |
| NPFocusPrevious = 1 |
| } NPFocusDirection; |
| |
| #define NP_ABI_MASK 0 |
| |
| typedef enum { |
| NPPVpluginNameString = 1, |
| NPPVpluginDescriptionString, |
| NPPVpluginWindowBool, |
| NPPVpluginTransparentBool, |
| NPPVjavaClass, |
| NPPVpluginWindowSize, |
| NPPVpluginTimerInterval, |
| NPPVpluginScriptableInstance = (10 | NP_ABI_MASK), |
| NPPVpluginScriptableIID = 11, |
| NPPVjavascriptPushCallerBool = 12, |
| NPPVpluginKeepLibraryInMemory = 13, |
| NPPVpluginNeedsXEmbed = 14, |
| NPPVpluginScriptableNPObject = 15, |
| NPPVformValue = 16, |
| NPPVpluginUrlRequestsDisplayedBool = 17, |
| NPPVpluginWantsAllNetworkStreams = 18, |
| NPPVpluginNativeAccessibleAtkPlugId = 19, |
| NPPVpluginCancelSrcStream = 20, |
| NPPVSupportsAdvancedKeyHandling = 21 |
| } NPPVariable; |
| |
| typedef enum { |
| NPNVxDisplay = 1, |
| NPNVxtAppContext, |
| NPNVnetscapeWindow, |
| NPNVjavascriptEnabledBool, |
| NPNVasdEnabledBool, |
| NPNVisOfflineBool, |
| NPNVserviceManager = (10 | NP_ABI_MASK), |
| NPNVDOMElement = (11 | NP_ABI_MASK), |
| NPNVDOMWindow = (12 | NP_ABI_MASK), |
| NPNVToolkit = (13 | NP_ABI_MASK), |
| NPNVSupportsXEmbedBool = 14, |
| NPNVWindowNPObject = 15, |
| NPNVPluginElementNPObject = 16, |
| NPNVSupportsWindowless = 17, |
| NPNVprivateModeBool = 18, |
| NPNVsupportsAdvancedKeyHandling = 21 |
| } NPNVariable; |
| |
| typedef enum { |
| NPWindowTypeWindow = 1, |
| NPWindowTypeDrawable |
| } NPWindowType; |
| |
| typedef struct _NPWindow { |
| void *window; |
| INT32 x; |
| INT32 y; |
| UINT32 width; |
| UINT32 height; |
| NPRect clipRect; |
| NPWindowType type; |
| } NPWindow; |
| |
| typedef struct _NPFullPrint { |
| NPBool pluginPrinted; |
| NPBool printOne; |
| void *platformPrint; |
| } NPFullPrint; |
| |
| typedef struct _NPEmbedPrint { |
| NPWindow window; |
| void *platformPrint; |
| } NPEmbedPrint; |
| |
| typedef struct _NPPrint { |
| UINT16 mode; |
| union { |
| NPFullPrint fullPrint; |
| NPEmbedPrint embedPrint; |
| } print; |
| } NPPrint; |
| |
| typedef HRGN NPRegion; |
| |
| #define NPERR_BASE 0 |
| #define NPERR_NO_ERROR (NPERR_BASE + 0) |
| #define NPERR_GENERIC_ERROR (NPERR_BASE + 1) |
| #define NPERR_INVALID_INSTANCE_ERROR (NPERR_BASE + 2) |
| #define NPERR_INVALID_FUNCTABLE_ERROR (NPERR_BASE + 3) |
| #define NPERR_MODULE_LOAD_FAILED_ERROR (NPERR_BASE + 4) |
| #define NPERR_OUT_OF_MEMORY_ERROR (NPERR_BASE + 5) |
| #define NPERR_INVALID_PLUGIN_ERROR (NPERR_BASE + 6) |
| #define NPERR_INVALID_PLUGIN_DIR_ERROR (NPERR_BASE + 7) |
| #define NPERR_INCOMPATIBLE_VERSION_ERROR (NPERR_BASE + 8) |
| #define NPERR_INVALID_PARAM (NPERR_BASE + 9) |
| #define NPERR_INVALID_URL (NPERR_BASE + 10) |
| #define NPERR_FILE_NOT_FOUND (NPERR_BASE + 11) |
| #define NPERR_NO_DATA (NPERR_BASE + 12) |
| #define NPERR_STREAM_NOT_SEEKABLE (NPERR_BASE + 13) |
| |
| /* Parts of npfunctions.h */ |
| |
| typedef NPError (CDECL *NPP_NewProcPtr)(NPMIMEType,NPP,UINT16,INT16,char**,char**,NPSavedData*); |
| typedef NPError (CDECL *NPP_DestroyProcPtr)(NPP,NPSavedData**); |
| typedef NPError (CDECL *NPP_SetWindowProcPtr)(NPP,NPWindow*); |
| typedef NPError (CDECL *NPP_NewStreamProcPtr)(NPP,NPMIMEType,NPStream*,NPBool,UINT16*); |
| typedef NPError (CDECL *NPP_DestroyStreamProcPtr)(NPP,NPStream*,NPReason); |
| typedef INT32 (CDECL *NPP_WriteReadyProcPtr)(NPP,NPStream*); |
| typedef INT32 (CDECL *NPP_WriteProcPtr)(NPP,NPStream*,INT32,INT32,void*); |
| typedef void (CDECL *NPP_StreamAsFileProcPtr)(NPP,NPStream*,const char*); |
| typedef void (CDECL *NPP_PrintProcPtr)(NPP,NPPrint*); |
| typedef INT16 (CDECL *NPP_HandleEventProcPtr)(NPP,void*); |
| typedef void (CDECL *NPP_URLNotifyProcPtr)(NPP,const char*,NPReason,void*); |
| typedef NPError (CDECL *NPP_GetValueProcPtr)(NPP,NPPVariable,void*); |
| typedef NPError (CDECL *NPP_SetValueProcPtr)(NPP,NPNVariable,void*); |
| typedef NPBool (CDECL *NPP_GotFocusPtr)(NPP,NPFocusDirection); |
| typedef void (CDECL *NPP_LostFocusPtr)(NPP); |
| |
| typedef struct _NPPluginFuncs { |
| UINT16 size; |
| UINT16 version; |
| NPP_NewProcPtr newp; |
| NPP_DestroyProcPtr destroy; |
| NPP_SetWindowProcPtr setwindow; |
| NPP_NewStreamProcPtr newstream; |
| NPP_DestroyStreamProcPtr destroystream; |
| NPP_StreamAsFileProcPtr asfile; |
| NPP_WriteReadyProcPtr writeready; |
| NPP_WriteProcPtr write; |
| NPP_PrintProcPtr print; |
| NPP_HandleEventProcPtr event; |
| NPP_URLNotifyProcPtr urlnotify; |
| void *javaClass; |
| NPP_GetValueProcPtr getvalue; |
| NPP_SetValueProcPtr setvalue; |
| NPP_GotFocusPtr gotfocus; |
| NPP_LostFocusPtr lostfocus; |
| } NPPluginFuncs; |
| |
| static nsIDOMHTMLElement *get_dom_element(NPP instance) |
| { |
| nsISupports *instance_unk = (nsISupports*)instance->ndata; |
| nsIPluginInstance *plugin_instance; |
| nsIDOMHTMLElement *html_elem; |
| nsIDOMElement *elem; |
| nsresult nsres; |
| |
| nsres = nsISupports_QueryInterface(instance_unk, &IID_nsIPluginInstance, (void**)&plugin_instance); |
| if(NS_FAILED(nsres)) { |
| ERR("Could not get nsIPluginInstance interface: %08x\n", nsres); |
| return NULL; |
| } |
| |
| nsres = nsIPluginInstance_GetDOMElement(plugin_instance, &elem); |
| nsIPluginInstance_Release(plugin_instance); |
| if(NS_FAILED(nsres)) { |
| ERR("GetDOMElement failed: %08x\n", nsres); |
| return NULL; |
| } |
| |
| nsres = nsIDOMElement_QueryInterface(elem, &IID_nsIDOMHTMLElement, (void**)&html_elem); |
| nsIDOMElement_Release(elem); |
| if(NS_FAILED(nsres)) { |
| ERR("Could not get nsIDOMHTMLElement iface: %08x\n", nsres); |
| return NULL; |
| } |
| |
| return html_elem; |
| } |
| |
| static HTMLInnerWindow *get_elem_window(nsIDOMHTMLElement *elem) |
| { |
| nsIDOMWindow *nswindow; |
| nsIDOMDocument *nsdoc; |
| HTMLOuterWindow *window; |
| nsresult nsres; |
| |
| nsres = nsIDOMHTMLElement_GetOwnerDocument(elem, &nsdoc); |
| if(NS_FAILED(nsres)) |
| return NULL; |
| |
| nsres = nsIDOMDocument_GetDefaultView(nsdoc, &nswindow); |
| nsIDOMDocument_Release(nsdoc); |
| if(NS_FAILED(nsres) || !nswindow) |
| return NULL; |
| |
| window = nswindow_to_window(nswindow); |
| nsIDOMWindow_Release(nswindow); |
| |
| return window->base.inner_window; |
| } |
| |
| static NPError CDECL NPP_New(NPMIMEType pluginType, NPP instance, UINT16 mode, INT16 argc, char **argn, |
| char **argv, NPSavedData *saved) |
| { |
| HTMLPluginContainer *container; |
| nsIDOMHTMLElement *nselem; |
| HTMLInnerWindow *window; |
| HTMLDOMNode *node; |
| NPError err = NPERR_NO_ERROR; |
| HRESULT hres; |
| |
| TRACE("(%s %p %x %d %p %p %p)\n", debugstr_a(pluginType), instance, mode, argc, argn, argv, saved); |
| |
| nselem = get_dom_element(instance); |
| if(!nselem) { |
| ERR("Could not get DOM element\n"); |
| return NPERR_GENERIC_ERROR; |
| } |
| |
| window = get_elem_window(nselem); |
| if(!window) { |
| ERR("Could not get element's window object\n"); |
| nsIDOMHTMLElement_Release(nselem); |
| return NPERR_GENERIC_ERROR; |
| } |
| |
| hres = get_node(window->doc, (nsIDOMNode*)nselem, TRUE, &node); |
| nsIDOMHTMLElement_Release(nselem); |
| if(FAILED(hres)) |
| return NPERR_GENERIC_ERROR; |
| |
| hres = IHTMLDOMNode_QueryInterface(&node->IHTMLDOMNode_iface, &IID_HTMLPluginContainer, |
| (void**)&container); |
| node_release(node); |
| if(FAILED(hres)) { |
| ERR("Not an object element\n"); |
| return NPERR_GENERIC_ERROR; |
| } |
| |
| if(!container->plugin_host) { |
| hres = create_plugin_host(window->doc, container); |
| if(FAILED(hres)) |
| err = NPERR_GENERIC_ERROR; |
| }else { |
| TRACE("plugin host already associated.\n"); |
| } |
| |
| instance->pdata = container->plugin_host; |
| |
| node_release(&container->element.node); |
| return err; |
| } |
| |
| static NPError CDECL NPP_Destroy(NPP instance, NPSavedData **save) |
| { |
| PluginHost *host = instance->pdata; |
| |
| TRACE("(%p %p)\n", instance, save); |
| |
| if(!host) |
| return NPERR_GENERIC_ERROR; |
| |
| detach_plugin_host(host); |
| IOleClientSite_Release(&host->IOleClientSite_iface); |
| instance->pdata = NULL; |
| return NPERR_NO_ERROR; |
| } |
| |
| static NPError CDECL NPP_SetWindow(NPP instance, NPWindow *window) |
| { |
| PluginHost *host = instance->pdata; |
| RECT pos_rect = {0, 0, window->width, window->height}; |
| |
| TRACE("(%p %p)\n", instance, window); |
| |
| if(!host) |
| return NPERR_GENERIC_ERROR; |
| |
| update_plugin_window(host, window->window, &pos_rect); |
| return NPERR_NO_ERROR; |
| } |
| |
| static NPError CDECL NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, NPBool seekable, UINT16 *stype) |
| { |
| TRACE("\n"); |
| return NPERR_GENERIC_ERROR; |
| } |
| |
| static NPError CDECL NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason) |
| { |
| TRACE("\n"); |
| return NPERR_GENERIC_ERROR; |
| } |
| |
| static INT32 CDECL NPP_WriteReady(NPP instance, NPStream *stream) |
| { |
| TRACE("\n"); |
| return NPERR_GENERIC_ERROR; |
| } |
| |
| static INT32 CDECL NPP_Write(NPP instance, NPStream *stream, INT32 offset, INT32 len, void *buffer) |
| { |
| TRACE("\n"); |
| return NPERR_GENERIC_ERROR; |
| } |
| |
| static void CDECL NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname) |
| { |
| TRACE("\n"); |
| } |
| |
| static void CDECL NPP_Print(NPP instance, NPPrint *platformPrint) |
| { |
| FIXME("\n"); |
| } |
| |
| static INT16 CDECL NPP_HandleEvent(NPP instance, void *event) |
| { |
| TRACE("\n"); |
| return NPERR_GENERIC_ERROR; |
| } |
| |
| static void CDECL NPP_URLNotify(NPP instance, const char *url, NPReason reason, void *notifyData) |
| { |
| TRACE("\n"); |
| } |
| |
| static NPError CDECL NPP_GetValue(NPP instance, NPPVariable variable, void *ret_value) |
| { |
| TRACE("\n"); |
| return NPERR_GENERIC_ERROR; |
| } |
| |
| static NPError CDECL NPP_SetValue(NPP instance, NPNVariable variable, void *value) |
| { |
| TRACE("\n"); |
| return NPERR_GENERIC_ERROR; |
| } |
| |
| static NPBool CDECL NPP_GotFocus(NPP instance, NPFocusDirection direction) |
| { |
| FIXME("\n"); |
| return NPERR_GENERIC_ERROR; |
| } |
| |
| static void CDECL NPP_LostFocus(NPP instance) |
| { |
| FIXME("\n"); |
| } |
| |
| /*********************************************************************** |
| * NP_GetEntryPoints (mshtml.@) |
| */ |
| NPError WINAPI NP_GetEntryPoints(NPPluginFuncs* funcs) |
| { |
| TRACE("(%p)\n", funcs); |
| |
| funcs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; |
| funcs->newp = NPP_New; |
| funcs->destroy = NPP_Destroy; |
| funcs->setwindow = NPP_SetWindow; |
| funcs->newstream = NPP_NewStream; |
| funcs->destroystream = NPP_DestroyStream; |
| funcs->asfile = NPP_StreamAsFile; |
| funcs->writeready = NPP_WriteReady; |
| funcs->write = NPP_Write; |
| funcs->print = NPP_Print; |
| funcs->event = NPP_HandleEvent; |
| funcs->urlnotify = NPP_URLNotify; |
| funcs->javaClass = NULL; |
| funcs->getvalue = NPP_GetValue; |
| funcs->setvalue = NPP_SetValue; |
| funcs->gotfocus = NPP_GotFocus; |
| funcs->lostfocus = NPP_LostFocus; |
| |
| return NPERR_NO_ERROR; |
| } |