push 4d5485f9b89f417d46b39b93e8d940437007f325
[wine/hacks.git] / dlls / mshtml / nsembed.c
blob0dfdf0ebd27dbcb608dd8d9e1a0a491706037dc0
1 /*
2 * Copyright 2005-2007 Jacek Caban for CodeWeavers
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.
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.
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
19 #include "config.h"
21 #include <stdarg.h>
23 #define COBJMACROS
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winuser.h"
28 #include "winreg.h"
29 #include "ole2.h"
31 #include "wine/debug.h"
32 #include "wine/unicode.h"
34 #include "mshtml_private.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
38 #define NS_APPSTARTUPNOTIFIER_CONTRACTID "@mozilla.org/embedcomp/appstartup-notifier;1"
39 #define NS_WEBBROWSER_CONTRACTID "@mozilla.org/embedding/browser/nsWebBrowser;1"
40 #define NS_PROFILE_CONTRACTID "@mozilla.org/profile/manager;1"
41 #define NS_MEMORY_CONTRACTID "@mozilla.org/xpcom/memory-service;1"
42 #define NS_STRINGSTREAM_CONTRACTID "@mozilla.org/io/string-input-stream;1"
43 #define NS_COMMANDPARAMS_CONTRACTID "@mozilla.org/embedcomp/command-params;1"
44 #define NS_HTMLSERIALIZER_CONTRACTID "@mozilla.org/layout/contentserializer;1?mimetype=text/html"
45 #define NS_EDITORCONTROLLER_CONTRACTID "@mozilla.org/editor/editorcontroller;1"
46 #define NS_ARRAY_CONTRACTID "@mozilla.org/array;1"
47 #define NS_VARIANT_CONTRACTID "@mozilla.org/variant;1"
49 #define APPSTARTUP_TOPIC "app-startup"
51 #define PR_UINT32_MAX 0xffffffff
53 struct nsCStringContainer {
54 void *v;
55 void *d1;
56 PRUint32 d2;
57 void *d3;
60 static nsresult (*NS_InitXPCOM2)(nsIServiceManager**,void*,void*);
61 static nsresult (*NS_ShutdownXPCOM)(nsIServiceManager*);
62 static nsresult (*NS_GetComponentRegistrar)(nsIComponentRegistrar**);
63 static nsresult (*NS_StringContainerInit)(nsStringContainer*);
64 static nsresult (*NS_CStringContainerInit)(nsCStringContainer*);
65 static nsresult (*NS_StringContainerFinish)(nsStringContainer*);
66 static nsresult (*NS_CStringContainerFinish)(nsCStringContainer*);
67 static nsresult (*NS_StringSetData)(nsAString*,const PRUnichar*,PRUint32);
68 static nsresult (*NS_CStringSetData)(nsACString*,const char*,PRUint32);
69 static nsresult (*NS_NewLocalFile)(const nsAString*,PRBool,nsIFile**);
70 static PRUint32 (*NS_StringGetData)(const nsAString*,const PRUnichar **,PRBool*);
71 static PRUint32 (*NS_CStringGetData)(const nsACString*,const char**,PRBool*);
73 static HINSTANCE hXPCOM = NULL;
75 static nsIServiceManager *pServMgr = NULL;
76 static nsIComponentManager *pCompMgr = NULL;
77 static nsIMemory *nsmem = NULL;
79 static const WCHAR wszNsContainer[] = {'N','s','C','o','n','t','a','i','n','e','r',0};
81 static ATOM nscontainer_class;
83 static LRESULT WINAPI nsembed_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
85 NSContainer *This;
86 nsresult nsres;
88 static const WCHAR wszTHIS[] = {'T','H','I','S',0};
90 if(msg == WM_CREATE) {
91 This = *(NSContainer**)lParam;
92 SetPropW(hwnd, wszTHIS, This);
93 }else {
94 This = (NSContainer*)GetPropW(hwnd, wszTHIS);
97 switch(msg) {
98 case WM_SIZE:
99 TRACE("(%p)->(WM_SIZE)\n", This);
101 nsres = nsIBaseWindow_SetSize(This->window,
102 LOWORD(lParam), HIWORD(lParam), TRUE);
103 if(NS_FAILED(nsres))
104 WARN("SetSize failed: %08x\n", nsres);
107 return DefWindowProcW(hwnd, msg, wParam, lParam);
111 static void register_nscontainer_class(void)
113 static WNDCLASSEXW wndclass = {
114 sizeof(WNDCLASSEXW),
115 CS_DBLCLKS,
116 nsembed_proc,
117 0, 0, NULL, NULL, NULL, NULL, NULL,
118 wszNsContainer,
119 NULL,
121 wndclass.hInstance = hInst;
122 nscontainer_class = RegisterClassExW(&wndclass);
125 static BOOL load_xpcom(const PRUnichar *gre_path)
127 WCHAR path_env[MAX_PATH];
128 int len;
130 static const WCHAR wszPATH[] = {'P','A','T','H',0};
131 static const WCHAR strXPCOM[] = {'x','p','c','o','m','.','d','l','l',0};
133 TRACE("(%s)\n", debugstr_w(gre_path));
135 /* We have to modify PATH as XPCOM loads other DLLs from this directory. */
136 GetEnvironmentVariableW(wszPATH, path_env, sizeof(path_env)/sizeof(WCHAR));
137 len = strlenW(path_env);
138 path_env[len++] = ';';
139 strcpyW(path_env+len, gre_path);
140 SetEnvironmentVariableW(wszPATH, path_env);
142 hXPCOM = LoadLibraryW(strXPCOM);
143 if(!hXPCOM) {
144 WARN("Could not load XPCOM: %d\n", GetLastError());
145 return FALSE;
148 #define NS_DLSYM(func) \
149 func = (typeof(func))GetProcAddress(hXPCOM, #func); \
150 if(!func) \
151 ERR("Could not GetProcAddress(" #func ") failed\n")
153 NS_DLSYM(NS_InitXPCOM2);
154 NS_DLSYM(NS_ShutdownXPCOM);
155 NS_DLSYM(NS_GetComponentRegistrar);
156 NS_DLSYM(NS_StringContainerInit);
157 NS_DLSYM(NS_CStringContainerInit);
158 NS_DLSYM(NS_StringContainerFinish);
159 NS_DLSYM(NS_CStringContainerFinish);
160 NS_DLSYM(NS_StringSetData);
161 NS_DLSYM(NS_CStringSetData);
162 NS_DLSYM(NS_NewLocalFile);
163 NS_DLSYM(NS_StringGetData);
164 NS_DLSYM(NS_CStringGetData);
166 #undef NS_DLSYM
168 return TRUE;
171 static BOOL check_version(LPCWSTR gre_path, const char *version_string)
173 WCHAR file_name[MAX_PATH];
174 char version[128];
175 DWORD read=0;
176 HANDLE hfile;
178 static const WCHAR wszVersion[] = {'\\','V','E','R','S','I','O','N',0};
180 strcpyW(file_name, gre_path);
181 strcatW(file_name, wszVersion);
183 hfile = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ, NULL,
184 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
185 if(hfile == INVALID_HANDLE_VALUE) {
186 ERR("Could not open VERSION file\n");
187 return FALSE;
190 ReadFile(hfile, version, sizeof(version), &read, NULL);
191 version[read] = 0;
192 CloseHandle(hfile);
194 TRACE("%s\n", debugstr_a(version));
196 if(strcmp(version, version_string)) {
197 ERR("Unexpected version %s, expected %s\n", debugstr_a(version),
198 debugstr_a(version_string));
199 return FALSE;
202 return TRUE;
205 static BOOL load_wine_gecko_v(PRUnichar *gre_path, HKEY mshtml_key,
206 const char *version, const char *version_string)
208 DWORD res, type, size = MAX_PATH;
209 HKEY hkey = mshtml_key;
211 static const WCHAR wszGeckoPath[] =
212 {'G','e','c','k','o','P','a','t','h',0};
214 if(version) {
215 /* @@ Wine registry key: HKCU\Software\Wine\MSHTML\<version> */
216 res = RegOpenKeyA(mshtml_key, version, &hkey);
217 if(res != ERROR_SUCCESS)
218 return FALSE;
221 res = RegQueryValueExW(hkey, wszGeckoPath, NULL, &type, (LPBYTE)gre_path, &size);
222 if(hkey != mshtml_key)
223 RegCloseKey(hkey);
224 if(res != ERROR_SUCCESS || type != REG_SZ)
225 return FALSE;
227 if(!check_version(gre_path, version_string))
228 return FALSE;
230 return load_xpcom(gre_path);
233 static BOOL load_wine_gecko(PRUnichar *gre_path)
235 HKEY hkey;
236 DWORD res;
237 BOOL ret;
239 static const WCHAR wszMshtmlKey[] = {
240 'S','o','f','t','w','a','r','e','\\','W','i','n','e',
241 '\\','M','S','H','T','M','L',0};
243 /* @@ Wine registry key: HKCU\Software\Wine\MSHTML */
244 res = RegOpenKeyW(HKEY_CURRENT_USER, wszMshtmlKey, &hkey);
245 if(res != ERROR_SUCCESS)
246 return FALSE;
248 ret = load_wine_gecko_v(gre_path, hkey, GECKO_VERSION, GECKO_VERSION_STRING)
249 || load_wine_gecko_v(gre_path, hkey, "0.0.1", "Wine Gecko 0.0.1\n")
250 || load_wine_gecko_v(gre_path, hkey, NULL, "Wine Gecko 0.0.1\n");
252 RegCloseKey(hkey);
253 return ret;
256 static void set_profile(void)
258 nsIProfile *profile;
259 PRBool exists = FALSE;
260 nsresult nsres;
262 static const WCHAR wszMSHTML[] = {'M','S','H','T','M','L',0};
264 nsres = nsIServiceManager_GetServiceByContractID(pServMgr, NS_PROFILE_CONTRACTID,
265 &IID_nsIProfile, (void**)&profile);
266 if(NS_FAILED(nsres)) {
267 ERR("Could not get profile service: %08x\n", nsres);
268 return;
271 nsres = nsIProfile_ProfileExists(profile, wszMSHTML, &exists);
272 if(!exists) {
273 nsres = nsIProfile_CreateNewProfile(profile, wszMSHTML, NULL, NULL, FALSE);
274 if(NS_FAILED(nsres))
275 ERR("CreateNewProfile failed: %08x\n", nsres);
278 nsres = nsIProfile_SetCurrentProfile(profile, wszMSHTML);
279 if(NS_FAILED(nsres))
280 ERR("SetCurrentProfile failed: %08x\n", nsres);
282 nsIProfile_Release(profile);
285 static BOOL init_xpcom(const PRUnichar *gre_path)
287 nsresult nsres;
288 nsIObserver *pStartNotif;
289 nsIComponentRegistrar *registrar = NULL;
290 nsAString path;
291 nsIFile *gre_dir;
293 nsAString_Init(&path, gre_path);
294 nsres = NS_NewLocalFile(&path, FALSE, &gre_dir);
295 nsAString_Finish(&path);
296 if(NS_FAILED(nsres)) {
297 ERR("NS_NewLocalFile failed: %08x\n", nsres);
298 FreeLibrary(hXPCOM);
299 return FALSE;
302 nsres = NS_InitXPCOM2(&pServMgr, gre_dir, NULL);
303 if(NS_FAILED(nsres)) {
304 ERR("NS_InitXPCOM2 failed: %08x\n", nsres);
305 FreeLibrary(hXPCOM);
306 return FALSE;
309 nsres = nsIServiceManager_QueryInterface(pServMgr, &IID_nsIComponentManager, (void**)&pCompMgr);
310 if(NS_FAILED(nsres))
311 ERR("Could not get nsIComponentManager: %08x\n", nsres);
313 nsres = NS_GetComponentRegistrar(&registrar);
314 if(NS_SUCCEEDED(nsres)) {
315 nsres = nsIComponentRegistrar_AutoRegister(registrar, NULL);
316 if(NS_FAILED(nsres))
317 ERR("AutoRegister(NULL) failed: %08x\n", nsres);
319 nsres = nsIComponentRegistrar_AutoRegister(registrar, gre_dir);
320 if(NS_FAILED(nsres))
321 ERR("AutoRegister(gre_dir) failed: %08x\n", nsres);
323 init_nsio(pCompMgr, registrar);
324 }else {
325 ERR("NS_GetComponentRegistrar failed: %08x\n", nsres);
328 nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr, NS_APPSTARTUPNOTIFIER_CONTRACTID,
329 NULL, &IID_nsIObserver, (void**)&pStartNotif);
330 if(NS_SUCCEEDED(nsres)) {
331 nsres = nsIObserver_Observe(pStartNotif, NULL, APPSTARTUP_TOPIC, NULL);
332 if(NS_FAILED(nsres))
333 ERR("Observe failed: %08x\n", nsres);
335 nsIObserver_Release(pStartNotif);
336 }else {
337 ERR("could not get appstartup-notifier: %08x\n", nsres);
340 set_profile();
342 nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr, NS_MEMORY_CONTRACTID,
343 NULL, &IID_nsIMemory, (void**)&nsmem);
344 if(NS_FAILED(nsres))
345 ERR("Could not get nsIMemory: %08x\n", nsres);
347 if(registrar) {
348 register_nsservice(registrar, pServMgr);
349 nsIComponentRegistrar_Release(registrar);
352 return TRUE;
355 static CRITICAL_SECTION cs_load_gecko;
356 static CRITICAL_SECTION_DEBUG cs_load_gecko_dbg =
358 0, 0, &cs_load_gecko,
359 { &cs_load_gecko_dbg.ProcessLocksList, &cs_load_gecko_dbg.ProcessLocksList },
360 0, 0, { (DWORD_PTR)(__FILE__ ": load_gecko") }
362 static CRITICAL_SECTION cs_load_gecko = { &cs_load_gecko_dbg, -1, 0, 0, 0, 0 };
364 static BOOL load_gecko(void)
366 PRUnichar gre_path[MAX_PATH];
367 BOOL ret = FALSE;
369 static LONG loading_thread;
371 TRACE("()\n");
373 /* load_gecko may be called recursively */
374 if(loading_thread == GetCurrentThreadId())
375 return pCompMgr != NULL;
377 EnterCriticalSection(&cs_load_gecko);
379 if(!loading_thread) {
380 loading_thread = GetCurrentThreadId();
382 if(load_wine_gecko(gre_path)
383 || (install_wine_gecko() && load_wine_gecko(gre_path)))
384 ret = init_xpcom(gre_path);
385 else
386 MESSAGE("Could not load Mozilla. HTML rendering will be disabled.\n");
387 }else {
388 ret = pCompMgr != NULL;
391 LeaveCriticalSection(&cs_load_gecko);
393 return ret;
396 void *nsalloc(size_t size)
398 return nsIMemory_Alloc(nsmem, size);
401 void nsfree(void *mem)
403 nsIMemory_Free(nsmem, mem);
406 void nsACString_Init(nsACString *str, const char *data)
408 NS_CStringContainerInit(str);
409 if(data)
410 nsACString_SetData(str, data);
413 void nsACString_SetData(nsACString *str, const char *data)
415 NS_CStringSetData(str, data, PR_UINT32_MAX);
418 PRUint32 nsACString_GetData(const nsACString *str, const char **data, PRBool *termited)
420 return NS_CStringGetData(str, data, termited);
423 void nsACString_Finish(nsACString *str)
425 NS_CStringContainerFinish(str);
428 void nsAString_Init(nsAString *str, const PRUnichar *data)
430 NS_StringContainerInit(str);
431 if(data)
432 NS_StringSetData(str, data, PR_UINT32_MAX);
435 PRUint32 nsAString_GetData(const nsAString *str, const PRUnichar **data, PRBool *termited)
437 return NS_StringGetData(str, data, termited);
440 void nsAString_Finish(nsAString *str)
442 NS_StringContainerFinish(str);
445 nsIInputStream *create_nsstream(const char *data, PRInt32 data_len)
447 nsIStringInputStream *ret;
448 nsresult nsres;
450 if(!pCompMgr)
451 return NULL;
453 nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr,
454 NS_STRINGSTREAM_CONTRACTID, NULL, &IID_nsIStringInputStream,
455 (void**)&ret);
456 if(NS_FAILED(nsres)) {
457 ERR("Could not get nsIStringInputStream\n");
458 return NULL;
461 nsres = nsIStringInputStream_SetData(ret, data, data_len);
462 if(NS_FAILED(nsres)) {
463 ERR("AdoptData failed: %08x\n", nsres);
464 nsIStringInputStream_Release(ret);
465 return NULL;
468 return (nsIInputStream*)ret;
471 nsIMutableArray *create_nsarray(void)
473 nsIMutableArray *ret;
474 nsresult nsres;
476 if(!pCompMgr)
477 return NULL;
479 nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr,
480 NS_ARRAY_CONTRACTID, NULL, &IID_nsIMutableArray,
481 (void**)&ret);
482 if(NS_FAILED(nsres)) {
483 ERR("Could not get nsIArray: %08x\n", nsres);
484 return NULL;
487 return ret;
490 nsIWritableVariant *create_nsvariant(void)
492 nsIWritableVariant *ret;
493 nsresult nsres;
495 if(!pCompMgr)
496 return NULL;
498 nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr,
499 NS_VARIANT_CONTRACTID, NULL, &IID_nsIWritableVariant,
500 (void**)&ret);
501 if(NS_FAILED(nsres)) {
502 ERR("Could not get nsIWritableVariant: %08x\n", nsres);
503 return NULL;
506 return ret;
509 nsICommandParams *create_nscommand_params(void)
511 nsICommandParams *ret = NULL;
512 nsresult nsres;
514 if(!pCompMgr)
515 return NULL;
517 nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr,
518 NS_COMMANDPARAMS_CONTRACTID, NULL, &IID_nsICommandParams,
519 (void**)&ret);
520 if(NS_FAILED(nsres))
521 ERR("Could not get nsICommandParams\n");
523 return ret;
526 static void nsnode_to_nsstring_rec(nsIContentSerializer *serializer, nsIDOMNode *nsnode, nsAString *str)
528 nsIDOMNodeList *node_list = NULL;
529 PRBool has_children = FALSE;
530 PRUint16 type;
531 nsresult nsres;
533 nsIDOMNode_HasChildNodes(nsnode, &has_children);
535 nsres = nsIDOMNode_GetNodeType(nsnode, &type);
536 if(NS_FAILED(nsres)) {
537 ERR("GetType failed: %08x\n", nsres);
538 return;
541 switch(type) {
542 case ELEMENT_NODE: {
543 nsIDOMElement *nselem;
544 nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMElement, (void**)&nselem);
545 nsIContentSerializer_AppendElementStart(serializer, nselem, has_children, str);
546 nsIDOMElement_Release(nselem);
547 break;
549 case TEXT_NODE: {
550 nsIDOMText *nstext;
551 nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMText, (void**)&nstext);
552 nsIContentSerializer_AppendText(serializer, nstext, 0, -1, str);
553 nsIDOMText_Release(nstext);
554 break;
556 case COMMENT_NODE: {
557 nsIDOMComment *nscomment;
558 nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMComment, (void**)&nscomment);
559 nsres = nsIContentSerializer_AppendComment(serializer, nscomment, 0, -1, str);
560 break;
562 case DOCUMENT_NODE: {
563 nsIDOMDocument *nsdoc;
564 nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMDocument, (void**)&nsdoc);
565 nsIContentSerializer_AppendDocumentStart(serializer, nsdoc, str);
566 nsIDOMDocument_Release(nsdoc);
567 break;
569 case DOCUMENT_FRAGMENT_NODE:
570 break;
571 default:
572 FIXME("Unhandled type %u\n", type);
575 if(has_children) {
576 PRUint32 child_cnt, i;
577 nsIDOMNode *child_node;
579 nsIDOMNode_GetChildNodes(nsnode, &node_list);
580 nsIDOMNodeList_GetLength(node_list, &child_cnt);
582 for(i=0; i<child_cnt; i++) {
583 nsres = nsIDOMNodeList_Item(node_list, i, &child_node);
584 if(NS_SUCCEEDED(nsres)) {
585 nsnode_to_nsstring_rec(serializer, child_node, str);
586 nsIDOMNode_Release(child_node);
587 }else {
588 ERR("Item failed: %08x\n", nsres);
592 nsIDOMNodeList_Release(node_list);
595 if(type == ELEMENT_NODE) {
596 nsIDOMElement *nselem;
597 nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMElement, (void**)&nselem);
598 nsIContentSerializer_AppendElementEnd(serializer, nselem, str);
599 nsIDOMElement_Release(nselem);
603 void nsnode_to_nsstring(nsIDOMNode *nsdoc, nsAString *str)
605 nsIContentSerializer *serializer;
606 nsIDOMNode *nsnode;
607 nsresult nsres;
609 nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr,
610 NS_HTMLSERIALIZER_CONTRACTID, NULL, &IID_nsIContentSerializer,
611 (void**)&serializer);
612 if(NS_FAILED(nsres)) {
613 ERR("Could not get nsIContentSerializer: %08x\n", nsres);
614 return;
617 nsres = nsIContentSerializer_Init(serializer, 0, 100, NULL, FALSE);
618 if(NS_FAILED(nsres))
619 ERR("Init failed: %08x\n", nsres);
621 nsIDOMDocument_QueryInterface(nsdoc, &IID_nsIDOMNode, (void**)&nsnode);
622 nsnode_to_nsstring_rec(serializer, nsnode, str);
623 nsIDOMNode_Release(nsnode);
625 nsres = nsIContentSerializer_Flush(serializer, str);
626 if(NS_FAILED(nsres))
627 ERR("Flush failed: %08x\n", nsres);
629 nsIContentSerializer_Release(serializer);
632 nsIController *get_editor_controller(NSContainer *This)
634 nsIController *ret = NULL;
635 nsIEditingSession *editing_session = NULL;
636 nsIInterfaceRequestor *iface_req;
637 nsIControllerContext *ctrlctx;
638 nsIEditor *editor = NULL;
639 nsresult nsres;
641 nsres = nsIWebBrowser_QueryInterface(This->webbrowser,
642 &IID_nsIInterfaceRequestor, (void**)&iface_req);
643 if(NS_FAILED(nsres)) {
644 ERR("Could not get nsIInterfaceRequestor: %08x\n", nsres);
645 return NULL;
648 nsres = nsIInterfaceRequestor_GetInterface(iface_req, &IID_nsIEditingSession,
649 (void**)&editing_session);
650 nsIInterfaceRequestor_Release(iface_req);
651 if(NS_FAILED(nsres)) {
652 ERR("Could not get nsIEditingSession: %08x\n", nsres);
653 return NULL;
656 nsres = nsIEditingSession_GetEditorForWindow(editing_session,
657 This->doc->window->nswindow, &editor);
658 nsIEditingSession_Release(editing_session);
659 if(NS_FAILED(nsres)) {
660 ERR("Could not get editor: %08x\n", nsres);
661 return NULL;
664 nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr,
665 NS_EDITORCONTROLLER_CONTRACTID, NULL, &IID_nsIControllerContext, (void**)&ctrlctx);
666 if(NS_SUCCEEDED(nsres)) {
667 nsres = nsIControllerContext_SetCommandContext(ctrlctx, editor);
668 if(NS_FAILED(nsres))
669 ERR("SetCommandContext failed: %08x\n", nsres);
670 nsres = nsIControllerContext_QueryInterface(ctrlctx, &IID_nsIController,
671 (void**)&ret);
672 nsIControllerContext_Release(ctrlctx);
673 if(NS_FAILED(nsres))
674 ERR("Could not get nsIController interface: %08x\n", nsres);
675 }else {
676 ERR("Could not create edit controller: %08x\n", nsres);
679 nsISupports_Release(editor);
681 return ret;
684 void set_ns_editmode(NSContainer *This)
686 nsIInterfaceRequestor *iface_req;
687 nsIEditingSession *editing_session = NULL;
688 nsIURIContentListener *listener = NULL;
689 nsIDOMWindow *dom_window = NULL;
690 nsresult nsres;
692 nsres = nsIWebBrowser_QueryInterface(This->webbrowser,
693 &IID_nsIInterfaceRequestor, (void**)&iface_req);
694 if(NS_FAILED(nsres)) {
695 ERR("Could not get nsIInterfaceRequestor: %08x\n", nsres);
696 return;
699 nsres = nsIInterfaceRequestor_GetInterface(iface_req, &IID_nsIEditingSession,
700 (void**)&editing_session);
701 nsIInterfaceRequestor_Release(iface_req);
702 if(NS_FAILED(nsres)) {
703 ERR("Could not get nsIEditingSession: %08x\n", nsres);
704 return;
707 nsres = nsIWebBrowser_GetContentDOMWindow(This->webbrowser, &dom_window);
708 if(NS_FAILED(nsres)) {
709 ERR("Could not get content DOM window: %08x\n", nsres);
710 nsIEditingSession_Release(editing_session);
711 return;
714 nsres = nsIEditingSession_MakeWindowEditable(editing_session, dom_window, NULL, FALSE);
715 nsIEditingSession_Release(editing_session);
716 nsIDOMWindow_Release(dom_window);
717 if(NS_FAILED(nsres)) {
718 ERR("MakeWindowEditable failed: %08x\n", nsres);
719 return;
722 /* MakeWindowEditable changes WebBrowser's parent URI content listener.
723 * It seams to be a bug in Gecko. To workaround it we set our content
724 * listener again and Gecko's one as its parent.
726 nsIWebBrowser_GetParentURIContentListener(This->webbrowser, &listener);
727 nsIURIContentListener_SetParentContentListener(NSURICL(This), listener);
728 nsIURIContentListener_Release(listener);
729 nsIWebBrowser_SetParentURIContentListener(This->webbrowser, NSURICL(This));
732 void close_gecko(void)
734 TRACE("()\n");
736 if(pCompMgr)
737 nsIComponentManager_Release(pCompMgr);
739 if(pServMgr)
740 nsIServiceManager_Release(pServMgr);
742 if(nsmem)
743 nsIMemory_Release(nsmem);
745 if(hXPCOM)
746 FreeLibrary(hXPCOM);
749 /**********************************************************
750 * nsIWebBrowserChrome interface
753 #define NSWBCHROME_THIS(iface) DEFINE_THIS(NSContainer, WebBrowserChrome, iface)
755 static nsresult NSAPI nsWebBrowserChrome_QueryInterface(nsIWebBrowserChrome *iface,
756 nsIIDRef riid, nsQIResult result)
758 NSContainer *This = NSWBCHROME_THIS(iface);
760 *result = NULL;
761 if(IsEqualGUID(&IID_nsISupports, riid)) {
762 TRACE("(%p)->(IID_nsISupports, %p)\n", This, result);
763 *result = NSWBCHROME(This);
764 }else if(IsEqualGUID(&IID_nsIWebBrowserChrome, riid)) {
765 TRACE("(%p)->(IID_nsIWebBrowserChrome, %p)\n", This, result);
766 *result = NSWBCHROME(This);
767 }else if(IsEqualGUID(&IID_nsIContextMenuListener, riid)) {
768 TRACE("(%p)->(IID_nsIContextMenuListener, %p)\n", This, result);
769 *result = NSCML(This);
770 }else if(IsEqualGUID(&IID_nsIURIContentListener, riid)) {
771 TRACE("(%p)->(IID_nsIURIContentListener %p)\n", This, result);
772 *result = NSURICL(This);
773 }else if(IsEqualGUID(&IID_nsIEmbeddingSiteWindow, riid)) {
774 TRACE("(%p)->(IID_nsIEmbeddingSiteWindow %p)\n", This, result);
775 *result = NSEMBWNDS(This);
776 }else if(IsEqualGUID(&IID_nsITooltipListener, riid)) {
777 TRACE("(%p)->(IID_nsITooltipListener %p)\n", This, result);
778 *result = NSTOOLTIP(This);
779 }else if(IsEqualGUID(&IID_nsIInterfaceRequestor, riid)) {
780 TRACE("(%p)->(IID_nsIInterfaceRequestor %p)\n", This, result);
781 *result = NSIFACEREQ(This);
782 }else if(IsEqualGUID(&IID_nsIWeakReference, riid)) {
783 TRACE("(%p)->(IID_nsIWeakReference %p)\n", This, result);
784 *result = NSWEAKREF(This);
785 }else if(IsEqualGUID(&IID_nsISupportsWeakReference, riid)) {
786 TRACE("(%p)->(IID_nsISupportsWeakReference %p)\n", This, result);
787 *result = NSSUPWEAKREF(This);
790 if(*result) {
791 nsIWebBrowserChrome_AddRef(NSWBCHROME(This));
792 return NS_OK;
795 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
796 return NS_NOINTERFACE;
799 static nsrefcnt NSAPI nsWebBrowserChrome_AddRef(nsIWebBrowserChrome *iface)
801 NSContainer *This = NSWBCHROME_THIS(iface);
802 LONG ref = InterlockedIncrement(&This->ref);
804 TRACE("(%p) ref=%d\n", This, ref);
806 return ref;
809 static nsrefcnt NSAPI nsWebBrowserChrome_Release(nsIWebBrowserChrome *iface)
811 NSContainer *This = NSWBCHROME_THIS(iface);
812 LONG ref = InterlockedDecrement(&This->ref);
814 TRACE("(%p) ref=%d\n", This, ref);
816 if(!ref) {
817 if(This->parent)
818 nsIWebBrowserChrome_Release(NSWBCHROME(This->parent));
819 mshtml_free(This);
822 return ref;
825 static nsresult NSAPI nsWebBrowserChrome_SetStatus(nsIWebBrowserChrome *iface,
826 PRUint32 statusType, const PRUnichar *status)
828 NSContainer *This = NSWBCHROME_THIS(iface);
829 TRACE("(%p)->(%d %s)\n", This, statusType, debugstr_w(status));
830 return NS_ERROR_NOT_IMPLEMENTED;
833 static nsresult NSAPI nsWebBrowserChrome_GetWebBrowser(nsIWebBrowserChrome *iface,
834 nsIWebBrowser **aWebBrowser)
836 NSContainer *This = NSWBCHROME_THIS(iface);
838 TRACE("(%p)->(%p)\n", This, aWebBrowser);
840 if(!aWebBrowser)
841 return NS_ERROR_INVALID_ARG;
843 if(This->webbrowser)
844 nsIWebBrowser_AddRef(This->webbrowser);
845 *aWebBrowser = This->webbrowser;
846 return S_OK;
849 static nsresult NSAPI nsWebBrowserChrome_SetWebBrowser(nsIWebBrowserChrome *iface,
850 nsIWebBrowser *aWebBrowser)
852 NSContainer *This = NSWBCHROME_THIS(iface);
854 TRACE("(%p)->(%p)\n", This, aWebBrowser);
856 if(aWebBrowser != This->webbrowser)
857 ERR("Wrong nsWebBrowser!\n");
859 return NS_OK;
862 static nsresult NSAPI nsWebBrowserChrome_GetChromeFlags(nsIWebBrowserChrome *iface,
863 PRUint32 *aChromeFlags)
865 NSContainer *This = NSWBCHROME_THIS(iface);
866 WARN("(%p)->(%p)\n", This, aChromeFlags);
867 return NS_ERROR_NOT_IMPLEMENTED;
870 static nsresult NSAPI nsWebBrowserChrome_SetChromeFlags(nsIWebBrowserChrome *iface,
871 PRUint32 aChromeFlags)
873 NSContainer *This = NSWBCHROME_THIS(iface);
874 WARN("(%p)->(%08x)\n", This, aChromeFlags);
875 return NS_ERROR_NOT_IMPLEMENTED;
878 static nsresult NSAPI nsWebBrowserChrome_DestroyBrowserWindow(nsIWebBrowserChrome *iface)
880 NSContainer *This = NSWBCHROME_THIS(iface);
881 TRACE("(%p)\n", This);
882 return NS_ERROR_NOT_IMPLEMENTED;
885 static nsresult NSAPI nsWebBrowserChrome_SizeBrowserTo(nsIWebBrowserChrome *iface,
886 PRInt32 aCX, PRInt32 aCY)
888 NSContainer *This = NSWBCHROME_THIS(iface);
889 WARN("(%p)->(%d %d)\n", This, aCX, aCY);
890 return NS_ERROR_NOT_IMPLEMENTED;
893 static nsresult NSAPI nsWebBrowserChrome_ShowAsModal(nsIWebBrowserChrome *iface)
895 NSContainer *This = NSWBCHROME_THIS(iface);
896 WARN("(%p)\n", This);
897 return NS_ERROR_NOT_IMPLEMENTED;
900 static nsresult NSAPI nsWebBrowserChrome_IsWindowModal(nsIWebBrowserChrome *iface, PRBool *_retval)
902 NSContainer *This = NSWBCHROME_THIS(iface);
903 WARN("(%p)->(%p)\n", This, _retval);
904 return NS_ERROR_NOT_IMPLEMENTED;
907 static nsresult NSAPI nsWebBrowserChrome_ExitModalEventLoop(nsIWebBrowserChrome *iface,
908 nsresult aStatus)
910 NSContainer *This = NSWBCHROME_THIS(iface);
911 WARN("(%p)->(%08x)\n", This, aStatus);
912 return NS_ERROR_NOT_IMPLEMENTED;
915 #undef NSWBCHROME_THIS
917 static const nsIWebBrowserChromeVtbl nsWebBrowserChromeVtbl = {
918 nsWebBrowserChrome_QueryInterface,
919 nsWebBrowserChrome_AddRef,
920 nsWebBrowserChrome_Release,
921 nsWebBrowserChrome_SetStatus,
922 nsWebBrowserChrome_GetWebBrowser,
923 nsWebBrowserChrome_SetWebBrowser,
924 nsWebBrowserChrome_GetChromeFlags,
925 nsWebBrowserChrome_SetChromeFlags,
926 nsWebBrowserChrome_DestroyBrowserWindow,
927 nsWebBrowserChrome_SizeBrowserTo,
928 nsWebBrowserChrome_ShowAsModal,
929 nsWebBrowserChrome_IsWindowModal,
930 nsWebBrowserChrome_ExitModalEventLoop
933 /**********************************************************
934 * nsIContextMenuListener interface
937 #define NSCML_THIS(iface) DEFINE_THIS(NSContainer, ContextMenuListener, iface)
939 static nsresult NSAPI nsContextMenuListener_QueryInterface(nsIContextMenuListener *iface,
940 nsIIDRef riid, nsQIResult result)
942 NSContainer *This = NSCML_THIS(iface);
943 return nsIWebBrowserChrome_QueryInterface(NSWBCHROME(This), riid, result);
946 static nsrefcnt NSAPI nsContextMenuListener_AddRef(nsIContextMenuListener *iface)
948 NSContainer *This = NSCML_THIS(iface);
949 return nsIWebBrowserChrome_AddRef(NSWBCHROME(This));
952 static nsrefcnt NSAPI nsContextMenuListener_Release(nsIContextMenuListener *iface)
954 NSContainer *This = NSCML_THIS(iface);
955 return nsIWebBrowserChrome_Release(NSWBCHROME(This));
958 static nsresult NSAPI nsContextMenuListener_OnShowContextMenu(nsIContextMenuListener *iface,
959 PRUint32 aContextFlags, nsIDOMEvent *aEvent, nsIDOMNode *aNode)
961 NSContainer *This = NSCML_THIS(iface);
962 nsIDOMMouseEvent *event;
963 POINT pt;
964 DWORD dwID = CONTEXT_MENU_DEFAULT;
965 nsresult nsres;
967 TRACE("(%p)->(%08x %p %p)\n", This, aContextFlags, aEvent, aNode);
969 nsres = nsIDOMEvent_QueryInterface(aEvent, &IID_nsIDOMMouseEvent, (void**)&event);
970 if(NS_FAILED(nsres)) {
971 ERR("Could not get nsIDOMMouseEvent interface: %08x\n", nsres);
972 return nsres;
975 nsIDOMMouseEvent_GetScreenX(event, &pt.x);
976 nsIDOMMouseEvent_GetScreenY(event, &pt.y);
977 nsIDOMMouseEvent_Release(event);
979 switch(aContextFlags) {
980 case CONTEXT_NONE:
981 case CONTEXT_DOCUMENT:
982 case CONTEXT_TEXT:
983 dwID = CONTEXT_MENU_DEFAULT;
984 break;
985 case CONTEXT_IMAGE:
986 case CONTEXT_IMAGE|CONTEXT_LINK:
987 dwID = CONTEXT_MENU_IMAGE;
988 break;
989 case CONTEXT_LINK:
990 dwID = CONTEXT_MENU_ANCHOR;
991 break;
992 case CONTEXT_INPUT:
993 dwID = CONTEXT_MENU_CONTROL;
994 break;
995 default:
996 FIXME("aContextFlags=%08x\n", aContextFlags);
999 show_context_menu(This->doc, dwID, &pt);
1001 return NS_OK;
1004 #undef NSCML_THIS
1006 static const nsIContextMenuListenerVtbl nsContextMenuListenerVtbl = {
1007 nsContextMenuListener_QueryInterface,
1008 nsContextMenuListener_AddRef,
1009 nsContextMenuListener_Release,
1010 nsContextMenuListener_OnShowContextMenu
1013 /**********************************************************
1014 * nsIURIContentListener interface
1017 #define NSURICL_THIS(iface) DEFINE_THIS(NSContainer, URIContentListener, iface)
1019 static nsresult NSAPI nsURIContentListener_QueryInterface(nsIURIContentListener *iface,
1020 nsIIDRef riid, nsQIResult result)
1022 NSContainer *This = NSURICL_THIS(iface);
1023 return nsIWebBrowserChrome_QueryInterface(NSWBCHROME(This), riid, result);
1026 static nsrefcnt NSAPI nsURIContentListener_AddRef(nsIURIContentListener *iface)
1028 NSContainer *This = NSURICL_THIS(iface);
1029 return nsIWebBrowserChrome_AddRef(NSWBCHROME(This));
1032 static nsrefcnt NSAPI nsURIContentListener_Release(nsIURIContentListener *iface)
1034 NSContainer *This = NSURICL_THIS(iface);
1035 return nsIWebBrowserChrome_Release(NSWBCHROME(This));
1038 static nsresult NSAPI nsURIContentListener_OnStartURIOpen(nsIURIContentListener *iface,
1039 nsIURI *aURI, PRBool *_retval)
1041 NSContainer *This = NSURICL_THIS(iface);
1042 nsIWineURI *wine_uri;
1043 nsACString spec_str;
1044 const char *spec;
1045 nsresult nsres;
1047 nsACString_Init(&spec_str, NULL);
1048 nsIURI_GetSpec(aURI, &spec_str);
1049 nsACString_GetData(&spec_str, &spec, NULL);
1051 TRACE("(%p)->(%p(%s) %p)\n", This, aURI, debugstr_a(spec), _retval);
1053 nsACString_Finish(&spec_str);
1055 nsres = nsIURI_QueryInterface(aURI, &IID_nsIWineURI, (void**)&wine_uri);
1056 if(NS_FAILED(nsres)) {
1057 WARN("Could not get nsIWineURI interface: %08x\n", nsres);
1058 return NS_ERROR_NOT_IMPLEMENTED;
1061 nsIWineURI_SetNSContainer(wine_uri, This);
1062 nsIWineURI_SetIsDocumentURI(wine_uri, TRUE);
1064 if(This->bscallback && This->bscallback->mon) {
1065 LPWSTR wine_url;
1066 HRESULT hres;
1068 hres = IMoniker_GetDisplayName(This->bscallback->mon, NULL, 0, &wine_url);
1069 if(SUCCEEDED(hres)) {
1070 nsIWineURI_SetWineURL(wine_uri, wine_url);
1071 CoTaskMemFree(wine_url);
1072 }else {
1073 WARN("GetDisplayName failed: %08x\n", hres);
1077 nsIWineURI_Release(wine_uri);
1079 *_retval = FALSE;
1080 return This->content_listener
1081 ? nsIURIContentListener_OnStartURIOpen(This->content_listener, aURI, _retval)
1082 : NS_OK;
1085 static nsresult NSAPI nsURIContentListener_DoContent(nsIURIContentListener *iface,
1086 const char *aContentType, PRBool aIsContentPreferred, nsIRequest *aRequest,
1087 nsIStreamListener **aContentHandler, PRBool *_retval)
1089 NSContainer *This = NSURICL_THIS(iface);
1091 TRACE("(%p)->(%s %x %p %p %p)\n", This, debugstr_a(aContentType), aIsContentPreferred,
1092 aRequest, aContentHandler, _retval);
1094 return This->content_listener
1095 ? nsIURIContentListener_DoContent(This->content_listener, aContentType,
1096 aIsContentPreferred, aRequest, aContentHandler, _retval)
1097 : NS_ERROR_NOT_IMPLEMENTED;
1100 static nsresult NSAPI nsURIContentListener_IsPreferred(nsIURIContentListener *iface,
1101 const char *aContentType, char **aDesiredContentType, PRBool *_retval)
1103 NSContainer *This = NSURICL_THIS(iface);
1105 TRACE("(%p)->(%s %p %p)\n", This, debugstr_a(aContentType), aDesiredContentType, _retval);
1107 /* FIXME: Should we do something here? */
1108 *_retval = TRUE;
1110 return This->content_listener
1111 ? nsIURIContentListener_IsPreferred(This->content_listener, aContentType,
1112 aDesiredContentType, _retval)
1113 : NS_OK;
1116 static nsresult NSAPI nsURIContentListener_CanHandleContent(nsIURIContentListener *iface,
1117 const char *aContentType, PRBool aIsContentPreferred, char **aDesiredContentType,
1118 PRBool *_retval)
1120 NSContainer *This = NSURICL_THIS(iface);
1122 TRACE("(%p)->(%s %x %p %p)\n", This, debugstr_a(aContentType), aIsContentPreferred,
1123 aDesiredContentType, _retval);
1125 return This->content_listener
1126 ? nsIURIContentListener_CanHandleContent(This->content_listener, aContentType,
1127 aIsContentPreferred, aDesiredContentType, _retval)
1128 : NS_ERROR_NOT_IMPLEMENTED;
1131 static nsresult NSAPI nsURIContentListener_GetLoadCookie(nsIURIContentListener *iface,
1132 nsISupports **aLoadCookie)
1134 NSContainer *This = NSURICL_THIS(iface);
1136 WARN("(%p)->(%p)\n", This, aLoadCookie);
1138 return This->content_listener
1139 ? nsIURIContentListener_GetLoadCookie(This->content_listener, aLoadCookie)
1140 : NS_ERROR_NOT_IMPLEMENTED;
1143 static nsresult NSAPI nsURIContentListener_SetLoadCookie(nsIURIContentListener *iface,
1144 nsISupports *aLoadCookie)
1146 NSContainer *This = NSURICL_THIS(iface);
1148 WARN("(%p)->(%p)\n", This, aLoadCookie);
1150 return This->content_listener
1151 ? nsIURIContentListener_SetLoadCookie(This->content_listener, aLoadCookie)
1152 : NS_ERROR_NOT_IMPLEMENTED;
1155 static nsresult NSAPI nsURIContentListener_GetParentContentListener(nsIURIContentListener *iface,
1156 nsIURIContentListener **aParentContentListener)
1158 NSContainer *This = NSURICL_THIS(iface);
1160 TRACE("(%p)->(%p)\n", This, aParentContentListener);
1162 if(This->content_listener)
1163 nsIURIContentListener_AddRef(This->content_listener);
1165 *aParentContentListener = This->content_listener;
1166 return NS_OK;
1169 static nsresult NSAPI nsURIContentListener_SetParentContentListener(nsIURIContentListener *iface,
1170 nsIURIContentListener *aParentContentListener)
1172 NSContainer *This = NSURICL_THIS(iface);
1174 TRACE("(%p)->(%p)\n", This, aParentContentListener);
1176 if(aParentContentListener == NSURICL(This))
1177 return NS_OK;
1179 if(This->content_listener)
1180 nsIURIContentListener_Release(This->content_listener);
1182 This->content_listener = aParentContentListener;
1183 if(This->content_listener)
1184 nsIURIContentListener_AddRef(This->content_listener);
1186 return NS_OK;
1189 #undef NSURICL_THIS
1191 static const nsIURIContentListenerVtbl nsURIContentListenerVtbl = {
1192 nsURIContentListener_QueryInterface,
1193 nsURIContentListener_AddRef,
1194 nsURIContentListener_Release,
1195 nsURIContentListener_OnStartURIOpen,
1196 nsURIContentListener_DoContent,
1197 nsURIContentListener_IsPreferred,
1198 nsURIContentListener_CanHandleContent,
1199 nsURIContentListener_GetLoadCookie,
1200 nsURIContentListener_SetLoadCookie,
1201 nsURIContentListener_GetParentContentListener,
1202 nsURIContentListener_SetParentContentListener
1205 /**********************************************************
1206 * nsIEmbeddinSiteWindow interface
1209 #define NSEMBWNDS_THIS(iface) DEFINE_THIS(NSContainer, EmbeddingSiteWindow, iface)
1211 static nsresult NSAPI nsEmbeddingSiteWindow_QueryInterface(nsIEmbeddingSiteWindow *iface,
1212 nsIIDRef riid, nsQIResult result)
1214 NSContainer *This = NSEMBWNDS_THIS(iface);
1215 return nsIWebBrowserChrome_QueryInterface(NSWBCHROME(This), riid, result);
1218 static nsrefcnt NSAPI nsEmbeddingSiteWindow_AddRef(nsIEmbeddingSiteWindow *iface)
1220 NSContainer *This = NSEMBWNDS_THIS(iface);
1221 return nsIWebBrowserChrome_AddRef(NSWBCHROME(This));
1224 static nsrefcnt NSAPI nsEmbeddingSiteWindow_Release(nsIEmbeddingSiteWindow *iface)
1226 NSContainer *This = NSEMBWNDS_THIS(iface);
1227 return nsIWebBrowserChrome_Release(NSWBCHROME(This));
1230 static nsresult NSAPI nsEmbeddingSiteWindow_SetDimensions(nsIEmbeddingSiteWindow *iface,
1231 PRUint32 flags, PRInt32 x, PRInt32 y, PRInt32 cx, PRInt32 cy)
1233 NSContainer *This = NSEMBWNDS_THIS(iface);
1234 WARN("(%p)->(%08x %d %d %d %d)\n", This, flags, x, y, cx, cy);
1235 return NS_ERROR_NOT_IMPLEMENTED;
1238 static nsresult NSAPI nsEmbeddingSiteWindow_GetDimensions(nsIEmbeddingSiteWindow *iface,
1239 PRUint32 flags, PRInt32 *x, PRInt32 *y, PRInt32 *cx, PRInt32 *cy)
1241 NSContainer *This = NSEMBWNDS_THIS(iface);
1242 WARN("(%p)->(%08x %p %p %p %p)\n", This, flags, x, y, cx, cy);
1243 return NS_ERROR_NOT_IMPLEMENTED;
1246 static nsresult NSAPI nsEmbeddingSiteWindow_SetFocus(nsIEmbeddingSiteWindow *iface)
1248 NSContainer *This = NSEMBWNDS_THIS(iface);
1250 TRACE("(%p)\n", This);
1252 return nsIBaseWindow_SetFocus(This->window);
1255 static nsresult NSAPI nsEmbeddingSiteWindow_GetVisibility(nsIEmbeddingSiteWindow *iface,
1256 PRBool *aVisibility)
1258 NSContainer *This = NSEMBWNDS_THIS(iface);
1260 TRACE("(%p)->(%p)\n", This, aVisibility);
1262 *aVisibility = This->doc && This->doc->hwnd && IsWindowVisible(This->doc->hwnd);
1263 return NS_OK;
1266 static nsresult NSAPI nsEmbeddingSiteWindow_SetVisibility(nsIEmbeddingSiteWindow *iface,
1267 PRBool aVisibility)
1269 NSContainer *This = NSEMBWNDS_THIS(iface);
1271 TRACE("(%p)->(%x)\n", This, aVisibility);
1273 return NS_OK;
1276 static nsresult NSAPI nsEmbeddingSiteWindow_GetTitle(nsIEmbeddingSiteWindow *iface,
1277 PRUnichar **aTitle)
1279 NSContainer *This = NSEMBWNDS_THIS(iface);
1280 WARN("(%p)->(%p)\n", This, aTitle);
1281 return NS_ERROR_NOT_IMPLEMENTED;
1284 static nsresult NSAPI nsEmbeddingSiteWindow_SetTitle(nsIEmbeddingSiteWindow *iface,
1285 const PRUnichar *aTitle)
1287 NSContainer *This = NSEMBWNDS_THIS(iface);
1288 WARN("(%p)->(%s)\n", This, debugstr_w(aTitle));
1289 return NS_ERROR_NOT_IMPLEMENTED;
1292 static nsresult NSAPI nsEmbeddingSiteWindow_GetSiteWindow(nsIEmbeddingSiteWindow *iface,
1293 void **aSiteWindow)
1295 NSContainer *This = NSEMBWNDS_THIS(iface);
1297 TRACE("(%p)->(%p)\n", This, aSiteWindow);
1299 *aSiteWindow = This->hwnd;
1300 return NS_OK;
1303 static const nsIEmbeddingSiteWindowVtbl nsEmbeddingSiteWindowVtbl = {
1304 nsEmbeddingSiteWindow_QueryInterface,
1305 nsEmbeddingSiteWindow_AddRef,
1306 nsEmbeddingSiteWindow_Release,
1307 nsEmbeddingSiteWindow_SetDimensions,
1308 nsEmbeddingSiteWindow_GetDimensions,
1309 nsEmbeddingSiteWindow_SetFocus,
1310 nsEmbeddingSiteWindow_GetVisibility,
1311 nsEmbeddingSiteWindow_SetVisibility,
1312 nsEmbeddingSiteWindow_GetTitle,
1313 nsEmbeddingSiteWindow_SetTitle,
1314 nsEmbeddingSiteWindow_GetSiteWindow
1317 #define NSTOOLTIP_THIS(iface) DEFINE_THIS(NSContainer, TooltipListener, iface)
1319 static nsresult NSAPI nsTooltipListener_QueryInterface(nsITooltipListener *iface, nsIIDRef riid,
1320 nsQIResult result)
1322 NSContainer *This = NSTOOLTIP_THIS(iface);
1323 return nsIWebBrowserChrome_QueryInterface(NSWBCHROME(This), riid, result);
1326 static nsrefcnt NSAPI nsTooltipListener_AddRef(nsITooltipListener *iface)
1328 NSContainer *This = NSTOOLTIP_THIS(iface);
1329 return nsIWebBrowserChrome_AddRef(NSWBCHROME(This));
1332 static nsrefcnt NSAPI nsTooltipListener_Release(nsITooltipListener *iface)
1334 NSContainer *This = NSTOOLTIP_THIS(iface);
1335 return nsIWebBrowserChrome_AddRef(NSWBCHROME(This));
1338 static nsresult NSAPI nsTooltipListener_OnShowTooltip(nsITooltipListener *iface,
1339 PRInt32 aXCoord, PRInt32 aYCoord, const PRUnichar *aTipText)
1341 NSContainer *This = NSTOOLTIP_THIS(iface);
1343 show_tooltip(This->doc, aXCoord, aYCoord, aTipText);
1345 return NS_OK;
1348 static nsresult NSAPI nsTooltipListener_OnHideTooltip(nsITooltipListener *iface)
1350 NSContainer *This = NSTOOLTIP_THIS(iface);
1352 hide_tooltip(This->doc);
1354 return NS_OK;
1357 #undef NSTOOLTIM_THIS
1359 static const nsITooltipListenerVtbl nsTooltipListenerVtbl = {
1360 nsTooltipListener_QueryInterface,
1361 nsTooltipListener_AddRef,
1362 nsTooltipListener_Release,
1363 nsTooltipListener_OnShowTooltip,
1364 nsTooltipListener_OnHideTooltip
1367 #define NSIFACEREQ_THIS(iface) DEFINE_THIS(NSContainer, InterfaceRequestor, iface)
1369 static nsresult NSAPI nsInterfaceRequestor_QueryInterface(nsIInterfaceRequestor *iface,
1370 nsIIDRef riid, nsQIResult result)
1372 NSContainer *This = NSIFACEREQ_THIS(iface);
1373 return nsIWebBrowserChrome_QueryInterface(NSWBCHROME(This), riid, result);
1376 static nsrefcnt NSAPI nsInterfaceRequestor_AddRef(nsIInterfaceRequestor *iface)
1378 NSContainer *This = NSIFACEREQ_THIS(iface);
1379 return nsIWebBrowserChrome_AddRef(NSWBCHROME(This));
1382 static nsrefcnt NSAPI nsInterfaceRequestor_Release(nsIInterfaceRequestor *iface)
1384 NSContainer *This = NSIFACEREQ_THIS(iface);
1385 return nsIWebBrowserChrome_Release(NSWBCHROME(This));
1388 static nsresult NSAPI nsInterfaceRequestor_GetInterface(nsIInterfaceRequestor *iface,
1389 nsIIDRef riid, nsQIResult result)
1391 NSContainer *This = NSIFACEREQ_THIS(iface);
1393 if(IsEqualGUID(&IID_nsIDOMWindow, riid)) {
1394 TRACE("(%p)->(IID_nsIDOMWindow %p)\n", This, result);
1395 return nsIWebBrowser_GetContentDOMWindow(This->webbrowser, (nsIDOMWindow**)result);
1398 return nsIWebBrowserChrome_QueryInterface(NSWBCHROME(This), riid, result);
1401 #undef NSIFACEREQ_THIS
1403 static const nsIInterfaceRequestorVtbl nsInterfaceRequestorVtbl = {
1404 nsInterfaceRequestor_QueryInterface,
1405 nsInterfaceRequestor_AddRef,
1406 nsInterfaceRequestor_Release,
1407 nsInterfaceRequestor_GetInterface
1410 #define NSWEAKREF_THIS(iface) DEFINE_THIS(NSContainer, WeakReference, iface)
1412 static nsresult NSAPI nsWeakReference_QueryInterface(nsIWeakReference *iface,
1413 nsIIDRef riid, nsQIResult result)
1415 NSContainer *This = NSWEAKREF_THIS(iface);
1416 return nsIWebBrowserChrome_QueryInterface(NSWBCHROME(This), riid, result);
1419 static nsrefcnt NSAPI nsWeakReference_AddRef(nsIWeakReference *iface)
1421 NSContainer *This = NSWEAKREF_THIS(iface);
1422 return nsIWebBrowserChrome_AddRef(NSWBCHROME(This));
1425 static nsrefcnt NSAPI nsWeakReference_Release(nsIWeakReference *iface)
1427 NSContainer *This = NSWEAKREF_THIS(iface);
1428 return nsIWebBrowserChrome_Release(NSWBCHROME(This));
1431 static nsresult NSAPI nsWeakReference_QueryReferent(nsIWeakReference *iface,
1432 const nsIID *riid, void **result)
1434 NSContainer *This = NSWEAKREF_THIS(iface);
1435 return nsIWebBrowserChrome_QueryInterface(NSWBCHROME(This), riid, result);
1438 #undef NSWEAKREF_THIS
1440 static const nsIWeakReferenceVtbl nsWeakReferenceVtbl = {
1441 nsWeakReference_QueryInterface,
1442 nsWeakReference_AddRef,
1443 nsWeakReference_Release,
1444 nsWeakReference_QueryReferent
1447 #define NSSUPWEAKREF_THIS(iface) DEFINE_THIS(NSContainer, SupportsWeakReference, iface)
1449 static nsresult NSAPI nsSupportsWeakReference_QueryInterface(nsISupportsWeakReference *iface,
1450 nsIIDRef riid, nsQIResult result)
1452 NSContainer *This = NSSUPWEAKREF_THIS(iface);
1453 return nsIWebBrowserChrome_QueryInterface(NSWBCHROME(This), riid, result);
1456 static nsrefcnt NSAPI nsSupportsWeakReference_AddRef(nsISupportsWeakReference *iface)
1458 NSContainer *This = NSSUPWEAKREF_THIS(iface);
1459 return nsIWebBrowserChrome_AddRef(NSWBCHROME(This));
1462 static nsrefcnt NSAPI nsSupportsWeakReference_Release(nsISupportsWeakReference *iface)
1464 NSContainer *This = NSSUPWEAKREF_THIS(iface);
1465 return nsIWebBrowserChrome_Release(NSWBCHROME(This));
1468 static nsresult NSAPI nsSupportsWeakReference_GetWeakReference(nsISupportsWeakReference *iface,
1469 nsIWeakReference **_retval)
1471 NSContainer *This = NSSUPWEAKREF_THIS(iface);
1473 TRACE("(%p)->(%p)\n", This, _retval);
1475 nsIWeakReference_AddRef(NSWEAKREF(This));
1476 *_retval = NSWEAKREF(This);
1477 return NS_OK;
1480 #undef NSWEAKREF_THIS
1482 static const nsISupportsWeakReferenceVtbl nsSupportsWeakReferenceVtbl = {
1483 nsSupportsWeakReference_QueryInterface,
1484 nsSupportsWeakReference_AddRef,
1485 nsSupportsWeakReference_Release,
1486 nsSupportsWeakReference_GetWeakReference
1490 NSContainer *NSContainer_Create(HTMLDocument *doc, NSContainer *parent)
1492 nsIWebBrowserSetup *wbsetup;
1493 nsIScrollable *scrollable;
1494 NSContainer *ret;
1495 nsresult nsres;
1497 if(!load_gecko())
1498 return NULL;
1500 ret = mshtml_alloc(sizeof(NSContainer));
1502 ret->lpWebBrowserChromeVtbl = &nsWebBrowserChromeVtbl;
1503 ret->lpContextMenuListenerVtbl = &nsContextMenuListenerVtbl;
1504 ret->lpURIContentListenerVtbl = &nsURIContentListenerVtbl;
1505 ret->lpEmbeddingSiteWindowVtbl = &nsEmbeddingSiteWindowVtbl;
1506 ret->lpTooltipListenerVtbl = &nsTooltipListenerVtbl;
1507 ret->lpInterfaceRequestorVtbl = &nsInterfaceRequestorVtbl;
1508 ret->lpWeakReferenceVtbl = &nsWeakReferenceVtbl;
1509 ret->lpSupportsWeakReferenceVtbl = &nsSupportsWeakReferenceVtbl;
1511 ret->doc = doc;
1512 ret->ref = 1;
1513 ret->bscallback = NULL;
1514 ret->content_listener = NULL;
1515 ret->editor_controller = NULL;
1517 if(parent)
1518 nsIWebBrowserChrome_AddRef(NSWBCHROME(parent));
1519 ret->parent = parent;
1521 nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr, NS_WEBBROWSER_CONTRACTID,
1522 NULL, &IID_nsIWebBrowser, (void**)&ret->webbrowser);
1523 if(NS_FAILED(nsres))
1524 ERR("Creating WebBrowser failed: %08x\n", nsres);
1526 nsres = nsIWebBrowser_SetContainerWindow(ret->webbrowser, NSWBCHROME(ret));
1527 if(NS_FAILED(nsres))
1528 ERR("SetContainerWindow failed: %08x\n", nsres);
1530 nsres = nsIWebBrowser_QueryInterface(ret->webbrowser, &IID_nsIBaseWindow,
1531 (void**)&ret->window);
1532 if(NS_FAILED(nsres))
1533 ERR("Could not get nsIBaseWindow interface: %08x\n", nsres);
1535 nsres = nsIWebBrowser_QueryInterface(ret->webbrowser, &IID_nsIWebBrowserSetup,
1536 (void**)&wbsetup);
1537 if(NS_SUCCEEDED(nsres)) {
1538 nsres = nsIWebBrowserSetup_SetProperty(wbsetup, SETUP_IS_CHROME_WRAPPER, TRUE);
1539 nsIWebBrowserSetup_Release(wbsetup);
1540 if(NS_FAILED(nsres))
1541 ERR("SetProperty(SETUP_IS_CHROME_WRAPPER) failed: %08x\n", nsres);
1542 }else {
1543 ERR("Could not get nsIWebBrowserSetup interface\n");
1546 nsres = nsIWebBrowser_QueryInterface(ret->webbrowser, &IID_nsIWebNavigation,
1547 (void**)&ret->navigation);
1548 if(NS_FAILED(nsres))
1549 ERR("Could not get nsIWebNavigation interface: %08x\n", nsres);
1551 nsres = nsIWebBrowserFocus_QueryInterface(ret->webbrowser, &IID_nsIWebBrowserFocus,
1552 (void**)&ret->focus);
1553 if(NS_FAILED(nsres))
1554 ERR("Could not get nsIWebBrowserFocus interface: %08x\n", nsres);
1556 if(!nscontainer_class)
1557 register_nscontainer_class();
1559 ret->hwnd = CreateWindowExW(0, wszNsContainer, NULL,
1560 WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, 100, 100,
1561 GetDesktopWindow(), NULL, hInst, ret);
1563 nsres = nsIBaseWindow_InitWindow(ret->window, ret->hwnd, NULL, 0, 0, 100, 100);
1564 if(NS_SUCCEEDED(nsres)) {
1565 nsres = nsIBaseWindow_Create(ret->window);
1566 if(NS_FAILED(nsres))
1567 WARN("Creating window failed: %08x\n", nsres);
1569 nsIBaseWindow_SetVisibility(ret->window, FALSE);
1570 nsIBaseWindow_SetEnabled(ret->window, FALSE);
1571 }else {
1572 ERR("InitWindow failed: %08x\n", nsres);
1575 nsres = nsIWebBrowser_SetParentURIContentListener(ret->webbrowser, NSURICL(ret));
1576 if(NS_FAILED(nsres))
1577 ERR("SetParentURIContentListener failed: %08x\n", nsres);
1579 init_nsevents(ret);
1581 nsres = nsIWebBrowser_QueryInterface(ret->webbrowser, &IID_nsIScrollable, (void**)&scrollable);
1582 if(NS_SUCCEEDED(nsres)) {
1583 nsres = nsIScrollable_SetDefaultScrollbarPreferences(scrollable,
1584 ScrollOrientation_Y, Scrollbar_Always);
1585 if(NS_FAILED(nsres))
1586 ERR("Could not set default Y scrollbar prefs: %08x\n", nsres);
1588 nsres = nsIScrollable_SetDefaultScrollbarPreferences(scrollable,
1589 ScrollOrientation_X, Scrollbar_Auto);
1590 if(NS_FAILED(nsres))
1591 ERR("Could not set default X scrollbar prefs: %08x\n", nsres);
1593 nsIScrollable_Release(scrollable);
1594 }else {
1595 ERR("Could not get nsIScrollable: %08x\n", nsres);
1598 return ret;
1601 void NSContainer_Release(NSContainer *This)
1603 TRACE("(%p)\n", This);
1605 ShowWindow(This->hwnd, SW_HIDE);
1606 SetParent(This->hwnd, NULL);
1608 nsIBaseWindow_SetVisibility(This->window, FALSE);
1609 nsIBaseWindow_Destroy(This->window);
1611 nsIWebBrowser_SetContainerWindow(This->webbrowser, NULL);
1613 nsIWebBrowser_Release(This->webbrowser);
1614 This->webbrowser = NULL;
1616 nsIWebNavigation_Release(This->navigation);
1617 This->navigation = NULL;
1619 nsIBaseWindow_Release(This->window);
1620 This->window = NULL;
1622 nsIWebBrowserFocus_Release(This->focus);
1623 This->focus = NULL;
1625 if(This->editor_controller) {
1626 nsIController_Release(This->editor_controller);
1627 This->editor_controller = NULL;
1630 if(This->content_listener) {
1631 nsIURIContentListener_Release(This->content_listener);
1632 This->content_listener = NULL;
1635 if(This->hwnd) {
1636 DestroyWindow(This->hwnd);
1637 This->hwnd = NULL;
1640 nsIWebBrowserChrome_Release(NSWBCHROME(This));