ntdll/tests: Use correct prototype for RtlCreateUnicodeString[FromAsciiz].
[wine.git] / dlls / mshtml / nsembed.c
blob4e7246444b16910345c676db61fd89228e81666c
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>
22 #include <assert.h>
24 #define COBJMACROS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "winreg.h"
30 #include "ole2.h"
31 #include "shlobj.h"
32 #include "shlwapi.h"
34 #include "wine/debug.h"
36 #include "mshtml_private.h"
37 #include "htmlevent.h"
38 #include "binding.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
41 WINE_DECLARE_DEBUG_CHANNEL(gecko);
43 #define NS_APPSTARTUPNOTIFIER_CONTRACTID "@mozilla.org/embedcomp/appstartup-notifier;1"
44 #define NS_WEBBROWSER_CONTRACTID "@mozilla.org/embedding/browser/nsWebBrowser;1"
45 #define NS_MEMORY_CONTRACTID "@mozilla.org/xpcom/memory-service;1"
46 #define NS_COMMANDPARAMS_CONTRACTID "@mozilla.org/embedcomp/command-params;1"
47 #define NS_HTMLSERIALIZER_CONTRACTID "@mozilla.org/layout/contentserializer;1?mimetype=text/html"
48 #define NS_EDITORCONTROLLER_CONTRACTID "@mozilla.org/editor/editorcontroller;1"
49 #define NS_PREFERENCES_CONTRACTID "@mozilla.org/preferences;1"
50 #define NS_VARIANT_CONTRACTID "@mozilla.org/variant;1"
52 #define PR_UINT32_MAX 0xffffffff
54 #define NS_STRING_CONTAINER_INIT_DEPEND 0x0002
55 #define NS_CSTRING_CONTAINER_INIT_DEPEND 0x0002
57 typedef UINT32 PRUint32;
59 static nsresult (CDECL *NS_InitXPCOM2)(nsIServiceManager**,void*,void*);
60 static nsresult (CDECL *NS_ShutdownXPCOM)(nsIServiceManager*);
61 static nsresult (CDECL *NS_GetComponentRegistrar)(nsIComponentRegistrar**);
62 static nsresult (CDECL *NS_StringContainerInit2)(nsStringContainer*,const PRUnichar*,PRUint32,PRUint32);
63 static nsresult (CDECL *NS_CStringContainerInit2)(nsCStringContainer*,const char*,PRUint32,PRUint32);
64 static nsresult (CDECL *NS_StringContainerFinish)(nsStringContainer*);
65 static nsresult (CDECL *NS_CStringContainerFinish)(nsCStringContainer*);
66 static nsresult (CDECL *NS_StringSetData)(nsAString*,const PRUnichar*,PRUint32);
67 static nsresult (CDECL *NS_CStringSetData)(nsACString*,const char*,PRUint32);
68 static nsresult (CDECL *NS_NewLocalFile)(const nsAString*,cpp_bool,nsIFile**);
69 static PRUint32 (CDECL *NS_StringGetData)(const nsAString*,const PRUnichar **,cpp_bool*);
70 static PRUint32 (CDECL *NS_CStringGetData)(const nsACString*,const char**,cpp_bool*);
72 static HINSTANCE xul_handle = NULL;
74 static nsIServiceManager *pServMgr = NULL;
75 static nsIComponentManager *pCompMgr = NULL;
76 static nsIMemory *nsmem = NULL;
77 static nsIFile *profile_directory, *plugin_directory;
79 static const WCHAR wszNsContainer[] = {'N','s','C','o','n','t','a','i','n','e','r',0};
81 static ATOM nscontainer_class;
82 static WCHAR gecko_path[MAX_PATH];
83 static unsigned gecko_path_len;
85 nsresult create_nsfile(const PRUnichar *path, nsIFile **ret)
87 nsAString str;
88 nsresult nsres;
90 nsAString_InitDepend(&str, path);
91 nsres = NS_NewLocalFile(&str, FALSE, ret);
92 nsAString_Finish(&str);
94 if(NS_FAILED(nsres))
95 WARN("NS_NewLocalFile failed: %08x\n", nsres);
96 return nsres;
99 typedef struct {
100 nsISimpleEnumerator nsISimpleEnumerator_iface;
101 LONG ref;
102 nsISupports *value;
103 } nsSingletonEnumerator;
105 static inline nsSingletonEnumerator *impl_from_nsISimpleEnumerator(nsISimpleEnumerator *iface)
107 return CONTAINING_RECORD(iface, nsSingletonEnumerator, nsISimpleEnumerator_iface);
110 static nsresult NSAPI nsSingletonEnumerator_QueryInterface(nsISimpleEnumerator *iface, nsIIDRef riid, void **ppv)
112 nsSingletonEnumerator *This = impl_from_nsISimpleEnumerator(iface);
114 if(IsEqualGUID(&IID_nsISupports, riid)) {
115 TRACE("(%p)->(IID_nsISupports %p)\n", This, ppv);
116 *ppv = &This->nsISimpleEnumerator_iface;
117 }else if(IsEqualGUID(&IID_nsISimpleEnumerator, riid)) {
118 TRACE("(%p)->(IID_nsISimpleEnumerator %p)\n", This, ppv);
119 *ppv = &This->nsISimpleEnumerator_iface;
120 }else {
121 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
122 *ppv = NULL;
123 return NS_NOINTERFACE;
126 nsISupports_AddRef((nsISupports*)*ppv);
127 return NS_OK;
130 static nsrefcnt NSAPI nsSingletonEnumerator_AddRef(nsISimpleEnumerator *iface)
132 nsSingletonEnumerator *This = impl_from_nsISimpleEnumerator(iface);
133 nsrefcnt ref = InterlockedIncrement(&This->ref);
135 TRACE("(%p) ref=%d\n", This, ref);
137 return ref;
140 static nsrefcnt NSAPI nsSingletonEnumerator_Release(nsISimpleEnumerator *iface)
142 nsSingletonEnumerator *This = impl_from_nsISimpleEnumerator(iface);
143 nsrefcnt ref = InterlockedDecrement(&This->ref);
145 TRACE("(%p) ref=%d\n", This, ref);
147 if(!ref) {
148 if(This->value)
149 nsISupports_Release(This->value);
150 heap_free(This);
153 return ref;
156 static nsresult NSAPI nsSingletonEnumerator_HasMoreElements(nsISimpleEnumerator *iface, cpp_bool *_retval)
158 nsSingletonEnumerator *This = impl_from_nsISimpleEnumerator(iface);
160 TRACE("(%p)->()\n", This);
162 *_retval = This->value != NULL;
163 return NS_OK;
166 static nsresult NSAPI nsSingletonEnumerator_GetNext(nsISimpleEnumerator *iface, nsISupports **_retval)
168 nsSingletonEnumerator *This = impl_from_nsISimpleEnumerator(iface);
170 TRACE("(%p)->()\n", This);
172 if(!This->value)
173 return NS_ERROR_UNEXPECTED;
175 *_retval = This->value;
176 This->value = NULL;
177 return NS_OK;
180 static const nsISimpleEnumeratorVtbl nsSingletonEnumeratorVtbl = {
181 nsSingletonEnumerator_QueryInterface,
182 nsSingletonEnumerator_AddRef,
183 nsSingletonEnumerator_Release,
184 nsSingletonEnumerator_HasMoreElements,
185 nsSingletonEnumerator_GetNext
188 static nsISimpleEnumerator *create_singleton_enumerator(nsISupports *value)
190 nsSingletonEnumerator *ret;
192 ret = heap_alloc(sizeof(*ret));
193 if(!ret)
194 return NULL;
196 ret->nsISimpleEnumerator_iface.lpVtbl = &nsSingletonEnumeratorVtbl;
197 ret->ref = 1;
199 if(value)
200 nsISupports_AddRef(value);
201 ret->value = value;
202 return &ret->nsISimpleEnumerator_iface;
205 static nsresult NSAPI nsDirectoryServiceProvider2_QueryInterface(nsIDirectoryServiceProvider2 *iface,
206 nsIIDRef riid, void **result)
208 if(IsEqualGUID(&IID_nsISupports, riid)) {
209 TRACE("(IID_nsISupports %p)\n", result);
210 *result = iface;
211 }else if(IsEqualGUID(&IID_nsIDirectoryServiceProvider, riid)) {
212 TRACE("(IID_nsIDirectoryServiceProvider %p)\n", result);
213 *result = iface;
214 }else if(IsEqualGUID(&IID_nsIDirectoryServiceProvider2, riid)) {
215 TRACE("(IID_nsIDirectoryServiceProvider2 %p)\n", result);
216 *result = iface;
217 }else {
218 WARN("(%s %p)\n", debugstr_guid(riid), result);
219 *result = NULL;
220 return NS_NOINTERFACE;
223 nsISupports_AddRef((nsISupports*)*result);
224 return NS_OK;
227 static nsrefcnt NSAPI nsDirectoryServiceProvider2_AddRef(nsIDirectoryServiceProvider2 *iface)
229 return 2;
232 static nsrefcnt NSAPI nsDirectoryServiceProvider2_Release(nsIDirectoryServiceProvider2 *iface)
234 return 1;
237 static nsresult create_profile_directory(void)
239 static const WCHAR wine_geckoW[] = {'\\','w','i','n','e','_','g','e','c','k','o',0};
241 WCHAR path[MAX_PATH + sizeof(wine_geckoW)/sizeof(WCHAR)];
242 cpp_bool exists;
243 nsresult nsres;
244 HRESULT hres;
246 hres = SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, path);
247 if(FAILED(hres)) {
248 ERR("SHGetFolderPath failed: %08x\n", hres);
249 return NS_ERROR_FAILURE;
252 strcatW(path, wine_geckoW);
253 nsres = create_nsfile(path, &profile_directory);
254 if(NS_FAILED(nsres))
255 return nsres;
257 nsres = nsIFile_Exists(profile_directory, &exists);
258 if(NS_FAILED(nsres)) {
259 ERR("Exists failed: %08x\n", nsres);
260 return nsres;
263 if(!exists) {
264 nsres = nsIFile_Create(profile_directory, 1, 0700);
265 if(NS_FAILED(nsres))
266 ERR("Create failed: %08x\n", nsres);
269 return nsres;
272 static nsresult NSAPI nsDirectoryServiceProvider2_GetFile(nsIDirectoryServiceProvider2 *iface,
273 const char *prop, cpp_bool *persistent, nsIFile **_retval)
275 TRACE("(%s %p %p)\n", debugstr_a(prop), persistent, _retval);
277 if(!strcmp(prop, "ProfD")) {
278 if(!profile_directory) {
279 nsresult nsres;
281 nsres = create_profile_directory();
282 if(NS_FAILED(nsres))
283 return nsres;
286 assert(profile_directory != NULL);
287 return nsIFile_Clone(profile_directory, _retval);
290 *_retval = NULL;
291 return NS_ERROR_FAILURE;
294 static nsresult NSAPI nsDirectoryServiceProvider2_GetFiles(nsIDirectoryServiceProvider2 *iface,
295 const char *prop, nsISimpleEnumerator **_retval)
297 TRACE("(%s %p)\n", debugstr_a(prop), _retval);
299 if(!strcmp(prop, "APluginsDL")) {
300 WCHAR plugin_path[MAX_PATH];
301 nsIFile *file;
302 int len;
303 nsresult nsres;
305 if(!plugin_directory) {
306 static const WCHAR gecko_pluginW[] = {'\\','g','e','c','k','o','\\','p','l','u','g','i','n',0};
308 len = GetSystemDirectoryW(plugin_path, (sizeof(plugin_path)-sizeof(gecko_pluginW))/sizeof(WCHAR)+1);
309 if(!len)
310 return NS_ERROR_UNEXPECTED;
312 strcpyW(plugin_path+len, gecko_pluginW);
313 nsres = create_nsfile(plugin_path, &plugin_directory);
314 if(NS_FAILED(nsres)) {
315 *_retval = NULL;
316 return nsres;
320 nsres = nsIFile_Clone(plugin_directory, &file);
321 if(NS_FAILED(nsres))
322 return nsres;
324 *_retval = create_singleton_enumerator((nsISupports*)file);
325 nsIFile_Release(file);
326 if(!*_retval)
327 return NS_ERROR_OUT_OF_MEMORY;
329 return NS_OK;
332 *_retval = NULL;
333 return NS_ERROR_FAILURE;
336 static const nsIDirectoryServiceProvider2Vtbl nsDirectoryServiceProvider2Vtbl = {
337 nsDirectoryServiceProvider2_QueryInterface,
338 nsDirectoryServiceProvider2_AddRef,
339 nsDirectoryServiceProvider2_Release,
340 nsDirectoryServiceProvider2_GetFile,
341 nsDirectoryServiceProvider2_GetFiles
344 static nsIDirectoryServiceProvider2 nsDirectoryServiceProvider2 =
345 { &nsDirectoryServiceProvider2Vtbl };
347 static LRESULT WINAPI nsembed_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
349 NSContainer *This;
350 nsresult nsres;
352 static const WCHAR wszTHIS[] = {'T','H','I','S',0};
354 if(msg == WM_CREATE) {
355 This = *(NSContainer**)lParam;
356 SetPropW(hwnd, wszTHIS, This);
357 }else {
358 This = GetPropW(hwnd, wszTHIS);
361 switch(msg) {
362 case WM_SIZE:
363 TRACE("(%p)->(WM_SIZE)\n", This);
365 nsres = nsIBaseWindow_SetSize(This->window,
366 LOWORD(lParam), HIWORD(lParam), TRUE);
367 if(NS_FAILED(nsres))
368 WARN("SetSize failed: %08x\n", nsres);
369 break;
371 case WM_PARENTNOTIFY:
372 TRACE("WM_PARENTNOTIFY %x\n", (unsigned)wParam);
374 switch(wParam) {
375 case WM_LBUTTONDOWN:
376 case WM_RBUTTONDOWN:
377 nsIWebBrowserFocus_Activate(This->focus);
381 return DefWindowProcW(hwnd, msg, wParam, lParam);
385 static void register_nscontainer_class(void)
387 static WNDCLASSEXW wndclass = {
388 sizeof(WNDCLASSEXW),
389 CS_DBLCLKS,
390 nsembed_proc,
391 0, 0, NULL, NULL, NULL, NULL, NULL,
392 wszNsContainer,
393 NULL,
395 wndclass.hInstance = hInst;
396 nscontainer_class = RegisterClassExW(&wndclass);
399 static BOOL install_wine_gecko(void)
401 PROCESS_INFORMATION pi;
402 STARTUPINFOW si;
403 WCHAR app[MAX_PATH];
404 WCHAR *args;
405 LONG len;
406 BOOL ret;
408 static const WCHAR controlW[] = {'\\','c','o','n','t','r','o','l','.','e','x','e',0};
409 static const WCHAR argsW[] =
410 {' ','a','p','p','w','i','z','.','c','p','l',' ','i','n','s','t','a','l','l','_','g','e','c','k','o',0};
412 len = GetSystemDirectoryW(app, MAX_PATH-sizeof(controlW)/sizeof(WCHAR));
413 memcpy(app+len, controlW, sizeof(controlW));
415 args = heap_alloc(len*sizeof(WCHAR) + sizeof(controlW) + sizeof(argsW));
416 if(!args)
417 return FALSE;
419 memcpy(args, app, len*sizeof(WCHAR) + sizeof(controlW));
420 memcpy(args + len + sizeof(controlW)/sizeof(WCHAR)-1, argsW, sizeof(argsW));
422 TRACE("starting %s\n", debugstr_w(args));
424 memset(&si, 0, sizeof(si));
425 si.cb = sizeof(si);
426 ret = CreateProcessW(app, args, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
427 heap_free(args);
428 if (ret) {
429 CloseHandle(pi.hThread);
430 WaitForSingleObject(pi.hProcess, INFINITE);
431 CloseHandle(pi.hProcess);
434 return ret;
437 static void set_environment(LPCWSTR gre_path)
439 WCHAR path_env[MAX_PATH], buf[20];
440 int len, debug_level = 0;
442 static const WCHAR pathW[] = {'P','A','T','H',0};
443 static const WCHAR warnW[] = {'w','a','r','n',0};
444 static const WCHAR xpcom_debug_breakW[] =
445 {'X','P','C','O','M','_','D','E','B','U','G','_','B','R','E','A','K',0};
446 static const WCHAR nspr_log_modulesW[] =
447 {'N','S','P','R','_','L','O','G','_','M','O','D','U','L','E','S',0};
448 static const WCHAR debug_formatW[] = {'a','l','l',':','%','d',0};
450 /* We have to modify PATH as XPCOM loads other DLLs from this directory. */
451 GetEnvironmentVariableW(pathW, path_env, sizeof(path_env)/sizeof(WCHAR));
452 len = strlenW(path_env);
453 path_env[len++] = ';';
454 strcpyW(path_env+len, gre_path);
455 SetEnvironmentVariableW(pathW, path_env);
457 SetEnvironmentVariableW(xpcom_debug_breakW, warnW);
459 if(TRACE_ON(gecko))
460 debug_level = 5;
461 else if(WARN_ON(gecko))
462 debug_level = 3;
463 else if(ERR_ON(gecko))
464 debug_level = 2;
466 sprintfW(buf, debug_formatW, debug_level);
467 SetEnvironmentVariableW(nspr_log_modulesW, buf);
470 static BOOL load_xul(const PRUnichar *gre_path)
472 static const WCHAR xul_dllW[] = {'\\','x','u','l','.','d','l','l',0};
473 WCHAR file_name[MAX_PATH];
475 strcpyW(file_name, gre_path);
476 strcatW(file_name, xul_dllW);
478 TRACE("(%s)\n", debugstr_w(file_name));
480 set_environment(gre_path);
482 xul_handle = LoadLibraryExW(file_name, 0, LOAD_WITH_ALTERED_SEARCH_PATH);
483 if(!xul_handle) {
484 WARN("Could not load XUL: %d\n", GetLastError());
485 return FALSE;
488 #define NS_DLSYM(func) \
489 func = (void *)GetProcAddress(xul_handle, #func "_P"); \
490 if(!func) \
491 ERR("Could not GetProcAddress(" #func ") failed\n")
493 NS_DLSYM(NS_InitXPCOM2);
494 NS_DLSYM(NS_ShutdownXPCOM);
495 NS_DLSYM(NS_GetComponentRegistrar);
496 NS_DLSYM(NS_StringContainerInit2);
497 NS_DLSYM(NS_CStringContainerInit2);
498 NS_DLSYM(NS_StringContainerFinish);
499 NS_DLSYM(NS_CStringContainerFinish);
500 NS_DLSYM(NS_StringSetData);
501 NS_DLSYM(NS_CStringSetData);
502 NS_DLSYM(NS_NewLocalFile);
503 NS_DLSYM(NS_StringGetData);
504 NS_DLSYM(NS_CStringGetData);
506 #undef NS_DLSYM
508 #define NS_DLSYM(func) \
509 func = (void *)GetProcAddress(xul_handle, #func); \
510 if(!func) \
511 ERR("Could not GetProcAddress(" #func ") failed\n")
513 NS_DLSYM(ccref_incr);
514 NS_DLSYM(ccref_decr);
515 NS_DLSYM(ccref_init);
516 NS_DLSYM(ccref_unmark_if_purple);
517 NS_DLSYM(ccp_init);
518 NS_DLSYM(describe_cc_node);
519 NS_DLSYM(note_cc_edge);
521 #undef NS_DLSYM
523 return TRUE;
526 static BOOL check_version(LPCWSTR gre_path, const char *version_string)
528 WCHAR file_name[MAX_PATH];
529 char version[128];
530 DWORD read=0;
531 HANDLE hfile;
533 static const WCHAR wszVersion[] = {'\\','V','E','R','S','I','O','N',0};
535 strcpyW(file_name, gre_path);
536 strcatW(file_name, wszVersion);
538 hfile = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ, NULL,
539 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
540 if(hfile == INVALID_HANDLE_VALUE) {
541 ERR("Could not open VERSION file\n");
542 return FALSE;
545 ReadFile(hfile, version, sizeof(version), &read, NULL);
546 version[read] = 0;
547 CloseHandle(hfile);
549 TRACE("%s\n", debugstr_a(version));
551 if(strcmp(version, version_string)) {
552 ERR("Unexpected version %s, expected %s\n", debugstr_a(version),
553 debugstr_a(version_string));
554 return FALSE;
557 return TRUE;
560 static BOOL load_wine_gecko_v(PRUnichar *gre_path, HKEY mshtml_key,
561 const char *version, const char *version_string)
563 DWORD res, type, size = MAX_PATH;
564 HKEY hkey = mshtml_key;
566 static const WCHAR wszGeckoPath[] =
567 {'G','e','c','k','o','P','a','t','h',0};
569 if(version) {
570 /* @@ Wine registry key: HKLM\Software\Wine\MSHTML\<version> */
571 res = RegOpenKeyA(mshtml_key, version, &hkey);
572 if(res != ERROR_SUCCESS)
573 return FALSE;
576 res = RegQueryValueExW(hkey, wszGeckoPath, NULL, &type, (LPBYTE)gre_path, &size);
577 if(hkey != mshtml_key)
578 RegCloseKey(hkey);
579 if(res != ERROR_SUCCESS || type != REG_SZ)
580 return FALSE;
582 if(!check_version(gre_path, version_string))
583 return FALSE;
585 return load_xul(gre_path);
588 static BOOL load_wine_gecko(PRUnichar *gre_path)
590 HKEY hkey;
591 DWORD res;
592 BOOL ret;
594 static const WCHAR wszMshtmlKey[] = {
595 'S','o','f','t','w','a','r','e','\\','W','i','n','e',
596 '\\','M','S','H','T','M','L',0};
598 /* @@ Wine registry key: HKLM\Software\Wine\MSHTML */
599 res = RegOpenKeyW(HKEY_LOCAL_MACHINE, wszMshtmlKey, &hkey);
600 if(res != ERROR_SUCCESS)
601 return FALSE;
603 ret = load_wine_gecko_v(gre_path, hkey, GECKO_VERSION, GECKO_VERSION_STRING);
605 RegCloseKey(hkey);
606 return ret;
609 static void set_bool_pref(nsIPrefBranch *pref, const char *pref_name, BOOL val)
611 nsresult nsres;
613 nsres = nsIPrefBranch_SetBoolPref(pref, pref_name, val);
614 if(NS_FAILED(nsres))
615 ERR("Could not set pref %s\n", debugstr_a(pref_name));
618 static void set_int_pref(nsIPrefBranch *pref, const char *pref_name, int val)
620 nsresult nsres;
622 nsres = nsIPrefBranch_SetIntPref(pref, pref_name, val);
623 if(NS_FAILED(nsres))
624 ERR("Could not set pref %s\n", debugstr_a(pref_name));
627 static void set_string_pref(nsIPrefBranch *pref, const char *pref_name, const char *val)
629 nsresult nsres;
631 nsres = nsIPrefBranch_SetCharPref(pref, pref_name, val);
632 if(NS_FAILED(nsres))
633 ERR("Could not set pref %s\n", debugstr_a(pref_name));
636 static void set_lang(nsIPrefBranch *pref)
638 char langs[100];
639 DWORD res, size, type;
640 HKEY hkey;
642 static const WCHAR international_keyW[] =
643 {'S','o','f','t','w','a','r','e',
644 '\\','M','i','c','r','o','s','o','f','t',
645 '\\','I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r',
646 '\\','I','n','t','e','r','n','a','t','i','o','n','a','l',0};
648 res = RegOpenKeyW(HKEY_CURRENT_USER, international_keyW, &hkey);
649 if(res != ERROR_SUCCESS)
650 return;
652 size = sizeof(langs);
653 res = RegQueryValueExA(hkey, "AcceptLanguage", 0, &type, (LPBYTE)langs, &size);
654 RegCloseKey(hkey);
655 if(res != ERROR_SUCCESS || type != REG_SZ)
656 return;
658 TRACE("Setting lang %s\n", debugstr_a(langs));
660 set_string_pref(pref, "intl.accept_languages", langs);
663 static void set_preferences(void)
665 nsIPrefBranch *pref;
666 nsresult nsres;
668 nsres = nsIServiceManager_GetServiceByContractID(pServMgr, NS_PREFERENCES_CONTRACTID,
669 &IID_nsIPrefBranch, (void**)&pref);
670 if(NS_FAILED(nsres)) {
671 ERR("Could not get preference service: %08x\n", nsres);
672 return;
675 set_lang(pref);
676 set_bool_pref(pref, "security.warn_entering_secure", FALSE);
677 set_bool_pref(pref, "security.warn_submit_insecure", FALSE);
678 set_int_pref(pref, "layout.spellcheckDefault", 0);
680 nsIPrefBranch_Release(pref);
683 static BOOL init_xpcom(const PRUnichar *gre_path)
685 nsIComponentRegistrar *registrar = NULL;
686 nsIFile *gre_dir;
687 WCHAR *ptr;
688 nsresult nsres;
690 nsres = create_nsfile(gre_path, &gre_dir);
691 if(NS_FAILED(nsres)) {
692 FreeLibrary(xul_handle);
693 return FALSE;
696 nsres = NS_InitXPCOM2(&pServMgr, gre_dir, (nsIDirectoryServiceProvider*)&nsDirectoryServiceProvider2);
697 if(NS_FAILED(nsres)) {
698 ERR("NS_InitXPCOM2 failed: %08x\n", nsres);
699 FreeLibrary(xul_handle);
700 return FALSE;
703 strcpyW(gecko_path, gre_path);
704 for(ptr = gecko_path; *ptr; ptr++) {
705 if(*ptr == '\\')
706 *ptr = '/';
708 gecko_path_len = ptr-gecko_path;
710 nsres = nsIServiceManager_QueryInterface(pServMgr, &IID_nsIComponentManager, (void**)&pCompMgr);
711 if(NS_FAILED(nsres))
712 ERR("Could not get nsIComponentManager: %08x\n", nsres);
714 nsres = NS_GetComponentRegistrar(&registrar);
715 if(NS_SUCCEEDED(nsres))
716 init_nsio(pCompMgr, registrar);
717 else
718 ERR("NS_GetComponentRegistrar failed: %08x\n", nsres);
720 init_mutation(pCompMgr);
721 set_preferences();
723 nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr, NS_MEMORY_CONTRACTID,
724 NULL, &IID_nsIMemory, (void**)&nsmem);
725 if(NS_FAILED(nsres))
726 ERR("Could not get nsIMemory: %08x\n", nsres);
728 if(registrar) {
729 register_nsservice(registrar, pServMgr);
730 nsIComponentRegistrar_Release(registrar);
733 init_node_cc();
735 return TRUE;
738 static CRITICAL_SECTION cs_load_gecko;
739 static CRITICAL_SECTION_DEBUG cs_load_gecko_dbg =
741 0, 0, &cs_load_gecko,
742 { &cs_load_gecko_dbg.ProcessLocksList, &cs_load_gecko_dbg.ProcessLocksList },
743 0, 0, { (DWORD_PTR)(__FILE__ ": load_gecko") }
745 static CRITICAL_SECTION cs_load_gecko = { &cs_load_gecko_dbg, -1, 0, 0, 0, 0 };
747 BOOL load_gecko(void)
749 PRUnichar gre_path[MAX_PATH];
750 BOOL ret = FALSE;
752 static DWORD loading_thread;
754 TRACE("()\n");
756 /* load_gecko may be called recursively */
757 if(loading_thread == GetCurrentThreadId())
758 return pCompMgr != NULL;
760 EnterCriticalSection(&cs_load_gecko);
762 if(!loading_thread) {
763 loading_thread = GetCurrentThreadId();
765 if(load_wine_gecko(gre_path)
766 || (install_wine_gecko() && load_wine_gecko(gre_path)))
767 ret = init_xpcom(gre_path);
768 else
769 MESSAGE("Could not load wine-gecko. HTML rendering will be disabled.\n");
770 }else {
771 ret = pCompMgr != NULL;
774 LeaveCriticalSection(&cs_load_gecko);
776 return ret;
779 void *nsalloc(size_t size)
781 return nsIMemory_Alloc(nsmem, size);
784 void nsfree(void *mem)
786 nsIMemory_Free(nsmem, mem);
789 static BOOL nsACString_Init(nsACString *str, const char *data)
791 return NS_SUCCEEDED(NS_CStringContainerInit2(str, data, PR_UINT32_MAX, 0));
795 * Initializes nsACString with data owned by caller.
796 * Caller must ensure that data is valid during lifetime of string object.
798 void nsACString_InitDepend(nsACString *str, const char *data)
800 NS_CStringContainerInit2(str, data, PR_UINT32_MAX, NS_CSTRING_CONTAINER_INIT_DEPEND);
803 void nsACString_SetData(nsACString *str, const char *data)
805 NS_CStringSetData(str, data, PR_UINT32_MAX);
808 UINT32 nsACString_GetData(const nsACString *str, const char **data)
810 return NS_CStringGetData(str, data, NULL);
813 void nsACString_Finish(nsACString *str)
815 NS_CStringContainerFinish(str);
818 BOOL nsAString_Init(nsAString *str, const PRUnichar *data)
820 return NS_SUCCEEDED(NS_StringContainerInit2(str, data, PR_UINT32_MAX, 0));
824 * Initializes nsAString with data owned by caller.
825 * Caller must ensure that data is valid during lifetime of string object.
827 void nsAString_InitDepend(nsAString *str, const PRUnichar *data)
829 NS_StringContainerInit2(str, data, PR_UINT32_MAX, NS_STRING_CONTAINER_INIT_DEPEND);
832 void nsAString_SetData(nsAString *str, const PRUnichar *data)
834 NS_StringSetData(str, data, PR_UINT32_MAX);
837 UINT32 nsAString_GetData(const nsAString *str, const PRUnichar **data)
839 return NS_StringGetData(str, data, NULL);
842 void nsAString_Finish(nsAString *str)
844 NS_StringContainerFinish(str);
847 HRESULT return_nsstr(nsresult nsres, nsAString *nsstr, BSTR *p)
849 const PRUnichar *str;
851 if(NS_FAILED(nsres)) {
852 ERR("failed: %08x\n", nsres);
853 nsAString_Finish(nsstr);
854 return E_FAIL;
857 nsAString_GetData(nsstr, &str);
858 TRACE("ret %s\n", debugstr_w(str));
859 if(*str) {
860 *p = SysAllocString(str);
861 if(!*p)
862 return E_OUTOFMEMORY;
863 }else {
864 *p = NULL;
867 nsAString_Finish(nsstr);
868 return S_OK;
871 nsICommandParams *create_nscommand_params(void)
873 nsICommandParams *ret = NULL;
874 nsresult nsres;
876 if(!pCompMgr)
877 return NULL;
879 nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr,
880 NS_COMMANDPARAMS_CONTRACTID, NULL, &IID_nsICommandParams,
881 (void**)&ret);
882 if(NS_FAILED(nsres))
883 ERR("Could not get nsICommandParams\n");
885 return ret;
888 nsIWritableVariant *create_nsvariant(void)
890 nsIWritableVariant *ret = NULL;
891 nsresult nsres;
893 if(!pCompMgr)
894 return NULL;
896 nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr,
897 NS_VARIANT_CONTRACTID, NULL, &IID_nsIWritableVariant, (void**)&ret);
898 if(NS_FAILED(nsres))
899 ERR("Could not get nsIVariant\n");
901 return ret;
904 nsresult get_nsinterface(nsISupports *iface, REFIID riid, void **ppv)
906 nsIInterfaceRequestor *iface_req;
907 nsresult nsres;
909 nsres = nsISupports_QueryInterface(iface, &IID_nsIInterfaceRequestor, (void**)&iface_req);
910 if(NS_FAILED(nsres))
911 return nsres;
913 nsres = nsIInterfaceRequestor_GetInterface(iface_req, riid, ppv);
914 nsIInterfaceRequestor_Release(iface_req);
916 return nsres;
919 static HRESULT nsnode_to_nsstring_rec(nsIContentSerializer *serializer, nsIDOMNode *nsnode, nsAString *str)
921 nsIDOMNodeList *node_list = NULL;
922 cpp_bool has_children = FALSE;
923 nsIContent *nscontent;
924 UINT16 type;
925 nsresult nsres;
927 nsIDOMNode_HasChildNodes(nsnode, &has_children);
929 nsres = nsIDOMNode_GetNodeType(nsnode, &type);
930 if(NS_FAILED(nsres)) {
931 ERR("GetType failed: %08x\n", nsres);
932 return E_FAIL;
935 if(type != DOCUMENT_NODE) {
936 nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIContent, (void**)&nscontent);
937 if(NS_FAILED(nsres)) {
938 ERR("Could not get nsIContent interface: %08x\n", nsres);
939 return E_FAIL;
943 switch(type) {
944 case ELEMENT_NODE:
945 nsIContentSerializer_AppendElementStart(serializer, nscontent, nscontent, str);
946 break;
947 case TEXT_NODE:
948 nsIContentSerializer_AppendText(serializer, nscontent, 0, -1, str);
949 break;
950 case COMMENT_NODE:
951 nsres = nsIContentSerializer_AppendComment(serializer, nscontent, 0, -1, str);
952 break;
953 case DOCUMENT_NODE: {
954 nsIDocument *nsdoc;
955 nsIDOMNode_QueryInterface(nsnode, &IID_nsIDocument, (void**)&nsdoc);
956 nsIContentSerializer_AppendDocumentStart(serializer, nsdoc, str);
957 nsIDocument_Release(nsdoc);
958 break;
960 case DOCUMENT_TYPE_NODE:
961 nsIContentSerializer_AppendDoctype(serializer, nscontent, str);
962 break;
963 case DOCUMENT_FRAGMENT_NODE:
964 break;
965 default:
966 FIXME("Unhandled type %u\n", type);
969 if(has_children) {
970 UINT32 child_cnt, i;
971 nsIDOMNode *child_node;
973 nsIDOMNode_GetChildNodes(nsnode, &node_list);
974 nsIDOMNodeList_GetLength(node_list, &child_cnt);
976 for(i=0; i<child_cnt; i++) {
977 nsres = nsIDOMNodeList_Item(node_list, i, &child_node);
978 if(NS_SUCCEEDED(nsres)) {
979 nsnode_to_nsstring_rec(serializer, child_node, str);
980 nsIDOMNode_Release(child_node);
981 }else {
982 ERR("Item failed: %08x\n", nsres);
986 nsIDOMNodeList_Release(node_list);
989 if(type == ELEMENT_NODE)
990 nsIContentSerializer_AppendElementEnd(serializer, nscontent, str);
992 if(type != DOCUMENT_NODE)
993 nsIContent_Release(nscontent);
994 return S_OK;
997 HRESULT nsnode_to_nsstring(nsIDOMNode *nsnode, nsAString *str)
999 nsIContentSerializer *serializer;
1000 nsresult nsres;
1001 HRESULT hres;
1003 nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr,
1004 NS_HTMLSERIALIZER_CONTRACTID, NULL, &IID_nsIContentSerializer,
1005 (void**)&serializer);
1006 if(NS_FAILED(nsres)) {
1007 ERR("Could not get nsIContentSerializer: %08x\n", nsres);
1008 return E_FAIL;
1011 nsres = nsIContentSerializer_Init(serializer, 0, 100, NULL, FALSE, FALSE /* FIXME */);
1012 if(NS_FAILED(nsres))
1013 ERR("Init failed: %08x\n", nsres);
1015 hres = nsnode_to_nsstring_rec(serializer, nsnode, str);
1016 if(SUCCEEDED(hres)) {
1017 nsres = nsIContentSerializer_Flush(serializer, str);
1018 if(NS_FAILED(nsres))
1019 ERR("Flush failed: %08x\n", nsres);
1022 nsIContentSerializer_Release(serializer);
1023 return hres;
1026 void get_editor_controller(NSContainer *This)
1028 nsIEditingSession *editing_session = NULL;
1029 nsIControllerContext *ctrlctx;
1030 nsresult nsres;
1032 if(This->editor) {
1033 nsIEditor_Release(This->editor);
1034 This->editor = NULL;
1037 if(This->editor_controller) {
1038 nsIController_Release(This->editor_controller);
1039 This->editor_controller = NULL;
1042 nsres = get_nsinterface((nsISupports*)This->webbrowser, &IID_nsIEditingSession,
1043 (void**)&editing_session);
1044 if(NS_FAILED(nsres)) {
1045 ERR("Could not get nsIEditingSession: %08x\n", nsres);
1046 return;
1049 nsres = nsIEditingSession_GetEditorForWindow(editing_session,
1050 This->doc->basedoc.window->nswindow, &This->editor);
1051 nsIEditingSession_Release(editing_session);
1052 if(NS_FAILED(nsres)) {
1053 ERR("Could not get editor: %08x\n", nsres);
1054 return;
1057 nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr,
1058 NS_EDITORCONTROLLER_CONTRACTID, NULL, &IID_nsIControllerContext, (void**)&ctrlctx);
1059 if(NS_SUCCEEDED(nsres)) {
1060 nsres = nsIControllerContext_SetCommandContext(ctrlctx, (nsISupports *)This->editor);
1061 if(NS_FAILED(nsres))
1062 ERR("SetCommandContext failed: %08x\n", nsres);
1063 nsres = nsIControllerContext_QueryInterface(ctrlctx, &IID_nsIController,
1064 (void**)&This->editor_controller);
1065 nsIControllerContext_Release(ctrlctx);
1066 if(NS_FAILED(nsres))
1067 ERR("Could not get nsIController interface: %08x\n", nsres);
1068 }else {
1069 ERR("Could not create edit controller: %08x\n", nsres);
1073 void close_gecko(void)
1075 TRACE("()\n");
1077 release_nsio();
1078 init_mutation(NULL);
1080 if(profile_directory) {
1081 nsIFile_Release(profile_directory);
1082 profile_directory = NULL;
1085 if(plugin_directory) {
1086 nsIFile_Release(plugin_directory);
1087 plugin_directory = NULL;
1090 if(pCompMgr)
1091 nsIComponentManager_Release(pCompMgr);
1093 if(pServMgr)
1094 nsIServiceManager_Release(pServMgr);
1096 if(nsmem)
1097 nsIMemory_Release(nsmem);
1099 /* Gecko doesn't really support being unloaded */
1100 /* if (hXPCOM) FreeLibrary(hXPCOM); */
1102 DeleteCriticalSection(&cs_load_gecko);
1105 BOOL is_gecko_path(const char *path)
1107 WCHAR *buf, *ptr;
1108 BOOL ret;
1110 buf = heap_strdupUtoW(path);
1111 if(!buf || strlenW(buf) < gecko_path_len)
1112 return FALSE;
1114 for(ptr = buf; *ptr; ptr++) {
1115 if(*ptr == '\\')
1116 *ptr = '/';
1119 UrlUnescapeW(buf, NULL, NULL, URL_UNESCAPE_INPLACE);
1120 buf[gecko_path_len] = 0;
1122 ret = !strcmpiW(buf, gecko_path);
1123 heap_free(buf);
1124 return ret;
1127 struct nsWeakReference {
1128 nsIWeakReference nsIWeakReference_iface;
1130 LONG ref;
1132 NSContainer *nscontainer;
1135 static inline nsWeakReference *impl_from_nsIWeakReference(nsIWeakReference *iface)
1137 return CONTAINING_RECORD(iface, nsWeakReference, nsIWeakReference_iface);
1140 static nsresult NSAPI nsWeakReference_QueryInterface(nsIWeakReference *iface,
1141 nsIIDRef riid, void **result)
1143 nsWeakReference *This = impl_from_nsIWeakReference(iface);
1145 if(IsEqualGUID(&IID_nsISupports, riid)) {
1146 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
1147 *result = &This->nsIWeakReference_iface;
1148 }else if(IsEqualGUID(&IID_nsIWeakReference, riid)) {
1149 TRACE("(%p)->(IID_nsIWeakReference %p)\n", This, result);
1150 *result = &This->nsIWeakReference_iface;
1151 }else {
1152 WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
1153 *result = NULL;
1154 return NS_NOINTERFACE;
1157 nsISupports_AddRef((nsISupports*)*result);
1158 return NS_OK;
1161 static nsrefcnt NSAPI nsWeakReference_AddRef(nsIWeakReference *iface)
1163 nsWeakReference *This = impl_from_nsIWeakReference(iface);
1164 LONG ref = InterlockedIncrement(&This->ref);
1166 TRACE("(%p) ref=%d\n", This, ref);
1168 return ref;
1171 static nsrefcnt NSAPI nsWeakReference_Release(nsIWeakReference *iface)
1173 nsWeakReference *This = impl_from_nsIWeakReference(iface);
1174 LONG ref = InterlockedIncrement(&This->ref);
1176 TRACE("(%p) ref=%d\n", This, ref);
1178 if(!ref) {
1179 assert(!This->nscontainer);
1180 heap_free(This);
1183 return ref;
1186 static nsresult NSAPI nsWeakReference_QueryReferent(nsIWeakReference *iface,
1187 const nsIID *riid, void **result)
1189 nsWeakReference *This = impl_from_nsIWeakReference(iface);
1191 if(!This->nscontainer)
1192 return NS_ERROR_NULL_POINTER;
1194 return nsIWebBrowserChrome_QueryInterface(&This->nscontainer->nsIWebBrowserChrome_iface, riid, result);
1197 static const nsIWeakReferenceVtbl nsWeakReferenceVtbl = {
1198 nsWeakReference_QueryInterface,
1199 nsWeakReference_AddRef,
1200 nsWeakReference_Release,
1201 nsWeakReference_QueryReferent
1204 /**********************************************************
1205 * nsIWebBrowserChrome interface
1208 static inline NSContainer *impl_from_nsIWebBrowserChrome(nsIWebBrowserChrome *iface)
1210 return CONTAINING_RECORD(iface, NSContainer, nsIWebBrowserChrome_iface);
1213 static nsresult NSAPI nsWebBrowserChrome_QueryInterface(nsIWebBrowserChrome *iface,
1214 nsIIDRef riid, void **result)
1216 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1218 *result = NULL;
1219 if(IsEqualGUID(&IID_nsISupports, riid)) {
1220 TRACE("(%p)->(IID_nsISupports, %p)\n", This, result);
1221 *result = &This->nsIWebBrowserChrome_iface;
1222 }else if(IsEqualGUID(&IID_nsIWebBrowserChrome, riid)) {
1223 TRACE("(%p)->(IID_nsIWebBrowserChrome, %p)\n", This, result);
1224 *result = &This->nsIWebBrowserChrome_iface;
1225 }else if(IsEqualGUID(&IID_nsIContextMenuListener, riid)) {
1226 TRACE("(%p)->(IID_nsIContextMenuListener, %p)\n", This, result);
1227 *result = &This->nsIContextMenuListener_iface;
1228 }else if(IsEqualGUID(&IID_nsIURIContentListener, riid)) {
1229 TRACE("(%p)->(IID_nsIURIContentListener %p)\n", This, result);
1230 *result = &This->nsIURIContentListener_iface;
1231 }else if(IsEqualGUID(&IID_nsIEmbeddingSiteWindow, riid)) {
1232 TRACE("(%p)->(IID_nsIEmbeddingSiteWindow %p)\n", This, result);
1233 *result = &This->nsIEmbeddingSiteWindow_iface;
1234 }else if(IsEqualGUID(&IID_nsITooltipListener, riid)) {
1235 TRACE("(%p)->(IID_nsITooltipListener %p)\n", This, result);
1236 *result = &This->nsITooltipListener_iface;
1237 }else if(IsEqualGUID(&IID_nsIInterfaceRequestor, riid)) {
1238 TRACE("(%p)->(IID_nsIInterfaceRequestor %p)\n", This, result);
1239 *result = &This->nsIInterfaceRequestor_iface;
1240 }else if(IsEqualGUID(&IID_nsISupportsWeakReference, riid)) {
1241 TRACE("(%p)->(IID_nsISupportsWeakReference %p)\n", This, result);
1242 *result = &This->nsISupportsWeakReference_iface;
1245 if(*result) {
1246 nsIWebBrowserChrome_AddRef(&This->nsIWebBrowserChrome_iface);
1247 return NS_OK;
1250 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
1251 return NS_NOINTERFACE;
1254 static nsrefcnt NSAPI nsWebBrowserChrome_AddRef(nsIWebBrowserChrome *iface)
1256 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1257 LONG ref = InterlockedIncrement(&This->ref);
1259 TRACE("(%p) ref=%d\n", This, ref);
1261 return ref;
1264 static nsrefcnt NSAPI nsWebBrowserChrome_Release(nsIWebBrowserChrome *iface)
1266 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1267 LONG ref = InterlockedDecrement(&This->ref);
1269 TRACE("(%p) ref=%d\n", This, ref);
1271 if(!ref) {
1272 if(This->parent)
1273 nsIWebBrowserChrome_Release(&This->parent->nsIWebBrowserChrome_iface);
1274 if(This->weak_reference) {
1275 This->weak_reference->nscontainer = NULL;
1276 nsIWeakReference_Release(&This->weak_reference->nsIWeakReference_iface);
1278 heap_free(This);
1281 return ref;
1284 static nsresult NSAPI nsWebBrowserChrome_SetStatus(nsIWebBrowserChrome *iface,
1285 UINT32 statusType, const PRUnichar *status)
1287 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1288 TRACE("(%p)->(%d %s)\n", This, statusType, debugstr_w(status));
1289 return NS_OK;
1292 static nsresult NSAPI nsWebBrowserChrome_GetWebBrowser(nsIWebBrowserChrome *iface,
1293 nsIWebBrowser **aWebBrowser)
1295 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1297 TRACE("(%p)->(%p)\n", This, aWebBrowser);
1299 if(!aWebBrowser)
1300 return NS_ERROR_INVALID_ARG;
1302 if(This->webbrowser)
1303 nsIWebBrowser_AddRef(This->webbrowser);
1304 *aWebBrowser = This->webbrowser;
1305 return S_OK;
1308 static nsresult NSAPI nsWebBrowserChrome_SetWebBrowser(nsIWebBrowserChrome *iface,
1309 nsIWebBrowser *aWebBrowser)
1311 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1313 TRACE("(%p)->(%p)\n", This, aWebBrowser);
1315 if(aWebBrowser != This->webbrowser)
1316 ERR("Wrong nsWebBrowser!\n");
1318 return NS_OK;
1321 static nsresult NSAPI nsWebBrowserChrome_GetChromeFlags(nsIWebBrowserChrome *iface,
1322 UINT32 *aChromeFlags)
1324 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1325 WARN("(%p)->(%p)\n", This, aChromeFlags);
1326 return NS_ERROR_NOT_IMPLEMENTED;
1329 static nsresult NSAPI nsWebBrowserChrome_SetChromeFlags(nsIWebBrowserChrome *iface,
1330 UINT32 aChromeFlags)
1332 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1333 WARN("(%p)->(%08x)\n", This, aChromeFlags);
1334 return NS_ERROR_NOT_IMPLEMENTED;
1337 static nsresult NSAPI nsWebBrowserChrome_DestroyBrowserWindow(nsIWebBrowserChrome *iface)
1339 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1340 TRACE("(%p)\n", This);
1341 return NS_ERROR_NOT_IMPLEMENTED;
1344 static nsresult NSAPI nsWebBrowserChrome_SizeBrowserTo(nsIWebBrowserChrome *iface,
1345 LONG aCX, LONG aCY)
1347 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1348 WARN("(%p)->(%d %d)\n", This, aCX, aCY);
1349 return NS_ERROR_NOT_IMPLEMENTED;
1352 static nsresult NSAPI nsWebBrowserChrome_ShowAsModal(nsIWebBrowserChrome *iface)
1354 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1355 WARN("(%p)\n", This);
1356 return NS_ERROR_NOT_IMPLEMENTED;
1359 static nsresult NSAPI nsWebBrowserChrome_IsWindowModal(nsIWebBrowserChrome *iface, cpp_bool *_retval)
1361 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1362 WARN("(%p)->(%p)\n", This, _retval);
1363 return NS_ERROR_NOT_IMPLEMENTED;
1366 static nsresult NSAPI nsWebBrowserChrome_ExitModalEventLoop(nsIWebBrowserChrome *iface,
1367 nsresult aStatus)
1369 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1370 WARN("(%p)->(%08x)\n", This, aStatus);
1371 return NS_ERROR_NOT_IMPLEMENTED;
1374 static const nsIWebBrowserChromeVtbl nsWebBrowserChromeVtbl = {
1375 nsWebBrowserChrome_QueryInterface,
1376 nsWebBrowserChrome_AddRef,
1377 nsWebBrowserChrome_Release,
1378 nsWebBrowserChrome_SetStatus,
1379 nsWebBrowserChrome_GetWebBrowser,
1380 nsWebBrowserChrome_SetWebBrowser,
1381 nsWebBrowserChrome_GetChromeFlags,
1382 nsWebBrowserChrome_SetChromeFlags,
1383 nsWebBrowserChrome_DestroyBrowserWindow,
1384 nsWebBrowserChrome_SizeBrowserTo,
1385 nsWebBrowserChrome_ShowAsModal,
1386 nsWebBrowserChrome_IsWindowModal,
1387 nsWebBrowserChrome_ExitModalEventLoop
1390 /**********************************************************
1391 * nsIContextMenuListener interface
1394 static inline NSContainer *impl_from_nsIContextMenuListener(nsIContextMenuListener *iface)
1396 return CONTAINING_RECORD(iface, NSContainer, nsIContextMenuListener_iface);
1399 static nsresult NSAPI nsContextMenuListener_QueryInterface(nsIContextMenuListener *iface,
1400 nsIIDRef riid, void **result)
1402 NSContainer *This = impl_from_nsIContextMenuListener(iface);
1403 return nsIWebBrowserChrome_QueryInterface(&This->nsIWebBrowserChrome_iface, riid, result);
1406 static nsrefcnt NSAPI nsContextMenuListener_AddRef(nsIContextMenuListener *iface)
1408 NSContainer *This = impl_from_nsIContextMenuListener(iface);
1409 return nsIWebBrowserChrome_AddRef(&This->nsIWebBrowserChrome_iface);
1412 static nsrefcnt NSAPI nsContextMenuListener_Release(nsIContextMenuListener *iface)
1414 NSContainer *This = impl_from_nsIContextMenuListener(iface);
1415 return nsIWebBrowserChrome_Release(&This->nsIWebBrowserChrome_iface);
1418 static nsresult NSAPI nsContextMenuListener_OnShowContextMenu(nsIContextMenuListener *iface,
1419 UINT32 aContextFlags, nsIDOMEvent *aEvent, nsIDOMNode *aNode)
1421 NSContainer *This = impl_from_nsIContextMenuListener(iface);
1422 nsIDOMMouseEvent *event;
1423 HTMLDOMNode *node;
1424 POINT pt;
1425 DWORD dwID = CONTEXT_MENU_DEFAULT;
1426 nsresult nsres;
1427 HRESULT hres;
1429 TRACE("(%p)->(%08x %p %p)\n", This, aContextFlags, aEvent, aNode);
1431 fire_event(This->doc->basedoc.doc_node /* FIXME */, EVENTID_CONTEXTMENU, TRUE, aNode, aEvent, NULL);
1433 nsres = nsIDOMEvent_QueryInterface(aEvent, &IID_nsIDOMMouseEvent, (void**)&event);
1434 if(NS_FAILED(nsres)) {
1435 ERR("Could not get nsIDOMMouseEvent interface: %08x\n", nsres);
1436 return nsres;
1439 nsIDOMMouseEvent_GetScreenX(event, &pt.x);
1440 nsIDOMMouseEvent_GetScreenY(event, &pt.y);
1441 nsIDOMMouseEvent_Release(event);
1443 switch(aContextFlags) {
1444 case CONTEXT_NONE:
1445 case CONTEXT_DOCUMENT:
1446 case CONTEXT_TEXT:
1447 dwID = CONTEXT_MENU_DEFAULT;
1448 break;
1449 case CONTEXT_IMAGE:
1450 case CONTEXT_IMAGE|CONTEXT_LINK:
1451 dwID = CONTEXT_MENU_IMAGE;
1452 break;
1453 case CONTEXT_LINK:
1454 dwID = CONTEXT_MENU_ANCHOR;
1455 break;
1456 case CONTEXT_INPUT:
1457 dwID = CONTEXT_MENU_CONTROL;
1458 break;
1459 default:
1460 FIXME("aContextFlags=%08x\n", aContextFlags);
1463 hres = get_node(This->doc->basedoc.doc_node, aNode, TRUE, &node);
1464 if(FAILED(hres))
1465 return NS_ERROR_FAILURE;
1467 show_context_menu(This->doc, dwID, &pt, (IDispatch*)&node->IHTMLDOMNode_iface);
1468 node_release(node);
1469 return NS_OK;
1472 static const nsIContextMenuListenerVtbl nsContextMenuListenerVtbl = {
1473 nsContextMenuListener_QueryInterface,
1474 nsContextMenuListener_AddRef,
1475 nsContextMenuListener_Release,
1476 nsContextMenuListener_OnShowContextMenu
1479 /**********************************************************
1480 * nsIURIContentListener interface
1483 static inline NSContainer *impl_from_nsIURIContentListener(nsIURIContentListener *iface)
1485 return CONTAINING_RECORD(iface, NSContainer, nsIURIContentListener_iface);
1488 static nsresult NSAPI nsURIContentListener_QueryInterface(nsIURIContentListener *iface,
1489 nsIIDRef riid, void **result)
1491 NSContainer *This = impl_from_nsIURIContentListener(iface);
1492 return nsIWebBrowserChrome_QueryInterface(&This->nsIWebBrowserChrome_iface, riid, result);
1495 static nsrefcnt NSAPI nsURIContentListener_AddRef(nsIURIContentListener *iface)
1497 NSContainer *This = impl_from_nsIURIContentListener(iface);
1498 return nsIWebBrowserChrome_AddRef(&This->nsIWebBrowserChrome_iface);
1501 static nsrefcnt NSAPI nsURIContentListener_Release(nsIURIContentListener *iface)
1503 NSContainer *This = impl_from_nsIURIContentListener(iface);
1504 return nsIWebBrowserChrome_Release(&This->nsIWebBrowserChrome_iface);
1507 static nsresult NSAPI nsURIContentListener_OnStartURIOpen(nsIURIContentListener *iface,
1508 nsIURI *aURI, cpp_bool *_retval)
1510 NSContainer *This = impl_from_nsIURIContentListener(iface);
1511 nsACString spec_str;
1512 const char *spec;
1513 nsresult nsres;
1515 nsACString_Init(&spec_str, NULL);
1516 nsIURI_GetSpec(aURI, &spec_str);
1517 nsACString_GetData(&spec_str, &spec);
1519 TRACE("(%p)->(%p(%s) %p)\n", This, aURI, debugstr_a(spec), _retval);
1521 nsACString_Finish(&spec_str);
1523 nsres = on_start_uri_open(This, aURI, _retval);
1524 if(NS_FAILED(nsres))
1525 return nsres;
1527 return !*_retval && This->content_listener
1528 ? nsIURIContentListener_OnStartURIOpen(This->content_listener, aURI, _retval)
1529 : NS_OK;
1532 static nsresult NSAPI nsURIContentListener_DoContent(nsIURIContentListener *iface,
1533 const char *aContentType, cpp_bool aIsContentPreferred, nsIRequest *aRequest,
1534 nsIStreamListener **aContentHandler, cpp_bool *_retval)
1536 NSContainer *This = impl_from_nsIURIContentListener(iface);
1538 TRACE("(%p)->(%s %x %p %p %p)\n", This, debugstr_a(aContentType), aIsContentPreferred,
1539 aRequest, aContentHandler, _retval);
1541 return This->content_listener
1542 ? nsIURIContentListener_DoContent(This->content_listener, aContentType,
1543 aIsContentPreferred, aRequest, aContentHandler, _retval)
1544 : NS_ERROR_NOT_IMPLEMENTED;
1547 static nsresult NSAPI nsURIContentListener_IsPreferred(nsIURIContentListener *iface,
1548 const char *aContentType, char **aDesiredContentType, cpp_bool *_retval)
1550 NSContainer *This = impl_from_nsIURIContentListener(iface);
1552 TRACE("(%p)->(%s %p %p)\n", This, debugstr_a(aContentType), aDesiredContentType, _retval);
1554 /* FIXME: Should we do something here? */
1555 *_retval = TRUE;
1557 return This->content_listener
1558 ? nsIURIContentListener_IsPreferred(This->content_listener, aContentType,
1559 aDesiredContentType, _retval)
1560 : NS_OK;
1563 static nsresult NSAPI nsURIContentListener_CanHandleContent(nsIURIContentListener *iface,
1564 const char *aContentType, cpp_bool aIsContentPreferred, char **aDesiredContentType,
1565 cpp_bool *_retval)
1567 NSContainer *This = impl_from_nsIURIContentListener(iface);
1569 TRACE("(%p)->(%s %x %p %p)\n", This, debugstr_a(aContentType), aIsContentPreferred,
1570 aDesiredContentType, _retval);
1572 return This->content_listener
1573 ? nsIURIContentListener_CanHandleContent(This->content_listener, aContentType,
1574 aIsContentPreferred, aDesiredContentType, _retval)
1575 : NS_ERROR_NOT_IMPLEMENTED;
1578 static nsresult NSAPI nsURIContentListener_GetLoadCookie(nsIURIContentListener *iface,
1579 nsISupports **aLoadCookie)
1581 NSContainer *This = impl_from_nsIURIContentListener(iface);
1583 WARN("(%p)->(%p)\n", This, aLoadCookie);
1585 return This->content_listener
1586 ? nsIURIContentListener_GetLoadCookie(This->content_listener, aLoadCookie)
1587 : NS_ERROR_NOT_IMPLEMENTED;
1590 static nsresult NSAPI nsURIContentListener_SetLoadCookie(nsIURIContentListener *iface,
1591 nsISupports *aLoadCookie)
1593 NSContainer *This = impl_from_nsIURIContentListener(iface);
1595 WARN("(%p)->(%p)\n", This, aLoadCookie);
1597 return This->content_listener
1598 ? nsIURIContentListener_SetLoadCookie(This->content_listener, aLoadCookie)
1599 : NS_ERROR_NOT_IMPLEMENTED;
1602 static nsresult NSAPI nsURIContentListener_GetParentContentListener(nsIURIContentListener *iface,
1603 nsIURIContentListener **aParentContentListener)
1605 NSContainer *This = impl_from_nsIURIContentListener(iface);
1607 TRACE("(%p)->(%p)\n", This, aParentContentListener);
1609 if(This->content_listener)
1610 nsIURIContentListener_AddRef(This->content_listener);
1612 *aParentContentListener = This->content_listener;
1613 return NS_OK;
1616 static nsresult NSAPI nsURIContentListener_SetParentContentListener(nsIURIContentListener *iface,
1617 nsIURIContentListener *aParentContentListener)
1619 NSContainer *This = impl_from_nsIURIContentListener(iface);
1621 TRACE("(%p)->(%p)\n", This, aParentContentListener);
1623 if(aParentContentListener == &This->nsIURIContentListener_iface)
1624 return NS_OK;
1626 if(This->content_listener)
1627 nsIURIContentListener_Release(This->content_listener);
1629 This->content_listener = aParentContentListener;
1630 if(This->content_listener)
1631 nsIURIContentListener_AddRef(This->content_listener);
1633 return NS_OK;
1636 static const nsIURIContentListenerVtbl nsURIContentListenerVtbl = {
1637 nsURIContentListener_QueryInterface,
1638 nsURIContentListener_AddRef,
1639 nsURIContentListener_Release,
1640 nsURIContentListener_OnStartURIOpen,
1641 nsURIContentListener_DoContent,
1642 nsURIContentListener_IsPreferred,
1643 nsURIContentListener_CanHandleContent,
1644 nsURIContentListener_GetLoadCookie,
1645 nsURIContentListener_SetLoadCookie,
1646 nsURIContentListener_GetParentContentListener,
1647 nsURIContentListener_SetParentContentListener
1650 /**********************************************************
1651 * nsIEmbeddinSiteWindow interface
1654 static inline NSContainer *impl_from_nsIEmbeddingSiteWindow(nsIEmbeddingSiteWindow *iface)
1656 return CONTAINING_RECORD(iface, NSContainer, nsIEmbeddingSiteWindow_iface);
1659 static nsresult NSAPI nsEmbeddingSiteWindow_QueryInterface(nsIEmbeddingSiteWindow *iface,
1660 nsIIDRef riid, void **result)
1662 NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
1663 return nsIWebBrowserChrome_QueryInterface(&This->nsIWebBrowserChrome_iface, riid, result);
1666 static nsrefcnt NSAPI nsEmbeddingSiteWindow_AddRef(nsIEmbeddingSiteWindow *iface)
1668 NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
1669 return nsIWebBrowserChrome_AddRef(&This->nsIWebBrowserChrome_iface);
1672 static nsrefcnt NSAPI nsEmbeddingSiteWindow_Release(nsIEmbeddingSiteWindow *iface)
1674 NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
1675 return nsIWebBrowserChrome_Release(&This->nsIWebBrowserChrome_iface);
1678 static nsresult NSAPI nsEmbeddingSiteWindow_SetDimensions(nsIEmbeddingSiteWindow *iface,
1679 UINT32 flags, LONG x, LONG y, LONG cx, LONG cy)
1681 NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
1682 WARN("(%p)->(%08x %d %d %d %d)\n", This, flags, x, y, cx, cy);
1683 return NS_ERROR_NOT_IMPLEMENTED;
1686 static nsresult NSAPI nsEmbeddingSiteWindow_GetDimensions(nsIEmbeddingSiteWindow *iface,
1687 UINT32 flags, LONG *x, LONG *y, LONG *cx, LONG *cy)
1689 NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
1690 WARN("(%p)->(%08x %p %p %p %p)\n", This, flags, x, y, cx, cy);
1691 return NS_ERROR_NOT_IMPLEMENTED;
1694 static nsresult NSAPI nsEmbeddingSiteWindow_SetFocus(nsIEmbeddingSiteWindow *iface)
1696 NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
1698 TRACE("(%p)\n", This);
1700 return nsIBaseWindow_SetFocus(This->window);
1703 static nsresult NSAPI nsEmbeddingSiteWindow_GetVisibility(nsIEmbeddingSiteWindow *iface,
1704 cpp_bool *aVisibility)
1706 NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
1708 TRACE("(%p)->(%p)\n", This, aVisibility);
1710 *aVisibility = This->doc && This->doc->hwnd && IsWindowVisible(This->doc->hwnd);
1711 return NS_OK;
1714 static nsresult NSAPI nsEmbeddingSiteWindow_SetVisibility(nsIEmbeddingSiteWindow *iface,
1715 cpp_bool aVisibility)
1717 NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
1719 TRACE("(%p)->(%x)\n", This, aVisibility);
1721 return NS_OK;
1724 static nsresult NSAPI nsEmbeddingSiteWindow_GetTitle(nsIEmbeddingSiteWindow *iface,
1725 PRUnichar **aTitle)
1727 NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
1728 WARN("(%p)->(%p)\n", This, aTitle);
1729 return NS_ERROR_NOT_IMPLEMENTED;
1732 static nsresult NSAPI nsEmbeddingSiteWindow_SetTitle(nsIEmbeddingSiteWindow *iface,
1733 const PRUnichar *aTitle)
1735 NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
1736 WARN("(%p)->(%s)\n", This, debugstr_w(aTitle));
1737 return NS_ERROR_NOT_IMPLEMENTED;
1740 static nsresult NSAPI nsEmbeddingSiteWindow_GetSiteWindow(nsIEmbeddingSiteWindow *iface,
1741 void **aSiteWindow)
1743 NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
1745 TRACE("(%p)->(%p)\n", This, aSiteWindow);
1747 *aSiteWindow = This->hwnd;
1748 return NS_OK;
1751 static const nsIEmbeddingSiteWindowVtbl nsEmbeddingSiteWindowVtbl = {
1752 nsEmbeddingSiteWindow_QueryInterface,
1753 nsEmbeddingSiteWindow_AddRef,
1754 nsEmbeddingSiteWindow_Release,
1755 nsEmbeddingSiteWindow_SetDimensions,
1756 nsEmbeddingSiteWindow_GetDimensions,
1757 nsEmbeddingSiteWindow_SetFocus,
1758 nsEmbeddingSiteWindow_GetVisibility,
1759 nsEmbeddingSiteWindow_SetVisibility,
1760 nsEmbeddingSiteWindow_GetTitle,
1761 nsEmbeddingSiteWindow_SetTitle,
1762 nsEmbeddingSiteWindow_GetSiteWindow
1765 static inline NSContainer *impl_from_nsITooltipListener(nsITooltipListener *iface)
1767 return CONTAINING_RECORD(iface, NSContainer, nsITooltipListener_iface);
1770 static nsresult NSAPI nsTooltipListener_QueryInterface(nsITooltipListener *iface, nsIIDRef riid,
1771 void **result)
1773 NSContainer *This = impl_from_nsITooltipListener(iface);
1774 return nsIWebBrowserChrome_QueryInterface(&This->nsIWebBrowserChrome_iface, riid, result);
1777 static nsrefcnt NSAPI nsTooltipListener_AddRef(nsITooltipListener *iface)
1779 NSContainer *This = impl_from_nsITooltipListener(iface);
1780 return nsIWebBrowserChrome_AddRef(&This->nsIWebBrowserChrome_iface);
1783 static nsrefcnt NSAPI nsTooltipListener_Release(nsITooltipListener *iface)
1785 NSContainer *This = impl_from_nsITooltipListener(iface);
1786 return nsIWebBrowserChrome_Release(&This->nsIWebBrowserChrome_iface);
1789 static nsresult NSAPI nsTooltipListener_OnShowTooltip(nsITooltipListener *iface,
1790 LONG aXCoord, LONG aYCoord, const PRUnichar *aTipText)
1792 NSContainer *This = impl_from_nsITooltipListener(iface);
1794 if (This->doc)
1795 show_tooltip(This->doc, aXCoord, aYCoord, aTipText);
1797 return NS_OK;
1800 static nsresult NSAPI nsTooltipListener_OnHideTooltip(nsITooltipListener *iface)
1802 NSContainer *This = impl_from_nsITooltipListener(iface);
1804 if (This->doc)
1805 hide_tooltip(This->doc);
1807 return NS_OK;
1810 static const nsITooltipListenerVtbl nsTooltipListenerVtbl = {
1811 nsTooltipListener_QueryInterface,
1812 nsTooltipListener_AddRef,
1813 nsTooltipListener_Release,
1814 nsTooltipListener_OnShowTooltip,
1815 nsTooltipListener_OnHideTooltip
1818 static inline NSContainer *impl_from_nsIInterfaceRequestor(nsIInterfaceRequestor *iface)
1820 return CONTAINING_RECORD(iface, NSContainer, nsIInterfaceRequestor_iface);
1823 static nsresult NSAPI nsInterfaceRequestor_QueryInterface(nsIInterfaceRequestor *iface,
1824 nsIIDRef riid, void **result)
1826 NSContainer *This = impl_from_nsIInterfaceRequestor(iface);
1827 return nsIWebBrowserChrome_QueryInterface(&This->nsIWebBrowserChrome_iface, riid, result);
1830 static nsrefcnt NSAPI nsInterfaceRequestor_AddRef(nsIInterfaceRequestor *iface)
1832 NSContainer *This = impl_from_nsIInterfaceRequestor(iface);
1833 return nsIWebBrowserChrome_AddRef(&This->nsIWebBrowserChrome_iface);
1836 static nsrefcnt NSAPI nsInterfaceRequestor_Release(nsIInterfaceRequestor *iface)
1838 NSContainer *This = impl_from_nsIInterfaceRequestor(iface);
1839 return nsIWebBrowserChrome_Release(&This->nsIWebBrowserChrome_iface);
1842 static nsresult NSAPI nsInterfaceRequestor_GetInterface(nsIInterfaceRequestor *iface,
1843 nsIIDRef riid, void **result)
1845 NSContainer *This = impl_from_nsIInterfaceRequestor(iface);
1847 if(IsEqualGUID(&IID_nsIDOMWindow, riid)) {
1848 TRACE("(%p)->(IID_nsIDOMWindow %p)\n", This, result);
1849 return nsIWebBrowser_GetContentDOMWindow(This->webbrowser, (nsIDOMWindow**)result);
1852 return nsIWebBrowserChrome_QueryInterface(&This->nsIWebBrowserChrome_iface, riid, result);
1855 static const nsIInterfaceRequestorVtbl nsInterfaceRequestorVtbl = {
1856 nsInterfaceRequestor_QueryInterface,
1857 nsInterfaceRequestor_AddRef,
1858 nsInterfaceRequestor_Release,
1859 nsInterfaceRequestor_GetInterface
1862 static inline NSContainer *impl_from_nsISupportsWeakReference(nsISupportsWeakReference *iface)
1864 return CONTAINING_RECORD(iface, NSContainer, nsISupportsWeakReference_iface);
1867 static nsresult NSAPI nsSupportsWeakReference_QueryInterface(nsISupportsWeakReference *iface,
1868 nsIIDRef riid, void **result)
1870 NSContainer *This = impl_from_nsISupportsWeakReference(iface);
1871 return nsIWebBrowserChrome_QueryInterface(&This->nsIWebBrowserChrome_iface, riid, result);
1874 static nsrefcnt NSAPI nsSupportsWeakReference_AddRef(nsISupportsWeakReference *iface)
1876 NSContainer *This = impl_from_nsISupportsWeakReference(iface);
1877 return nsIWebBrowserChrome_AddRef(&This->nsIWebBrowserChrome_iface);
1880 static nsrefcnt NSAPI nsSupportsWeakReference_Release(nsISupportsWeakReference *iface)
1882 NSContainer *This = impl_from_nsISupportsWeakReference(iface);
1883 return nsIWebBrowserChrome_Release(&This->nsIWebBrowserChrome_iface);
1886 static nsresult NSAPI nsSupportsWeakReference_GetWeakReference(nsISupportsWeakReference *iface,
1887 nsIWeakReference **_retval)
1889 NSContainer *This = impl_from_nsISupportsWeakReference(iface);
1891 TRACE("(%p)->(%p)\n", This, _retval);
1893 if(!This->weak_reference) {
1894 This->weak_reference = heap_alloc(sizeof(nsWeakReference));
1895 if(!This->weak_reference)
1896 return NS_ERROR_OUT_OF_MEMORY;
1898 This->weak_reference->nsIWeakReference_iface.lpVtbl = &nsWeakReferenceVtbl;
1899 This->weak_reference->ref = 1;
1900 This->weak_reference->nscontainer = This;
1903 *_retval = &This->weak_reference->nsIWeakReference_iface;
1904 nsIWeakReference_AddRef(*_retval);
1905 return NS_OK;
1908 static const nsISupportsWeakReferenceVtbl nsSupportsWeakReferenceVtbl = {
1909 nsSupportsWeakReference_QueryInterface,
1910 nsSupportsWeakReference_AddRef,
1911 nsSupportsWeakReference_Release,
1912 nsSupportsWeakReference_GetWeakReference
1915 static HRESULT init_nscontainer(NSContainer *nscontainer)
1917 nsIWebBrowserSetup *wbsetup;
1918 nsIScrollable *scrollable;
1919 nsresult nsres;
1921 nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr, NS_WEBBROWSER_CONTRACTID,
1922 NULL, &IID_nsIWebBrowser, (void**)&nscontainer->webbrowser);
1923 if(NS_FAILED(nsres)) {
1924 ERR("Creating WebBrowser failed: %08x\n", nsres);
1925 return E_FAIL;
1928 nsres = nsIWebBrowser_SetContainerWindow(nscontainer->webbrowser, &nscontainer->nsIWebBrowserChrome_iface);
1929 if(NS_FAILED(nsres)) {
1930 ERR("SetContainerWindow failed: %08x\n", nsres);
1931 return E_FAIL;
1934 nsres = nsIWebBrowser_QueryInterface(nscontainer->webbrowser, &IID_nsIBaseWindow,
1935 (void**)&nscontainer->window);
1936 if(NS_FAILED(nsres)) {
1937 ERR("Could not get nsIBaseWindow interface: %08x\n", nsres);
1938 return E_FAIL;
1941 nsres = nsIWebBrowser_QueryInterface(nscontainer->webbrowser, &IID_nsIWebBrowserSetup,
1942 (void**)&wbsetup);
1943 if(NS_SUCCEEDED(nsres)) {
1944 nsres = nsIWebBrowserSetup_SetProperty(wbsetup, SETUP_IS_CHROME_WRAPPER, FALSE);
1945 nsIWebBrowserSetup_Release(wbsetup);
1946 if(NS_FAILED(nsres)) {
1947 ERR("SetProperty(SETUP_IS_CHROME_WRAPPER) failed: %08x\n", nsres);
1948 return E_FAIL;
1950 }else {
1951 ERR("Could not get nsIWebBrowserSetup interface\n");
1952 return E_FAIL;
1955 nsres = nsIWebBrowser_QueryInterface(nscontainer->webbrowser, &IID_nsIWebNavigation,
1956 (void**)&nscontainer->navigation);
1957 if(NS_FAILED(nsres)) {
1958 ERR("Could not get nsIWebNavigation interface: %08x\n", nsres);
1959 return E_FAIL;
1962 nsres = nsIWebBrowser_QueryInterface(nscontainer->webbrowser, &IID_nsIWebBrowserFocus,
1963 (void**)&nscontainer->focus);
1964 if(NS_FAILED(nsres)) {
1965 ERR("Could not get nsIWebBrowserFocus interface: %08x\n", nsres);
1966 return E_FAIL;
1969 if(!nscontainer_class) {
1970 register_nscontainer_class();
1971 if(!nscontainer_class)
1972 return E_FAIL;
1975 nscontainer->hwnd = CreateWindowExW(0, wszNsContainer, NULL,
1976 WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, 100, 100,
1977 GetDesktopWindow(), NULL, hInst, nscontainer);
1978 if(!nscontainer->hwnd) {
1979 WARN("Could not create window\n");
1980 return E_FAIL;
1983 nsres = nsIBaseWindow_InitWindow(nscontainer->window, nscontainer->hwnd, NULL, 0, 0, 100, 100);
1984 if(NS_SUCCEEDED(nsres)) {
1985 nsres = nsIBaseWindow_Create(nscontainer->window);
1986 if(NS_FAILED(nsres)) {
1987 WARN("Creating window failed: %08x\n", nsres);
1988 return E_FAIL;
1991 nsIBaseWindow_SetVisibility(nscontainer->window, FALSE);
1992 nsIBaseWindow_SetEnabled(nscontainer->window, FALSE);
1993 }else {
1994 ERR("InitWindow failed: %08x\n", nsres);
1995 return E_FAIL;
1998 nsres = nsIWebBrowser_SetParentURIContentListener(nscontainer->webbrowser,
1999 &nscontainer->nsIURIContentListener_iface);
2000 if(NS_FAILED(nsres))
2001 ERR("SetParentURIContentListener failed: %08x\n", nsres);
2003 nsres = nsIWebBrowser_QueryInterface(nscontainer->webbrowser, &IID_nsIScrollable, (void**)&scrollable);
2004 if(NS_SUCCEEDED(nsres)) {
2005 nsres = nsIScrollable_SetDefaultScrollbarPreferences(scrollable,
2006 ScrollOrientation_Y, Scrollbar_Always);
2007 if(NS_FAILED(nsres))
2008 ERR("Could not set default Y scrollbar prefs: %08x\n", nsres);
2010 nsres = nsIScrollable_SetDefaultScrollbarPreferences(scrollable,
2011 ScrollOrientation_X, Scrollbar_Auto);
2012 if(NS_FAILED(nsres))
2013 ERR("Could not set default X scrollbar prefs: %08x\n", nsres);
2015 nsIScrollable_Release(scrollable);
2016 }else {
2017 ERR("Could not get nsIScrollable: %08x\n", nsres);
2020 return S_OK;
2023 HRESULT create_nscontainer(HTMLDocumentObj *doc, NSContainer **_ret)
2025 NSContainer *ret;
2026 HRESULT hres;
2028 if(!load_gecko())
2029 return CLASS_E_CLASSNOTAVAILABLE;
2031 ret = heap_alloc_zero(sizeof(NSContainer));
2032 if(!ret)
2033 return E_OUTOFMEMORY;
2035 ret->nsIWebBrowserChrome_iface.lpVtbl = &nsWebBrowserChromeVtbl;
2036 ret->nsIContextMenuListener_iface.lpVtbl = &nsContextMenuListenerVtbl;
2037 ret->nsIURIContentListener_iface.lpVtbl = &nsURIContentListenerVtbl;
2038 ret->nsIEmbeddingSiteWindow_iface.lpVtbl = &nsEmbeddingSiteWindowVtbl;
2039 ret->nsITooltipListener_iface.lpVtbl = &nsTooltipListenerVtbl;
2040 ret->nsIInterfaceRequestor_iface.lpVtbl = &nsInterfaceRequestorVtbl;
2041 ret->nsISupportsWeakReference_iface.lpVtbl = &nsSupportsWeakReferenceVtbl;
2043 ret->doc = doc;
2044 ret->ref = 1;
2046 hres = init_nscontainer(ret);
2047 if(SUCCEEDED(hres))
2048 *_ret = ret;
2049 else
2050 nsIWebBrowserChrome_Release(&ret->nsIWebBrowserChrome_iface);
2051 return hres;
2054 void NSContainer_Release(NSContainer *This)
2056 TRACE("(%p)\n", This);
2058 This->doc = NULL;
2060 ShowWindow(This->hwnd, SW_HIDE);
2061 SetParent(This->hwnd, NULL);
2063 nsIBaseWindow_SetVisibility(This->window, FALSE);
2064 nsIBaseWindow_Destroy(This->window);
2066 nsIWebBrowser_SetContainerWindow(This->webbrowser, NULL);
2068 nsIWebBrowser_Release(This->webbrowser);
2069 This->webbrowser = NULL;
2071 nsIWebNavigation_Release(This->navigation);
2072 This->navigation = NULL;
2074 nsIBaseWindow_Release(This->window);
2075 This->window = NULL;
2077 nsIWebBrowserFocus_Release(This->focus);
2078 This->focus = NULL;
2080 if(This->editor_controller) {
2081 nsIController_Release(This->editor_controller);
2082 This->editor_controller = NULL;
2085 if(This->editor) {
2086 nsIEditor_Release(This->editor);
2087 This->editor = NULL;
2090 if(This->content_listener) {
2091 nsIURIContentListener_Release(This->content_listener);
2092 This->content_listener = NULL;
2095 if(This->hwnd) {
2096 DestroyWindow(This->hwnd);
2097 This->hwnd = NULL;
2100 nsIWebBrowserChrome_Release(&This->nsIWebBrowserChrome_iface);