1 /*
2 * Copyright 2005-2007 Jacek Caban for CodeWeavers
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19 #include "mshtml_private.h"
20
21 #include <wincon.h>
22 #include <shlobj.h>
23
24 WINE_DECLARE_DEBUG_CHANNEL(gecko);
25
26 #define NS_APPSTARTUPNOTIFIER_CONTRACTID "@mozilla.org/embedcomp/appstartup-notifier;1"
27 #define NS_WEBBROWSER_CONTRACTID "@mozilla.org/embedding/browser/nsWebBrowser;1"
28 #define NS_COMMANDPARAMS_CONTRACTID "@mozilla.org/embedcomp/command-params;1"
29 #define NS_HTMLSERIALIZER_CONTRACTID "@mozilla.org/layout/contentserializer;1?mimetype=text/html"
30 #define NS_EDITORCONTROLLER_CONTRACTID "@mozilla.org/editor/editorcontroller;1"
31 #define NS_PREFERENCES_CONTRACTID "@mozilla.org/preferences;1"
32 #define NS_VARIANT_CONTRACTID "@mozilla.org/variant;1"
33 #define NS_CATEGORYMANAGER_CONTRACTID "@mozilla.org/categorymanager;1"
34 #define NS_XMLHTTPREQUEST_CONTRACTID "@mozilla.org/xmlextras/xmlhttprequest;1"
35 #define NS_SCRIPTSECURITYMANAGER_CONTRACTID "@mozilla.org/scriptsecuritymanager;1"
36
37 #define PR_UINT32_MAX 0xffffffff
38
39 #define NS_STRING_CONTAINER_INIT_DEPEND 0x0002
40 #define NS_CSTRING_CONTAINER_INIT_DEPEND 0x0002
41
42 typedef UINT32 PRUint32;
43
44 static nsresult (CDECL *NS_InitXPCOM2)(nsIServiceManager**,void*,void*);
45 static nsresult (CDECL *NS_ShutdownXPCOM)(nsIServiceManager*);
46 static nsresult (CDECL *NS_GetComponentRegistrar)(nsIComponentRegistrar**);
47 static nsresult (CDECL *NS_StringContainerInit2)(nsStringContainer*,const PRUnichar*,PRUint32,PRUint32);
48 static nsresult (CDECL *NS_CStringContainerInit2)(nsCStringContainer*,const char*,PRUint32,PRUint32);
49 static nsresult (CDECL *NS_StringContainerFinish)(nsStringContainer*);
50 static nsresult (CDECL *NS_CStringContainerFinish)(nsCStringContainer*);
51 static nsresult (CDECL *NS_StringSetData)(nsAString*,const PRUnichar*,PRUint32);
52 static nsresult (CDECL *NS_CStringSetData)(nsACString*,const char*,PRUint32);
53 static nsresult (CDECL *NS_NewLocalFile)(const nsAString*,cpp_bool,nsIFile**);
54 static PRUint32 (CDECL *NS_StringGetData)(const nsAString*,const PRUnichar **,cpp_bool*);
55 static PRUint32 (CDECL *NS_CStringGetData)(const nsACString*,const char**,cpp_bool*);
56 static void* (CDECL *NS_Alloc)(SIZE_T);
57 static void (CDECL *NS_Free)(void*);
58
59 static HINSTANCE xul_handle = NULL;
60
61 static nsIServiceManager *pServMgr = NULL;
62 static nsIComponentManager *pCompMgr = NULL;
63 static nsICategoryManager *cat_mgr;
64 static nsIFile *profile_directory, *plugin_directory;
65
66 static const WCHAR wszNsContainer[] = {'N','s','C','o','n','t','a','i','n','e','r',0};
67
68 static ATOM nscontainer_class;
69 static WCHAR gecko_path[MAX_PATH];
70 static unsigned gecko_path_len;
71
create_nsfile(const PRUnichar * path,nsIFile ** ret)72 nsresult create_nsfile(const PRUnichar *path, nsIFile **ret)
73 {
74 nsAString str;
75 nsresult nsres;
76
77 nsAString_InitDepend(&str, path);
78 nsres = NS_NewLocalFile(&str, FALSE, ret);
79 nsAString_Finish(&str);
80
81 if(NS_FAILED(nsres))
82 WARN("NS_NewLocalFile failed: %08x\n", nsres);
83 return nsres;
84 }
85
86 typedef struct {
87 nsISimpleEnumerator nsISimpleEnumerator_iface;
88 LONG ref;
89 nsISupports *value;
90 } nsSingletonEnumerator;
91
impl_from_nsISimpleEnumerator(nsISimpleEnumerator * iface)92 static inline nsSingletonEnumerator *impl_from_nsISimpleEnumerator(nsISimpleEnumerator *iface)
93 {
94 return CONTAINING_RECORD(iface, nsSingletonEnumerator, nsISimpleEnumerator_iface);
95 }
96
nsSingletonEnumerator_QueryInterface(nsISimpleEnumerator * iface,nsIIDRef riid,void ** ppv)97 static nsresult NSAPI nsSingletonEnumerator_QueryInterface(nsISimpleEnumerator *iface, nsIIDRef riid, void **ppv)
98 {
99 nsSingletonEnumerator *This = impl_from_nsISimpleEnumerator(iface);
100
101 if(IsEqualGUID(&IID_nsISupports, riid)) {
102 TRACE("(%p)->(IID_nsISupports %p)\n", This, ppv);
103 *ppv = &This->nsISimpleEnumerator_iface;
104 }else if(IsEqualGUID(&IID_nsISimpleEnumerator, riid)) {
105 TRACE("(%p)->(IID_nsISimpleEnumerator %p)\n", This, ppv);
106 *ppv = &This->nsISimpleEnumerator_iface;
107 }else {
108 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
109 *ppv = NULL;
110 return NS_NOINTERFACE;
111 }
112
113 nsISupports_AddRef((nsISupports*)*ppv);
114 return NS_OK;
115 }
116
nsSingletonEnumerator_AddRef(nsISimpleEnumerator * iface)117 static nsrefcnt NSAPI nsSingletonEnumerator_AddRef(nsISimpleEnumerator *iface)
118 {
119 nsSingletonEnumerator *This = impl_from_nsISimpleEnumerator(iface);
120 nsrefcnt ref = InterlockedIncrement(&This->ref);
121
122 TRACE("(%p) ref=%d\n", This, ref);
123
124 return ref;
125 }
126
nsSingletonEnumerator_Release(nsISimpleEnumerator * iface)127 static nsrefcnt NSAPI nsSingletonEnumerator_Release(nsISimpleEnumerator *iface)
128 {
129 nsSingletonEnumerator *This = impl_from_nsISimpleEnumerator(iface);
130 nsrefcnt ref = InterlockedDecrement(&This->ref);
131
132 TRACE("(%p) ref=%d\n", This, ref);
133
134 if(!ref) {
135 if(This->value)
136 nsISupports_Release(This->value);
137 heap_free(This);
138 }
139
140 return ref;
141 }
142
nsSingletonEnumerator_HasMoreElements(nsISimpleEnumerator * iface,cpp_bool * _retval)143 static nsresult NSAPI nsSingletonEnumerator_HasMoreElements(nsISimpleEnumerator *iface, cpp_bool *_retval)
144 {
145 nsSingletonEnumerator *This = impl_from_nsISimpleEnumerator(iface);
146
147 TRACE("(%p)->()\n", This);
148
149 *_retval = This->value != NULL;
150 return NS_OK;
151 }
152
nsSingletonEnumerator_GetNext(nsISimpleEnumerator * iface,nsISupports ** _retval)153 static nsresult NSAPI nsSingletonEnumerator_GetNext(nsISimpleEnumerator *iface, nsISupports **_retval)
154 {
155 nsSingletonEnumerator *This = impl_from_nsISimpleEnumerator(iface);
156
157 TRACE("(%p)->()\n", This);
158
159 if(!This->value)
160 return NS_ERROR_UNEXPECTED;
161
162 *_retval = This->value;
163 This->value = NULL;
164 return NS_OK;
165 }
166
167 static const nsISimpleEnumeratorVtbl nsSingletonEnumeratorVtbl = {
168 nsSingletonEnumerator_QueryInterface,
169 nsSingletonEnumerator_AddRef,
170 nsSingletonEnumerator_Release,
171 nsSingletonEnumerator_HasMoreElements,
172 nsSingletonEnumerator_GetNext
173 };
174
create_singleton_enumerator(nsISupports * value)175 static nsISimpleEnumerator *create_singleton_enumerator(nsISupports *value)
176 {
177 nsSingletonEnumerator *ret;
178
179 ret = heap_alloc(sizeof(*ret));
180 if(!ret)
181 return NULL;
182
183 ret->nsISimpleEnumerator_iface.lpVtbl = &nsSingletonEnumeratorVtbl;
184 ret->ref = 1;
185
186 if(value)
187 nsISupports_AddRef(value);
188 ret->value = value;
189 return &ret->nsISimpleEnumerator_iface;
190 }
191
nsDirectoryServiceProvider2_QueryInterface(nsIDirectoryServiceProvider2 * iface,nsIIDRef riid,void ** result)192 static nsresult NSAPI nsDirectoryServiceProvider2_QueryInterface(nsIDirectoryServiceProvider2 *iface,
193 nsIIDRef riid, void **result)
194 {
195 if(IsEqualGUID(&IID_nsISupports, riid)) {
196 TRACE("(IID_nsISupports %p)\n", result);
197 *result = iface;
198 }else if(IsEqualGUID(&IID_nsIDirectoryServiceProvider, riid)) {
199 TRACE("(IID_nsIDirectoryServiceProvider %p)\n", result);
200 *result = iface;
201 }else if(IsEqualGUID(&IID_nsIDirectoryServiceProvider2, riid)) {
202 TRACE("(IID_nsIDirectoryServiceProvider2 %p)\n", result);
203 *result = iface;
204 }else {
205 WARN("(%s %p)\n", debugstr_guid(riid), result);
206 *result = NULL;
207 return NS_NOINTERFACE;
208 }
209
210 nsISupports_AddRef((nsISupports*)*result);
211 return NS_OK;
212 }
213
nsDirectoryServiceProvider2_AddRef(nsIDirectoryServiceProvider2 * iface)214 static nsrefcnt NSAPI nsDirectoryServiceProvider2_AddRef(nsIDirectoryServiceProvider2 *iface)
215 {
216 return 2;
217 }
218
nsDirectoryServiceProvider2_Release(nsIDirectoryServiceProvider2 * iface)219 static nsrefcnt NSAPI nsDirectoryServiceProvider2_Release(nsIDirectoryServiceProvider2 *iface)
220 {
221 return 1;
222 }
223
create_profile_directory(void)224 static nsresult create_profile_directory(void)
225 {
226 static const WCHAR wine_geckoW[] = {'\\','w','i','n','e','_','g','e','c','k','o',0};
227
228 WCHAR path[MAX_PATH + sizeof(wine_geckoW)/sizeof(WCHAR)];
229 cpp_bool exists;
230 nsresult nsres;
231 HRESULT hres;
232
233 hres = SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, path);
234 if(FAILED(hres)) {
235 ERR("SHGetFolderPath failed: %08x\n", hres);
236 return NS_ERROR_FAILURE;
237 }
238
239 strcatW(path, wine_geckoW);
240 nsres = create_nsfile(path, &profile_directory);
241 if(NS_FAILED(nsres))
242 return nsres;
243
244 nsres = nsIFile_Exists(profile_directory, &exists);
245 if(NS_FAILED(nsres)) {
246 ERR("Exists failed: %08x\n", nsres);
247 return nsres;
248 }
249
250 if(!exists) {
251 nsres = nsIFile_Create(profile_directory, 1, 0700);
252 if(NS_FAILED(nsres))
253 ERR("Create failed: %08x\n", nsres);
254 }
255
256 return nsres;
257 }
258
nsDirectoryServiceProvider2_GetFile(nsIDirectoryServiceProvider2 * iface,const char * prop,cpp_bool * persistent,nsIFile ** _retval)259 static nsresult NSAPI nsDirectoryServiceProvider2_GetFile(nsIDirectoryServiceProvider2 *iface,
260 const char *prop, cpp_bool *persistent, nsIFile **_retval)
261 {
262 TRACE("(%s %p %p)\n", debugstr_a(prop), persistent, _retval);
263
264 if(!strcmp(prop, "ProfD")) {
265 if(!profile_directory) {
266 nsresult nsres;
267
268 nsres = create_profile_directory();
269 if(NS_FAILED(nsres))
270 return nsres;
271 }
272
273 assert(profile_directory != NULL);
274 return nsIFile_Clone(profile_directory, _retval);
275 }
276
277 *_retval = NULL;
278 return NS_ERROR_FAILURE;
279 }
280
nsDirectoryServiceProvider2_GetFiles(nsIDirectoryServiceProvider2 * iface,const char * prop,nsISimpleEnumerator ** _retval)281 static nsresult NSAPI nsDirectoryServiceProvider2_GetFiles(nsIDirectoryServiceProvider2 *iface,
282 const char *prop, nsISimpleEnumerator **_retval)
283 {
284 TRACE("(%s %p)\n", debugstr_a(prop), _retval);
285
286 if(!strcmp(prop, "APluginsDL")) {
287 WCHAR plugin_path[MAX_PATH];
288 nsIFile *file;
289 int len;
290 nsresult nsres;
291
292 if(!plugin_directory) {
293 static const WCHAR gecko_pluginW[] = {'\\','g','e','c','k','o','\\','p','l','u','g','i','n',0};
294
295 len = GetSystemDirectoryW(plugin_path, (sizeof(plugin_path)-sizeof(gecko_pluginW))/sizeof(WCHAR)+1);
296 if(!len)
297 return NS_ERROR_UNEXPECTED;
298
299 strcpyW(plugin_path+len, gecko_pluginW);
300 nsres = create_nsfile(plugin_path, &plugin_directory);
301 if(NS_FAILED(nsres)) {
302 *_retval = NULL;
303 return nsres;
304 }
305 }
306
307 nsres = nsIFile_Clone(plugin_directory, &file);
308 if(NS_FAILED(nsres))
309 return nsres;
310
311 *_retval = create_singleton_enumerator((nsISupports*)file);
312 nsIFile_Release(file);
313 if(!*_retval)
314 return NS_ERROR_OUT_OF_MEMORY;
315
316 return NS_OK;
317 }
318
319 *_retval = NULL;
320 return NS_ERROR_FAILURE;
321 }
322
323 static const nsIDirectoryServiceProvider2Vtbl nsDirectoryServiceProvider2Vtbl = {
324 nsDirectoryServiceProvider2_QueryInterface,
325 nsDirectoryServiceProvider2_AddRef,
326 nsDirectoryServiceProvider2_Release,
327 nsDirectoryServiceProvider2_GetFile,
328 nsDirectoryServiceProvider2_GetFiles
329 };
330
331 static nsIDirectoryServiceProvider2 nsDirectoryServiceProvider2 =
332 { &nsDirectoryServiceProvider2Vtbl };
333
nsembed_proc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)334 static LRESULT WINAPI nsembed_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
335 {
336 NSContainer *This;
337 nsresult nsres;
338
339 static const WCHAR wszTHIS[] = {'T','H','I','S',0};
340
341 if(msg == WM_CREATE) {
342 This = *(NSContainer**)lParam;
343 SetPropW(hwnd, wszTHIS, This);
344 }else {
345 This = GetPropW(hwnd, wszTHIS);
346 }
347
348 switch(msg) {
349 case WM_SIZE:
350 TRACE("(%p)->(WM_SIZE)\n", This);
351
352 nsres = nsIBaseWindow_SetSize(This->window,
353 LOWORD(lParam), HIWORD(lParam), TRUE);
354 if(NS_FAILED(nsres))
355 WARN("SetSize failed: %08x\n", nsres);
356 break;
357
358 case WM_PARENTNOTIFY:
359 TRACE("WM_PARENTNOTIFY %x\n", (unsigned)wParam);
360
361 switch(wParam) {
362 case WM_LBUTTONDOWN:
363 case WM_RBUTTONDOWN:
364 nsIWebBrowserFocus_Activate(This->focus);
365 }
366 }
367
368 return DefWindowProcW(hwnd, msg, wParam, lParam);
369 }
370
371
register_nscontainer_class(void)372 static void register_nscontainer_class(void)
373 {
374 static WNDCLASSEXW wndclass = {
375 sizeof(WNDCLASSEXW),
376 CS_DBLCLKS,
377 nsembed_proc,
378 0, 0, NULL, NULL, NULL, NULL, NULL,
379 wszNsContainer,
380 NULL,
381 };
382 wndclass.hInstance = hInst;
383 nscontainer_class = RegisterClassExW(&wndclass);
384 }
385
386 #ifndef __REACTOS__
install_wine_gecko(void)387 static BOOL install_wine_gecko(void)
388 {
389 PROCESS_INFORMATION pi;
390 STARTUPINFOW si;
391 WCHAR app[MAX_PATH];
392 WCHAR *args;
393 LONG len;
394 BOOL ret;
395
396 static const WCHAR controlW[] = {'\\','c','o','n','t','r','o','l','.','e','x','e',0};
397 static const WCHAR argsW[] =
398 {' ','a','p','p','w','i','z','.','c','p','l',' ','i','n','s','t','a','l','l','_','g','e','c','k','o',0};
399
400 len = GetSystemDirectoryW(app, MAX_PATH-sizeof(controlW)/sizeof(WCHAR));
401 memcpy(app+len, controlW, sizeof(controlW));
402
403 args = heap_alloc(len*sizeof(WCHAR) + sizeof(controlW) + sizeof(argsW));
404 if(!args)
405 return FALSE;
406
407 memcpy(args, app, len*sizeof(WCHAR) + sizeof(controlW));
408 memcpy(args + len + sizeof(controlW)/sizeof(WCHAR)-1, argsW, sizeof(argsW));
409
410 TRACE("starting %s\n", debugstr_w(args));
411
412 memset(&si, 0, sizeof(si));
413 si.cb = sizeof(si);
414 ret = CreateProcessW(app, args, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
415 heap_free(args);
416 if (ret) {
417 CloseHandle(pi.hThread);
418 WaitForSingleObject(pi.hProcess, INFINITE);
419 CloseHandle(pi.hProcess);
420 }
421
422 return ret;
423 }
424 #endif
425
set_environment(LPCWSTR gre_path)426 static void set_environment(LPCWSTR gre_path)
427 {
428 size_t len, gre_path_len;
429 int debug_level = 0;
430 WCHAR *path, buf[20];
431 const WCHAR *ptr;
432
433 static const WCHAR pathW[] = {'P','A','T','H',0};
434 static const WCHAR warnW[] = {'w','a','r','n',0};
435 static const WCHAR xpcom_debug_breakW[] =
436 {'X','P','C','O','M','_','D','E','B','U','G','_','B','R','E','A','K',0};
437 static const WCHAR nspr_log_modulesW[] =
438 {'N','S','P','R','_','L','O','G','_','M','O','D','U','L','E','S',0};
439 static const WCHAR debug_formatW[] = {'a','l','l',':','%','d',0};
440
441 SetEnvironmentVariableW(xpcom_debug_breakW, warnW);
442
443 if(TRACE_ON(gecko))
444 debug_level = 5;
445 else if(WARN_ON(gecko))
446 debug_level = 3;
447 else if(ERR_ON(gecko))
448 debug_level = 2;
449
450 sprintfW(buf, debug_formatW, debug_level);
451 SetEnvironmentVariableW(nspr_log_modulesW, buf);
452
453 len = GetEnvironmentVariableW(pathW, NULL, 0);
454 gre_path_len = strlenW(gre_path);
455 path = heap_alloc((len+gre_path_len+1)*sizeof(WCHAR));
456 if(!path)
457 return;
458 GetEnvironmentVariableW(pathW, path, len);
459
460 /* We have to modify PATH as xul.dll loads other DLLs from this directory. */
461 if(!(ptr = strstrW(path, gre_path))
462 || (ptr > path && *(ptr-1) != ';')
463 || (ptr[gre_path_len] && ptr[gre_path_len] != ';')) {
464 if(len)
465 path[len-1] = ';';
466 strcpyW(path+len, gre_path);
467 SetEnvironmentVariableW(pathW, path);
468 }
469 heap_free(path);
470 }
471
load_xul(const PRUnichar * gre_path)472 static BOOL load_xul(const PRUnichar *gre_path)
473 {
474 static const WCHAR xul_dllW[] = {'\\','x','u','l','.','d','l','l',0};
475 WCHAR file_name[MAX_PATH];
476
477 strcpyW(file_name, gre_path);
478 strcatW(file_name, xul_dllW);
479
480 TRACE("(%s)\n", debugstr_w(file_name));
481
482 set_environment(gre_path);
483
484 xul_handle = LoadLibraryExW(file_name, 0, LOAD_WITH_ALTERED_SEARCH_PATH);
485 if(!xul_handle) {
486 WARN("Could not load XUL: %d\n", GetLastError());
487 return FALSE;
488 }
489
490 #define NS_DLSYM(func) \
491 func = (void *)GetProcAddress(xul_handle, #func); \
492 if(!func) \
493 ERR("Could not GetProcAddress(" #func ") failed\n")
494
495 NS_DLSYM(NS_InitXPCOM2);
496 NS_DLSYM(NS_ShutdownXPCOM);
497 NS_DLSYM(NS_GetComponentRegistrar);
498 NS_DLSYM(NS_StringContainerInit2);
499 NS_DLSYM(NS_CStringContainerInit2);
500 NS_DLSYM(NS_StringContainerFinish);
501 NS_DLSYM(NS_CStringContainerFinish);
502 NS_DLSYM(NS_StringSetData);
503 NS_DLSYM(NS_CStringSetData);
504 NS_DLSYM(NS_NewLocalFile);
505 NS_DLSYM(NS_StringGetData);
506 NS_DLSYM(NS_CStringGetData);
507 NS_DLSYM(NS_Alloc);
508 NS_DLSYM(NS_Free);
509 NS_DLSYM(ccref_incr);
510 NS_DLSYM(ccref_decr);
511 NS_DLSYM(ccref_init);
512 NS_DLSYM(ccp_init);
513 NS_DLSYM(describe_cc_node);
514 NS_DLSYM(note_cc_edge);
515
516 #undef NS_DLSYM
517
518 return TRUE;
519 }
520
check_version(LPCWSTR gre_path,const char * version_string)521 static BOOL check_version(LPCWSTR gre_path, const char *version_string)
522 {
523 WCHAR file_name[MAX_PATH];
524 char version[128];
525 DWORD read=0;
526 HANDLE hfile;
527
528 static const WCHAR wszVersion[] = {'\\','V','E','R','S','I','O','N',0};
529
530 strcpyW(file_name, gre_path);
531 strcatW(file_name, wszVersion);
532
533 hfile = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ, NULL,
534 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
535 if(hfile == INVALID_HANDLE_VALUE) {
536 ERR("Could not open VERSION file\n");
537 return FALSE;
538 }
539
540 ReadFile(hfile, version, sizeof(version), &read, NULL);
541 version[read] = 0;
542 CloseHandle(hfile);
543
544 TRACE("%s\n", debugstr_a(version));
545
546 if(strcmp(version, version_string)) {
547 ERR("Unexpected version %s, expected %s\n", debugstr_a(version),
548 debugstr_a(version_string));
549 return FALSE;
550 }
551
552 return TRUE;
553 }
554
load_wine_gecko_v(PRUnichar * gre_path,HKEY mshtml_key,const char * version,const char * version_string)555 static BOOL load_wine_gecko_v(PRUnichar *gre_path, HKEY mshtml_key,
556 const char *version, const char *version_string)
557 {
558 DWORD res, type, size = MAX_PATH;
559 HKEY hkey = mshtml_key;
560
561 static const WCHAR wszGeckoPath[] =
562 {'G','e','c','k','o','P','a','t','h',0};
563
564 if(version) {
565 /* @@ Wine registry key: HKLM\Software\Wine\MSHTML\<version> */
566 res = RegOpenKeyA(mshtml_key, version, &hkey);
567 if(res != ERROR_SUCCESS)
568 return FALSE;
569 }
570
571 res = RegQueryValueExW(hkey, wszGeckoPath, NULL, &type, (LPBYTE)gre_path, &size);
572 if(hkey != mshtml_key)
573 RegCloseKey(hkey);
574 if(res != ERROR_SUCCESS || type != REG_SZ)
575 return FALSE;
576
577 if(!check_version(gre_path, version_string))
578 return FALSE;
579
580 return load_xul(gre_path);
581 }
582
load_wine_gecko(PRUnichar * gre_path)583 static BOOL load_wine_gecko(PRUnichar *gre_path)
584 {
585 HKEY hkey;
586 DWORD res;
587 BOOL ret;
588
589 static const WCHAR wszMshtmlKey[] = {
590 'S','o','f','t','w','a','r','e','\\','W','i','n','e',
591 '\\','M','S','H','T','M','L',0};
592
593 /* @@ Wine registry key: HKLM\Software\Wine\MSHTML */
594 res = RegOpenKeyW(HKEY_LOCAL_MACHINE, wszMshtmlKey, &hkey);
595 if(res != ERROR_SUCCESS)
596 return FALSE;
597
598 ret = load_wine_gecko_v(gre_path, hkey, GECKO_VERSION, GECKO_VERSION_STRING);
599
600 RegCloseKey(hkey);
601 return ret;
602 }
603
set_bool_pref(nsIPrefBranch * pref,const char * pref_name,BOOL val)604 static void set_bool_pref(nsIPrefBranch *pref, const char *pref_name, BOOL val)
605 {
606 nsresult nsres;
607
608 nsres = nsIPrefBranch_SetBoolPref(pref, pref_name, val);
609 if(NS_FAILED(nsres))
610 ERR("Could not set pref %s\n", debugstr_a(pref_name));
611 }
612
set_int_pref(nsIPrefBranch * pref,const char * pref_name,int val)613 static void set_int_pref(nsIPrefBranch *pref, const char *pref_name, int val)
614 {
615 nsresult nsres;
616
617 nsres = nsIPrefBranch_SetIntPref(pref, pref_name, val);
618 if(NS_FAILED(nsres))
619 ERR("Could not set pref %s\n", debugstr_a(pref_name));
620 }
621
set_string_pref(nsIPrefBranch * pref,const char * pref_name,const char * val)622 static void set_string_pref(nsIPrefBranch *pref, const char *pref_name, const char *val)
623 {
624 nsresult nsres;
625
626 nsres = nsIPrefBranch_SetCharPref(pref, pref_name, val);
627 if(NS_FAILED(nsres))
628 ERR("Could not set pref %s\n", debugstr_a(pref_name));
629 }
630
set_lang(nsIPrefBranch * pref)631 static void set_lang(nsIPrefBranch *pref)
632 {
633 char langs[100];
634 DWORD res, size, type;
635 HKEY hkey;
636
637 static const WCHAR international_keyW[] =
638 {'S','o','f','t','w','a','r','e',
639 '\\','M','i','c','r','o','s','o','f','t',
640 '\\','I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r',
641 '\\','I','n','t','e','r','n','a','t','i','o','n','a','l',0};
642
643 res = RegOpenKeyW(HKEY_CURRENT_USER, international_keyW, &hkey);
644 if(res != ERROR_SUCCESS)
645 return;
646
647 size = sizeof(langs);
648 res = RegQueryValueExA(hkey, "AcceptLanguage", 0, &type, (LPBYTE)langs, &size);
649 RegCloseKey(hkey);
650 if(res != ERROR_SUCCESS || type != REG_SZ)
651 return;
652
653 TRACE("Setting lang %s\n", debugstr_a(langs));
654
655 set_string_pref(pref, "intl.accept_languages", langs);
656 }
657
set_preferences(void)658 static void set_preferences(void)
659 {
660 nsIPrefBranch *pref;
661 nsresult nsres;
662
663 nsres = nsIServiceManager_GetServiceByContractID(pServMgr, NS_PREFERENCES_CONTRACTID,
664 &IID_nsIPrefBranch, (void**)&pref);
665 if(NS_FAILED(nsres)) {
666 ERR("Could not get preference service: %08x\n", nsres);
667 return;
668 }
669
670 set_lang(pref);
671 set_bool_pref(pref, "security.warn_entering_secure", FALSE);
672 set_bool_pref(pref, "security.warn_submit_insecure", FALSE);
673 set_int_pref(pref, "layout.spellcheckDefault", 0);
674
675 nsIPrefBranch_Release(pref);
676 }
677
init_xpcom(const PRUnichar * gre_path)678 static BOOL init_xpcom(const PRUnichar *gre_path)
679 {
680 nsIComponentRegistrar *registrar = NULL;
681 nsIFile *gre_dir;
682 WCHAR *ptr;
683 nsresult nsres;
684
685 nsres = create_nsfile(gre_path, &gre_dir);
686 if(NS_FAILED(nsres)) {
687 FreeLibrary(xul_handle);
688 return FALSE;
689 }
690
691 nsres = NS_InitXPCOM2(&pServMgr, gre_dir, (nsIDirectoryServiceProvider*)&nsDirectoryServiceProvider2);
692 if(NS_FAILED(nsres)) {
693 ERR("NS_InitXPCOM2 failed: %08x\n", nsres);
694 FreeLibrary(xul_handle);
695 return FALSE;
696 }
697
698 strcpyW(gecko_path, gre_path);
699 for(ptr = gecko_path; *ptr; ptr++) {
700 if(*ptr == '\\')
701 *ptr = '/';
702 }
703 gecko_path_len = ptr-gecko_path;
704
705 nsres = nsIServiceManager_QueryInterface(pServMgr, &IID_nsIComponentManager, (void**)&pCompMgr);
706 if(NS_FAILED(nsres))
707 ERR("Could not get nsIComponentManager: %08x\n", nsres);
708
709 nsres = NS_GetComponentRegistrar(®istrar);
710 if(NS_SUCCEEDED(nsres))
711 init_nsio(pCompMgr, registrar);
712 else
713 ERR("NS_GetComponentRegistrar failed: %08x\n", nsres);
714
715 init_mutation(pCompMgr);
716 set_preferences();
717
718 nsres = nsIServiceManager_GetServiceByContractID(pServMgr, NS_CATEGORYMANAGER_CONTRACTID,
719 &IID_nsICategoryManager, (void**)&cat_mgr);
720 if(NS_FAILED(nsres))
721 ERR("Could not get category manager service: %08x\n", nsres);
722
723 if(registrar) {
724 register_nsservice(registrar, pServMgr);
725 nsIComponentRegistrar_Release(registrar);
726 }
727
728 init_node_cc();
729
730 return TRUE;
731 }
732
733 static CRITICAL_SECTION cs_load_gecko;
734 static CRITICAL_SECTION_DEBUG cs_load_gecko_dbg =
735 {
736 0, 0, &cs_load_gecko,
737 { &cs_load_gecko_dbg.ProcessLocksList, &cs_load_gecko_dbg.ProcessLocksList },
738 0, 0, { (DWORD_PTR)(__FILE__ ": load_gecko") }
739 };
740 static CRITICAL_SECTION cs_load_gecko = { &cs_load_gecko_dbg, -1, 0, 0, 0, 0 };
741
load_gecko(void)742 BOOL load_gecko(void)
743 {
744 PRUnichar gre_path[MAX_PATH];
745 BOOL ret = FALSE;
746
747 static DWORD loading_thread;
748
749 TRACE("()\n");
750
751 /* load_gecko may be called recursively */
752 if(loading_thread == GetCurrentThreadId())
753 return pCompMgr != NULL;
754
755 EnterCriticalSection(&cs_load_gecko);
756
757 if(!loading_thread) {
758 loading_thread = GetCurrentThreadId();
759
760 #ifdef __REACTOS__
761 if(load_wine_gecko(gre_path))
762 #else
763 if(load_wine_gecko(gre_path)
764 || (install_wine_gecko() && load_wine_gecko(gre_path)))
765 #endif
766 ret = init_xpcom(gre_path);
767 else
768 MESSAGE("Could not load wine-gecko. HTML rendering will be disabled.\n");
769 }else {
770 ret = pCompMgr != NULL;
771 }
772
773 LeaveCriticalSection(&cs_load_gecko);
774
775 return ret;
776 }
777
nsalloc(size_t size)778 void *nsalloc(size_t size)
779 {
780 return NS_Alloc(size);
781 }
782
nsfree(void * mem)783 void nsfree(void *mem)
784 {
785 NS_Free(mem);
786 }
787
nsACString_Init(nsACString * str,const char * data)788 BOOL nsACString_Init(nsACString *str, const char *data)
789 {
790 return NS_SUCCEEDED(NS_CStringContainerInit2(str, data, PR_UINT32_MAX, 0));
791 }
792
793 /*
794 * Initializes nsACString with data owned by caller.
795 * Caller must ensure that data is valid during lifetime of string object.
796 */
nsACString_InitDepend(nsACString * str,const char * data)797 void nsACString_InitDepend(nsACString *str, const char *data)
798 {
799 NS_CStringContainerInit2(str, data, PR_UINT32_MAX, NS_CSTRING_CONTAINER_INIT_DEPEND);
800 }
801
nsACString_SetData(nsACString * str,const char * data)802 void nsACString_SetData(nsACString *str, const char *data)
803 {
804 NS_CStringSetData(str, data, PR_UINT32_MAX);
805 }
806
nsACString_GetData(const nsACString * str,const char ** data)807 UINT32 nsACString_GetData(const nsACString *str, const char **data)
808 {
809 return NS_CStringGetData(str, data, NULL);
810 }
811
nsACString_Finish(nsACString * str)812 void nsACString_Finish(nsACString *str)
813 {
814 NS_CStringContainerFinish(str);
815 }
816
nsAString_Init(nsAString * str,const PRUnichar * data)817 BOOL nsAString_Init(nsAString *str, const PRUnichar *data)
818 {
819 return NS_SUCCEEDED(NS_StringContainerInit2(str, data, PR_UINT32_MAX, 0));
820 }
821
822 /*
823 * Initializes nsAString with data owned by caller.
824 * Caller must ensure that data is valid during lifetime of string object.
825 */
nsAString_InitDepend(nsAString * str,const PRUnichar * data)826 void nsAString_InitDepend(nsAString *str, const PRUnichar *data)
827 {
828 NS_StringContainerInit2(str, data, PR_UINT32_MAX, NS_STRING_CONTAINER_INIT_DEPEND);
829 }
830
nsAString_GetData(const nsAString * str,const PRUnichar ** data)831 UINT32 nsAString_GetData(const nsAString *str, const PRUnichar **data)
832 {
833 return NS_StringGetData(str, data, NULL);
834 }
835
nsAString_Finish(nsAString * str)836 void nsAString_Finish(nsAString *str)
837 {
838 NS_StringContainerFinish(str);
839 }
840
return_nsstr(nsresult nsres,nsAString * nsstr,BSTR * p)841 HRESULT return_nsstr(nsresult nsres, nsAString *nsstr, BSTR *p)
842 {
843 const PRUnichar *str;
844
845 if(NS_FAILED(nsres)) {
846 ERR("failed: %08x\n", nsres);
847 nsAString_Finish(nsstr);
848 return E_FAIL;
849 }
850
851 nsAString_GetData(nsstr, &str);
852 TRACE("ret %s\n", debugstr_w(str));
853 if(*str) {
854 *p = SysAllocString(str);
855 if(!*p)
856 return E_OUTOFMEMORY;
857 }else {
858 *p = NULL;
859 }
860
861 nsAString_Finish(nsstr);
862 return S_OK;
863 }
864
create_nscommand_params(void)865 nsICommandParams *create_nscommand_params(void)
866 {
867 nsICommandParams *ret = NULL;
868 nsresult nsres;
869
870 if(!pCompMgr)
871 return NULL;
872
873 nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr,
874 NS_COMMANDPARAMS_CONTRACTID, NULL, &IID_nsICommandParams,
875 (void**)&ret);
876 if(NS_FAILED(nsres))
877 ERR("Could not get nsICommandParams\n");
878
879 return ret;
880 }
881
create_nsvariant(void)882 nsIWritableVariant *create_nsvariant(void)
883 {
884 nsIWritableVariant *ret = NULL;
885 nsresult nsres;
886
887 if(!pCompMgr)
888 return NULL;
889
890 nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr,
891 NS_VARIANT_CONTRACTID, NULL, &IID_nsIWritableVariant, (void**)&ret);
892 if(NS_FAILED(nsres))
893 ERR("Could not get nsIVariant\n");
894
895 return ret;
896 }
897
get_nscategory_entry(const char * category,const char * entry)898 char *get_nscategory_entry(const char *category, const char *entry)
899 {
900 char *ret = NULL;
901 nsresult nsres;
902
903 nsres = nsICategoryManager_GetCategoryEntry(cat_mgr, category, entry, &ret);
904 return NS_SUCCEEDED(nsres) ? ret : NULL;
905 }
906
get_nsinterface(nsISupports * iface,REFIID riid,void ** ppv)907 nsresult get_nsinterface(nsISupports *iface, REFIID riid, void **ppv)
908 {
909 nsIInterfaceRequestor *iface_req;
910 nsresult nsres;
911
912 nsres = nsISupports_QueryInterface(iface, &IID_nsIInterfaceRequestor, (void**)&iface_req);
913 if(NS_FAILED(nsres))
914 return nsres;
915
916 nsres = nsIInterfaceRequestor_GetInterface(iface_req, riid, ppv);
917 nsIInterfaceRequestor_Release(iface_req);
918
919 return nsres;
920 }
921
nsnode_to_nsstring_rec(nsIContentSerializer * serializer,nsIDOMNode * nsnode,nsAString * str)922 static HRESULT nsnode_to_nsstring_rec(nsIContentSerializer *serializer, nsIDOMNode *nsnode, nsAString *str)
923 {
924 nsIDOMNodeList *node_list = NULL;
925 cpp_bool has_children = FALSE;
926 nsIContent *nscontent;
927 UINT16 type;
928 nsresult nsres;
929
930 nsIDOMNode_HasChildNodes(nsnode, &has_children);
931
932 nsres = nsIDOMNode_GetNodeType(nsnode, &type);
933 if(NS_FAILED(nsres)) {
934 ERR("GetType failed: %08x\n", nsres);
935 return E_FAIL;
936 }
937
938 if(type != DOCUMENT_NODE) {
939 nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIContent, (void**)&nscontent);
940 if(NS_FAILED(nsres)) {
941 ERR("Could not get nsIContent interface: %08x\n", nsres);
942 return E_FAIL;
943 }
944 }
945
946 switch(type) {
947 case ELEMENT_NODE:
948 nsIContentSerializer_AppendElementStart(serializer, nscontent, nscontent, str);
949 break;
950 case TEXT_NODE:
951 nsIContentSerializer_AppendText(serializer, nscontent, 0, -1, str);
952 break;
953 case COMMENT_NODE:
954 nsres = nsIContentSerializer_AppendComment(serializer, nscontent, 0, -1, str);
955 break;
956 case DOCUMENT_NODE: {
957 nsIDocument *nsdoc;
958 nsIDOMNode_QueryInterface(nsnode, &IID_nsIDocument, (void**)&nsdoc);
959 nsIContentSerializer_AppendDocumentStart(serializer, nsdoc, str);
960 nsIDocument_Release(nsdoc);
961 break;
962 }
963 case DOCUMENT_TYPE_NODE:
964 nsIContentSerializer_AppendDoctype(serializer, nscontent, str);
965 break;
966 case DOCUMENT_FRAGMENT_NODE:
967 break;
968 default:
969 FIXME("Unhandled type %u\n", type);
970 }
971
972 if(has_children) {
973 UINT32 child_cnt, i;
974 nsIDOMNode *child_node;
975
976 nsIDOMNode_GetChildNodes(nsnode, &node_list);
977 nsIDOMNodeList_GetLength(node_list, &child_cnt);
978
979 for(i=0; i<child_cnt; i++) {
980 nsres = nsIDOMNodeList_Item(node_list, i, &child_node);
981 if(NS_SUCCEEDED(nsres)) {
982 nsnode_to_nsstring_rec(serializer, child_node, str);
983 nsIDOMNode_Release(child_node);
984 }else {
985 ERR("Item failed: %08x\n", nsres);
986 }
987 }
988
989 nsIDOMNodeList_Release(node_list);
990 }
991
992 if(type == ELEMENT_NODE)
993 nsIContentSerializer_AppendElementEnd(serializer, nscontent, str);
994
995 if(type != DOCUMENT_NODE)
996 nsIContent_Release(nscontent);
997 return S_OK;
998 }
999
nsnode_to_nsstring(nsIDOMNode * nsnode,nsAString * str)1000 HRESULT nsnode_to_nsstring(nsIDOMNode *nsnode, nsAString *str)
1001 {
1002 nsIContentSerializer *serializer;
1003 nsresult nsres;
1004 HRESULT hres;
1005
1006 nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr,
1007 NS_HTMLSERIALIZER_CONTRACTID, NULL, &IID_nsIContentSerializer,
1008 (void**)&serializer);
1009 if(NS_FAILED(nsres)) {
1010 ERR("Could not get nsIContentSerializer: %08x\n", nsres);
1011 return E_FAIL;
1012 }
1013
1014 nsres = nsIContentSerializer_Init(serializer, 0, 100, NULL, FALSE, FALSE /* FIXME */);
1015 if(NS_FAILED(nsres))
1016 ERR("Init failed: %08x\n", nsres);
1017
1018 hres = nsnode_to_nsstring_rec(serializer, nsnode, str);
1019 if(SUCCEEDED(hres)) {
1020 nsres = nsIContentSerializer_Flush(serializer, str);
1021 if(NS_FAILED(nsres))
1022 ERR("Flush failed: %08x\n", nsres);
1023 }
1024
1025 nsIContentSerializer_Release(serializer);
1026 return hres;
1027 }
1028
get_editor_controller(NSContainer * This)1029 void get_editor_controller(NSContainer *This)
1030 {
1031 nsIEditingSession *editing_session = NULL;
1032 nsIControllerContext *ctrlctx;
1033 nsresult nsres;
1034
1035 if(This->editor) {
1036 nsIEditor_Release(This->editor);
1037 This->editor = NULL;
1038 }
1039
1040 if(This->editor_controller) {
1041 nsIController_Release(This->editor_controller);
1042 This->editor_controller = NULL;
1043 }
1044
1045 nsres = get_nsinterface((nsISupports*)This->webbrowser, &IID_nsIEditingSession,
1046 (void**)&editing_session);
1047 if(NS_FAILED(nsres)) {
1048 ERR("Could not get nsIEditingSession: %08x\n", nsres);
1049 return;
1050 }
1051
1052 nsres = nsIEditingSession_GetEditorForWindow(editing_session,
1053 This->doc->basedoc.window->nswindow, &This->editor);
1054 nsIEditingSession_Release(editing_session);
1055 if(NS_FAILED(nsres)) {
1056 ERR("Could not get editor: %08x\n", nsres);
1057 return;
1058 }
1059
1060 nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr,
1061 NS_EDITORCONTROLLER_CONTRACTID, NULL, &IID_nsIControllerContext, (void**)&ctrlctx);
1062 if(NS_SUCCEEDED(nsres)) {
1063 nsres = nsIControllerContext_SetCommandContext(ctrlctx, (nsISupports *)This->editor);
1064 if(NS_FAILED(nsres))
1065 ERR("SetCommandContext failed: %08x\n", nsres);
1066 nsres = nsIControllerContext_QueryInterface(ctrlctx, &IID_nsIController,
1067 (void**)&This->editor_controller);
1068 nsIControllerContext_Release(ctrlctx);
1069 if(NS_FAILED(nsres))
1070 ERR("Could not get nsIController interface: %08x\n", nsres);
1071 }else {
1072 ERR("Could not create edit controller: %08x\n", nsres);
1073 }
1074 }
1075
close_gecko(void)1076 void close_gecko(void)
1077 {
1078 TRACE("()\n");
1079
1080 release_nsio();
1081 init_mutation(NULL);
1082
1083 if(profile_directory) {
1084 nsIFile_Release(profile_directory);
1085 profile_directory = NULL;
1086 }
1087
1088 if(plugin_directory) {
1089 nsIFile_Release(plugin_directory);
1090 plugin_directory = NULL;
1091 }
1092
1093 if(pCompMgr)
1094 nsIComponentManager_Release(pCompMgr);
1095
1096 if(pServMgr)
1097 nsIServiceManager_Release(pServMgr);
1098
1099 if(cat_mgr)
1100 nsICategoryManager_Release(cat_mgr);
1101
1102 /* Gecko doesn't really support being unloaded */
1103 /* if (hXPCOM) FreeLibrary(hXPCOM); */
1104
1105 DeleteCriticalSection(&cs_load_gecko);
1106 }
1107
is_gecko_path(const char * path)1108 BOOL is_gecko_path(const char *path)
1109 {
1110 WCHAR *buf, *ptr;
1111 BOOL ret;
1112
1113 buf = heap_strdupUtoW(path);
1114 if(!buf || strlenW(buf) < gecko_path_len)
1115 return FALSE;
1116
1117 for(ptr = buf; *ptr; ptr++) {
1118 if(*ptr == '\\')
1119 *ptr = '/';
1120 }
1121
1122 UrlUnescapeW(buf, NULL, NULL, URL_UNESCAPE_INPLACE);
1123 buf[gecko_path_len] = 0;
1124
1125 ret = !strcmpiW(buf, gecko_path);
1126 heap_free(buf);
1127 return ret;
1128 }
1129
set_viewer_zoom(NSContainer * nscontainer,float factor)1130 void set_viewer_zoom(NSContainer *nscontainer, float factor)
1131 {
1132 nsIContentViewer *content_viewer;
1133 nsIDocShell *doc_shell;
1134 nsresult nsres;
1135
1136 TRACE("Setting to %f\n", factor);
1137
1138 nsres = get_nsinterface((nsISupports*)nscontainer->navigation, &IID_nsIDocShell, (void**)&doc_shell);
1139 assert(nsres == NS_OK);
1140
1141 nsres = nsIDocShell_GetContentViewer(doc_shell, &content_viewer);
1142 assert(nsres == NS_OK && content_viewer);
1143 nsIDocShell_Release(doc_shell);
1144
1145 nsres = nsIContentViewer_SetFullZoom(content_viewer, factor);
1146 if(NS_FAILED(nsres))
1147 ERR("SetFullZoom failed: %08x\n", nsres);
1148
1149 nsIContentViewer_Release(content_viewer);
1150 }
1151
1152 struct nsWeakReference {
1153 nsIWeakReference nsIWeakReference_iface;
1154
1155 LONG ref;
1156
1157 NSContainer *nscontainer;
1158 };
1159
impl_from_nsIWeakReference(nsIWeakReference * iface)1160 static inline nsWeakReference *impl_from_nsIWeakReference(nsIWeakReference *iface)
1161 {
1162 return CONTAINING_RECORD(iface, nsWeakReference, nsIWeakReference_iface);
1163 }
1164
nsWeakReference_QueryInterface(nsIWeakReference * iface,nsIIDRef riid,void ** result)1165 static nsresult NSAPI nsWeakReference_QueryInterface(nsIWeakReference *iface,
1166 nsIIDRef riid, void **result)
1167 {
1168 nsWeakReference *This = impl_from_nsIWeakReference(iface);
1169
1170 if(IsEqualGUID(&IID_nsISupports, riid)) {
1171 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
1172 *result = &This->nsIWeakReference_iface;
1173 }else if(IsEqualGUID(&IID_nsIWeakReference, riid)) {
1174 TRACE("(%p)->(IID_nsIWeakReference %p)\n", This, result);
1175 *result = &This->nsIWeakReference_iface;
1176 }else {
1177 WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
1178 *result = NULL;
1179 return NS_NOINTERFACE;
1180 }
1181
1182 nsISupports_AddRef((nsISupports*)*result);
1183 return NS_OK;
1184 }
1185
nsWeakReference_AddRef(nsIWeakReference * iface)1186 static nsrefcnt NSAPI nsWeakReference_AddRef(nsIWeakReference *iface)
1187 {
1188 nsWeakReference *This = impl_from_nsIWeakReference(iface);
1189 LONG ref = InterlockedIncrement(&This->ref);
1190
1191 TRACE("(%p) ref=%d\n", This, ref);
1192
1193 return ref;
1194 }
1195
nsWeakReference_Release(nsIWeakReference * iface)1196 static nsrefcnt NSAPI nsWeakReference_Release(nsIWeakReference *iface)
1197 {
1198 nsWeakReference *This = impl_from_nsIWeakReference(iface);
1199 LONG ref = InterlockedIncrement(&This->ref);
1200
1201 TRACE("(%p) ref=%d\n", This, ref);
1202
1203 if(!ref) {
1204 assert(!This->nscontainer);
1205 heap_free(This);
1206 }
1207
1208 return ref;
1209 }
1210
nsWeakReference_QueryReferent(nsIWeakReference * iface,const nsIID * riid,void ** result)1211 static nsresult NSAPI nsWeakReference_QueryReferent(nsIWeakReference *iface,
1212 const nsIID *riid, void **result)
1213 {
1214 nsWeakReference *This = impl_from_nsIWeakReference(iface);
1215
1216 if(!This->nscontainer)
1217 return NS_ERROR_NULL_POINTER;
1218
1219 return nsIWebBrowserChrome_QueryInterface(&This->nscontainer->nsIWebBrowserChrome_iface, riid, result);
1220 }
1221
1222 static const nsIWeakReferenceVtbl nsWeakReferenceVtbl = {
1223 nsWeakReference_QueryInterface,
1224 nsWeakReference_AddRef,
1225 nsWeakReference_Release,
1226 nsWeakReference_QueryReferent
1227 };
1228
1229 /**********************************************************
1230 * nsIWebBrowserChrome interface
1231 */
1232
impl_from_nsIWebBrowserChrome(nsIWebBrowserChrome * iface)1233 static inline NSContainer *impl_from_nsIWebBrowserChrome(nsIWebBrowserChrome *iface)
1234 {
1235 return CONTAINING_RECORD(iface, NSContainer, nsIWebBrowserChrome_iface);
1236 }
1237
nsWebBrowserChrome_QueryInterface(nsIWebBrowserChrome * iface,nsIIDRef riid,void ** result)1238 static nsresult NSAPI nsWebBrowserChrome_QueryInterface(nsIWebBrowserChrome *iface,
1239 nsIIDRef riid, void **result)
1240 {
1241 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1242
1243 *result = NULL;
1244 if(IsEqualGUID(&IID_nsISupports, riid)) {
1245 TRACE("(%p)->(IID_nsISupports, %p)\n", This, result);
1246 *result = &This->nsIWebBrowserChrome_iface;
1247 }else if(IsEqualGUID(&IID_nsIWebBrowserChrome, riid)) {
1248 TRACE("(%p)->(IID_nsIWebBrowserChrome, %p)\n", This, result);
1249 *result = &This->nsIWebBrowserChrome_iface;
1250 }else if(IsEqualGUID(&IID_nsIContextMenuListener, riid)) {
1251 TRACE("(%p)->(IID_nsIContextMenuListener, %p)\n", This, result);
1252 *result = &This->nsIContextMenuListener_iface;
1253 }else if(IsEqualGUID(&IID_nsIURIContentListener, riid)) {
1254 TRACE("(%p)->(IID_nsIURIContentListener %p)\n", This, result);
1255 *result = &This->nsIURIContentListener_iface;
1256 }else if(IsEqualGUID(&IID_nsIEmbeddingSiteWindow, riid)) {
1257 TRACE("(%p)->(IID_nsIEmbeddingSiteWindow %p)\n", This, result);
1258 *result = &This->nsIEmbeddingSiteWindow_iface;
1259 }else if(IsEqualGUID(&IID_nsITooltipListener, riid)) {
1260 TRACE("(%p)->(IID_nsITooltipListener %p)\n", This, result);
1261 *result = &This->nsITooltipListener_iface;
1262 }else if(IsEqualGUID(&IID_nsIInterfaceRequestor, riid)) {
1263 TRACE("(%p)->(IID_nsIInterfaceRequestor %p)\n", This, result);
1264 *result = &This->nsIInterfaceRequestor_iface;
1265 }else if(IsEqualGUID(&IID_nsISupportsWeakReference, riid)) {
1266 TRACE("(%p)->(IID_nsISupportsWeakReference %p)\n", This, result);
1267 *result = &This->nsISupportsWeakReference_iface;
1268 }
1269
1270 if(*result) {
1271 nsIWebBrowserChrome_AddRef(&This->nsIWebBrowserChrome_iface);
1272 return NS_OK;
1273 }
1274
1275 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
1276 return NS_NOINTERFACE;
1277 }
1278
nsWebBrowserChrome_AddRef(nsIWebBrowserChrome * iface)1279 static nsrefcnt NSAPI nsWebBrowserChrome_AddRef(nsIWebBrowserChrome *iface)
1280 {
1281 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1282 LONG ref = InterlockedIncrement(&This->ref);
1283
1284 TRACE("(%p) ref=%d\n", This, ref);
1285
1286 return ref;
1287 }
1288
nsWebBrowserChrome_Release(nsIWebBrowserChrome * iface)1289 static nsrefcnt NSAPI nsWebBrowserChrome_Release(nsIWebBrowserChrome *iface)
1290 {
1291 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1292 LONG ref = InterlockedDecrement(&This->ref);
1293
1294 TRACE("(%p) ref=%d\n", This, ref);
1295
1296 if(!ref) {
1297 if(This->parent)
1298 nsIWebBrowserChrome_Release(&This->parent->nsIWebBrowserChrome_iface);
1299 if(This->weak_reference) {
1300 This->weak_reference->nscontainer = NULL;
1301 nsIWeakReference_Release(&This->weak_reference->nsIWeakReference_iface);
1302 }
1303 heap_free(This);
1304 }
1305
1306 return ref;
1307 }
1308
nsWebBrowserChrome_SetStatus(nsIWebBrowserChrome * iface,UINT32 statusType,const PRUnichar * status)1309 static nsresult NSAPI nsWebBrowserChrome_SetStatus(nsIWebBrowserChrome *iface,
1310 UINT32 statusType, const PRUnichar *status)
1311 {
1312 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1313 TRACE("(%p)->(%d %s)\n", This, statusType, debugstr_w(status));
1314 return NS_OK;
1315 }
1316
nsWebBrowserChrome_GetWebBrowser(nsIWebBrowserChrome * iface,nsIWebBrowser ** aWebBrowser)1317 static nsresult NSAPI nsWebBrowserChrome_GetWebBrowser(nsIWebBrowserChrome *iface,
1318 nsIWebBrowser **aWebBrowser)
1319 {
1320 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1321
1322 TRACE("(%p)->(%p)\n", This, aWebBrowser);
1323
1324 if(!aWebBrowser)
1325 return NS_ERROR_INVALID_ARG;
1326
1327 if(This->webbrowser)
1328 nsIWebBrowser_AddRef(This->webbrowser);
1329 *aWebBrowser = This->webbrowser;
1330 return S_OK;
1331 }
1332
nsWebBrowserChrome_SetWebBrowser(nsIWebBrowserChrome * iface,nsIWebBrowser * aWebBrowser)1333 static nsresult NSAPI nsWebBrowserChrome_SetWebBrowser(nsIWebBrowserChrome *iface,
1334 nsIWebBrowser *aWebBrowser)
1335 {
1336 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1337
1338 TRACE("(%p)->(%p)\n", This, aWebBrowser);
1339
1340 if(aWebBrowser != This->webbrowser)
1341 ERR("Wrong nsWebBrowser!\n");
1342
1343 return NS_OK;
1344 }
1345
nsWebBrowserChrome_GetChromeFlags(nsIWebBrowserChrome * iface,UINT32 * aChromeFlags)1346 static nsresult NSAPI nsWebBrowserChrome_GetChromeFlags(nsIWebBrowserChrome *iface,
1347 UINT32 *aChromeFlags)
1348 {
1349 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1350 WARN("(%p)->(%p)\n", This, aChromeFlags);
1351 return NS_ERROR_NOT_IMPLEMENTED;
1352 }
1353
nsWebBrowserChrome_SetChromeFlags(nsIWebBrowserChrome * iface,UINT32 aChromeFlags)1354 static nsresult NSAPI nsWebBrowserChrome_SetChromeFlags(nsIWebBrowserChrome *iface,
1355 UINT32 aChromeFlags)
1356 {
1357 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1358 WARN("(%p)->(%08x)\n", This, aChromeFlags);
1359 return NS_ERROR_NOT_IMPLEMENTED;
1360 }
1361
nsWebBrowserChrome_DestroyBrowserWindow(nsIWebBrowserChrome * iface)1362 static nsresult NSAPI nsWebBrowserChrome_DestroyBrowserWindow(nsIWebBrowserChrome *iface)
1363 {
1364 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1365 TRACE("(%p)\n", This);
1366 return NS_ERROR_NOT_IMPLEMENTED;
1367 }
1368
nsWebBrowserChrome_SizeBrowserTo(nsIWebBrowserChrome * iface,LONG aCX,LONG aCY)1369 static nsresult NSAPI nsWebBrowserChrome_SizeBrowserTo(nsIWebBrowserChrome *iface,
1370 LONG aCX, LONG aCY)
1371 {
1372 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1373 WARN("(%p)->(%d %d)\n", This, aCX, aCY);
1374 return NS_ERROR_NOT_IMPLEMENTED;
1375 }
1376
nsWebBrowserChrome_ShowAsModal(nsIWebBrowserChrome * iface)1377 static nsresult NSAPI nsWebBrowserChrome_ShowAsModal(nsIWebBrowserChrome *iface)
1378 {
1379 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1380 WARN("(%p)\n", This);
1381 return NS_ERROR_NOT_IMPLEMENTED;
1382 }
1383
nsWebBrowserChrome_IsWindowModal(nsIWebBrowserChrome * iface,cpp_bool * _retval)1384 static nsresult NSAPI nsWebBrowserChrome_IsWindowModal(nsIWebBrowserChrome *iface, cpp_bool *_retval)
1385 {
1386 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1387 WARN("(%p)->(%p)\n", This, _retval);
1388 return NS_ERROR_NOT_IMPLEMENTED;
1389 }
1390
nsWebBrowserChrome_ExitModalEventLoop(nsIWebBrowserChrome * iface,nsresult aStatus)1391 static nsresult NSAPI nsWebBrowserChrome_ExitModalEventLoop(nsIWebBrowserChrome *iface,
1392 nsresult aStatus)
1393 {
1394 NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
1395 WARN("(%p)->(%08x)\n", This, aStatus);
1396 return NS_ERROR_NOT_IMPLEMENTED;
1397 }
1398
1399 static const nsIWebBrowserChromeVtbl nsWebBrowserChromeVtbl = {
1400 nsWebBrowserChrome_QueryInterface,
1401 nsWebBrowserChrome_AddRef,
1402 nsWebBrowserChrome_Release,
1403 nsWebBrowserChrome_SetStatus,
1404 nsWebBrowserChrome_GetWebBrowser,
1405 nsWebBrowserChrome_SetWebBrowser,
1406 nsWebBrowserChrome_GetChromeFlags,
1407 nsWebBrowserChrome_SetChromeFlags,
1408 nsWebBrowserChrome_DestroyBrowserWindow,
1409 nsWebBrowserChrome_SizeBrowserTo,
1410 nsWebBrowserChrome_ShowAsModal,
1411 nsWebBrowserChrome_IsWindowModal,
1412 nsWebBrowserChrome_ExitModalEventLoop
1413 };
1414
1415 /**********************************************************
1416 * nsIContextMenuListener interface
1417 */
1418
impl_from_nsIContextMenuListener(nsIContextMenuListener * iface)1419 static inline NSContainer *impl_from_nsIContextMenuListener(nsIContextMenuListener *iface)
1420 {
1421 return CONTAINING_RECORD(iface, NSContainer, nsIContextMenuListener_iface);
1422 }
1423
nsContextMenuListener_QueryInterface(nsIContextMenuListener * iface,nsIIDRef riid,void ** result)1424 static nsresult NSAPI nsContextMenuListener_QueryInterface(nsIContextMenuListener *iface,
1425 nsIIDRef riid, void **result)
1426 {
1427 NSContainer *This = impl_from_nsIContextMenuListener(iface);
1428 return nsIWebBrowserChrome_QueryInterface(&This->nsIWebBrowserChrome_iface, riid, result);
1429 }
1430
nsContextMenuListener_AddRef(nsIContextMenuListener * iface)1431 static nsrefcnt NSAPI nsContextMenuListener_AddRef(nsIContextMenuListener *iface)
1432 {
1433 NSContainer *This = impl_from_nsIContextMenuListener(iface);
1434 return nsIWebBrowserChrome_AddRef(&This->nsIWebBrowserChrome_iface);
1435 }
1436
nsContextMenuListener_Release(nsIContextMenuListener * iface)1437 static nsrefcnt NSAPI nsContextMenuListener_Release(nsIContextMenuListener *iface)
1438 {
1439 NSContainer *This = impl_from_nsIContextMenuListener(iface);
1440 return nsIWebBrowserChrome_Release(&This->nsIWebBrowserChrome_iface);
1441 }
1442
nsContextMenuListener_OnShowContextMenu(nsIContextMenuListener * iface,UINT32 aContextFlags,nsIDOMEvent * aEvent,nsIDOMNode * aNode)1443 static nsresult NSAPI nsContextMenuListener_OnShowContextMenu(nsIContextMenuListener *iface,
1444 UINT32 aContextFlags, nsIDOMEvent *aEvent, nsIDOMNode *aNode)
1445 {
1446 NSContainer *This = impl_from_nsIContextMenuListener(iface);
1447 nsIDOMMouseEvent *event;
1448 HTMLDOMNode *node;
1449 POINT pt;
1450 DWORD dwID = CONTEXT_MENU_DEFAULT;
1451 nsresult nsres;
1452 HRESULT hres;
1453
1454 TRACE("(%p)->(%08x %p %p)\n", This, aContextFlags, aEvent, aNode);
1455
1456 fire_event(This->doc->basedoc.doc_node /* FIXME */, EVENTID_CONTEXTMENU, TRUE, aNode, aEvent, NULL);
1457
1458 nsres = nsIDOMEvent_QueryInterface(aEvent, &IID_nsIDOMMouseEvent, (void**)&event);
1459 if(NS_FAILED(nsres)) {
1460 ERR("Could not get nsIDOMMouseEvent interface: %08x\n", nsres);
1461 return nsres;
1462 }
1463
1464 nsIDOMMouseEvent_GetScreenX(event, &pt.x);
1465 nsIDOMMouseEvent_GetScreenY(event, &pt.y);
1466 nsIDOMMouseEvent_Release(event);
1467
1468 switch(aContextFlags) {
1469 case CONTEXT_NONE:
1470 case CONTEXT_DOCUMENT:
1471 case CONTEXT_TEXT: {
1472 nsISelection *selection;
1473
1474 nsres = nsIDOMHTMLDocument_GetSelection(This->doc->basedoc.doc_node->nsdoc, &selection);
1475 if(NS_SUCCEEDED(nsres) && selection) {
1476 cpp_bool is_collapsed;
1477
1478 /* FIXME: Check if the click was inside selection. */
1479 nsres = nsISelection_GetIsCollapsed(selection, &is_collapsed);
1480 nsISelection_Release(selection);
1481 if(NS_SUCCEEDED(nsres) && !is_collapsed)
1482 dwID = CONTEXT_MENU_TEXTSELECT;
1483 }
1484 break;
1485 }
1486 case CONTEXT_IMAGE:
1487 case CONTEXT_IMAGE|CONTEXT_LINK:
1488 dwID = CONTEXT_MENU_IMAGE;
1489 break;
1490 case CONTEXT_LINK:
1491 dwID = CONTEXT_MENU_ANCHOR;
1492 break;
1493 case CONTEXT_INPUT:
1494 dwID = CONTEXT_MENU_CONTROL;
1495 break;
1496 default:
1497 FIXME("aContextFlags=%08x\n", aContextFlags);
1498 };
1499
1500 hres = get_node(This->doc->basedoc.doc_node, aNode, TRUE, &node);
1501 if(FAILED(hres))
1502 return NS_ERROR_FAILURE;
1503
1504 show_context_menu(This->doc, dwID, &pt, (IDispatch*)&node->IHTMLDOMNode_iface);
1505 node_release(node);
1506 return NS_OK;
1507 }
1508
1509 static const nsIContextMenuListenerVtbl nsContextMenuListenerVtbl = {
1510 nsContextMenuListener_QueryInterface,
1511 nsContextMenuListener_AddRef,
1512 nsContextMenuListener_Release,
1513 nsContextMenuListener_OnShowContextMenu
1514 };
1515
1516 /**********************************************************
1517 * nsIURIContentListener interface
1518 */
1519
impl_from_nsIURIContentListener(nsIURIContentListener * iface)1520 static inline NSContainer *impl_from_nsIURIContentListener(nsIURIContentListener *iface)
1521 {
1522 return CONTAINING_RECORD(iface, NSContainer, nsIURIContentListener_iface);
1523 }
1524
nsURIContentListener_QueryInterface(nsIURIContentListener * iface,nsIIDRef riid,void ** result)1525 static nsresult NSAPI nsURIContentListener_QueryInterface(nsIURIContentListener *iface,
1526 nsIIDRef riid, void **result)
1527 {
1528 NSContainer *This = impl_from_nsIURIContentListener(iface);
1529 return nsIWebBrowserChrome_QueryInterface(&This->nsIWebBrowserChrome_iface, riid, result);
1530 }
1531
nsURIContentListener_AddRef(nsIURIContentListener * iface)1532 static nsrefcnt NSAPI nsURIContentListener_AddRef(nsIURIContentListener *iface)
1533 {
1534 NSContainer *This = impl_from_nsIURIContentListener(iface);
1535 return nsIWebBrowserChrome_AddRef(&This->nsIWebBrowserChrome_iface);
1536 }
1537
nsURIContentListener_Release(nsIURIContentListener * iface)1538 static nsrefcnt NSAPI nsURIContentListener_Release(nsIURIContentListener *iface)
1539 {
1540 NSContainer *This = impl_from_nsIURIContentListener(iface);
1541 return nsIWebBrowserChrome_Release(&This->nsIWebBrowserChrome_iface);
1542 }
1543
nsURIContentListener_OnStartURIOpen(nsIURIContentListener * iface,nsIURI * aURI,cpp_bool * _retval)1544 static nsresult NSAPI nsURIContentListener_OnStartURIOpen(nsIURIContentListener *iface,
1545 nsIURI *aURI, cpp_bool *_retval)
1546 {
1547 NSContainer *This = impl_from_nsIURIContentListener(iface);
1548 nsACString spec_str;
1549 const char *spec;
1550 nsresult nsres;
1551
1552 nsACString_Init(&spec_str, NULL);
1553 nsIURI_GetSpec(aURI, &spec_str);
1554 nsACString_GetData(&spec_str, &spec);
1555
1556 TRACE("(%p)->(%p(%s) %p)\n", This, aURI, debugstr_a(spec), _retval);
1557
1558 nsACString_Finish(&spec_str);
1559
1560 nsres = on_start_uri_open(This, aURI, _retval);
1561 if(NS_FAILED(nsres))
1562 return nsres;
1563
1564 return !*_retval && This->content_listener
1565 ? nsIURIContentListener_OnStartURIOpen(This->content_listener, aURI, _retval)
1566 : NS_OK;
1567 }
1568
nsURIContentListener_DoContent(nsIURIContentListener * iface,const nsACString * aContentType,cpp_bool aIsContentPreferred,nsIRequest * aRequest,nsIStreamListener ** aContentHandler,cpp_bool * _retval)1569 static nsresult NSAPI nsURIContentListener_DoContent(nsIURIContentListener *iface,
1570 const nsACString *aContentType, cpp_bool aIsContentPreferred, nsIRequest *aRequest,
1571 nsIStreamListener **aContentHandler, cpp_bool *_retval)
1572 {
1573 NSContainer *This = impl_from_nsIURIContentListener(iface);
1574
1575 TRACE("(%p)->(%p %x %p %p %p)\n", This, aContentType, aIsContentPreferred,
1576 aRequest, aContentHandler, _retval);
1577
1578 return This->content_listener
1579 ? nsIURIContentListener_DoContent(This->content_listener, aContentType,
1580 aIsContentPreferred, aRequest, aContentHandler, _retval)
1581 : NS_ERROR_NOT_IMPLEMENTED;
1582 }
1583
nsURIContentListener_IsPreferred(nsIURIContentListener * iface,const char * aContentType,char ** aDesiredContentType,cpp_bool * _retval)1584 static nsresult NSAPI nsURIContentListener_IsPreferred(nsIURIContentListener *iface,
1585 const char *aContentType, char **aDesiredContentType, cpp_bool *_retval)
1586 {
1587 NSContainer *This = impl_from_nsIURIContentListener(iface);
1588
1589 TRACE("(%p)->(%s %p %p)\n", This, debugstr_a(aContentType), aDesiredContentType, _retval);
1590
1591 /* FIXME: Should we do something here? */
1592 *_retval = TRUE;
1593
1594 return This->content_listener
1595 ? nsIURIContentListener_IsPreferred(This->content_listener, aContentType,
1596 aDesiredContentType, _retval)
1597 : NS_OK;
1598 }
1599
nsURIContentListener_CanHandleContent(nsIURIContentListener * iface,const char * aContentType,cpp_bool aIsContentPreferred,char ** aDesiredContentType,cpp_bool * _retval)1600 static nsresult NSAPI nsURIContentListener_CanHandleContent(nsIURIContentListener *iface,
1601 const char *aContentType, cpp_bool aIsContentPreferred, char **aDesiredContentType,
1602 cpp_bool *_retval)
1603 {
1604 NSContainer *This = impl_from_nsIURIContentListener(iface);
1605
1606 TRACE("(%p)->(%s %x %p %p)\n", This, debugstr_a(aContentType), aIsContentPreferred,
1607 aDesiredContentType, _retval);
1608
1609 return This->content_listener
1610 ? nsIURIContentListener_CanHandleContent(This->content_listener, aContentType,
1611 aIsContentPreferred, aDesiredContentType, _retval)
1612 : NS_ERROR_NOT_IMPLEMENTED;
1613 }
1614
nsURIContentListener_GetLoadCookie(nsIURIContentListener * iface,nsISupports ** aLoadCookie)1615 static nsresult NSAPI nsURIContentListener_GetLoadCookie(nsIURIContentListener *iface,
1616 nsISupports **aLoadCookie)
1617 {
1618 NSContainer *This = impl_from_nsIURIContentListener(iface);
1619
1620 WARN("(%p)->(%p)\n", This, aLoadCookie);
1621
1622 return This->content_listener
1623 ? nsIURIContentListener_GetLoadCookie(This->content_listener, aLoadCookie)
1624 : NS_ERROR_NOT_IMPLEMENTED;
1625 }
1626
nsURIContentListener_SetLoadCookie(nsIURIContentListener * iface,nsISupports * aLoadCookie)1627 static nsresult NSAPI nsURIContentListener_SetLoadCookie(nsIURIContentListener *iface,
1628 nsISupports *aLoadCookie)
1629 {
1630 NSContainer *This = impl_from_nsIURIContentListener(iface);
1631
1632 WARN("(%p)->(%p)\n", This, aLoadCookie);
1633
1634 return This->content_listener
1635 ? nsIURIContentListener_SetLoadCookie(This->content_listener, aLoadCookie)
1636 : NS_ERROR_NOT_IMPLEMENTED;
1637 }
1638
nsURIContentListener_GetParentContentListener(nsIURIContentListener * iface,nsIURIContentListener ** aParentContentListener)1639 static nsresult NSAPI nsURIContentListener_GetParentContentListener(nsIURIContentListener *iface,
1640 nsIURIContentListener **aParentContentListener)
1641 {
1642 NSContainer *This = impl_from_nsIURIContentListener(iface);
1643
1644 TRACE("(%p)->(%p)\n", This, aParentContentListener);
1645
1646 if(This->content_listener)
1647 nsIURIContentListener_AddRef(This->content_listener);
1648
1649 *aParentContentListener = This->content_listener;
1650 return NS_OK;
1651 }
1652
nsURIContentListener_SetParentContentListener(nsIURIContentListener * iface,nsIURIContentListener * aParentContentListener)1653 static nsresult NSAPI nsURIContentListener_SetParentContentListener(nsIURIContentListener *iface,
1654 nsIURIContentListener *aParentContentListener)
1655 {
1656 NSContainer *This = impl_from_nsIURIContentListener(iface);
1657
1658 TRACE("(%p)->(%p)\n", This, aParentContentListener);
1659
1660 if(aParentContentListener == &This->nsIURIContentListener_iface)
1661 return NS_OK;
1662
1663 if(This->content_listener)
1664 nsIURIContentListener_Release(This->content_listener);
1665
1666 This->content_listener = aParentContentListener;
1667 if(This->content_listener)
1668 nsIURIContentListener_AddRef(This->content_listener);
1669
1670 return NS_OK;
1671 }
1672
1673 static const nsIURIContentListenerVtbl nsURIContentListenerVtbl = {
1674 nsURIContentListener_QueryInterface,
1675 nsURIContentListener_AddRef,
1676 nsURIContentListener_Release,
1677 nsURIContentListener_OnStartURIOpen,
1678 nsURIContentListener_DoContent,
1679 nsURIContentListener_IsPreferred,
1680 nsURIContentListener_CanHandleContent,
1681 nsURIContentListener_GetLoadCookie,
1682 nsURIContentListener_SetLoadCookie,
1683 nsURIContentListener_GetParentContentListener,
1684 nsURIContentListener_SetParentContentListener
1685 };
1686
1687 /**********************************************************
1688 * nsIEmbeddinSiteWindow interface
1689 */
1690
impl_from_nsIEmbeddingSiteWindow(nsIEmbeddingSiteWindow * iface)1691 static inline NSContainer *impl_from_nsIEmbeddingSiteWindow(nsIEmbeddingSiteWindow *iface)
1692 {
1693 return CONTAINING_RECORD(iface, NSContainer, nsIEmbeddingSiteWindow_iface);
1694 }
1695
nsEmbeddingSiteWindow_QueryInterface(nsIEmbeddingSiteWindow * iface,nsIIDRef riid,void ** result)1696 static nsresult NSAPI nsEmbeddingSiteWindow_QueryInterface(nsIEmbeddingSiteWindow *iface,
1697 nsIIDRef riid, void **result)
1698 {
1699 NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
1700 return nsIWebBrowserChrome_QueryInterface(&This->nsIWebBrowserChrome_iface, riid, result);
1701 }
1702
nsEmbeddingSiteWindow_AddRef(nsIEmbeddingSiteWindow * iface)1703 static nsrefcnt NSAPI nsEmbeddingSiteWindow_AddRef(nsIEmbeddingSiteWindow *iface)
1704 {
1705 NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
1706 return nsIWebBrowserChrome_AddRef(&This->nsIWebBrowserChrome_iface);
1707 }
1708
nsEmbeddingSiteWindow_Release(nsIEmbeddingSiteWindow * iface)1709 static nsrefcnt NSAPI nsEmbeddingSiteWindow_Release(nsIEmbeddingSiteWindow *iface)
1710 {
1711 NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
1712 return nsIWebBrowserChrome_Release(&This->nsIWebBrowserChrome_iface);
1713 }
1714
nsEmbeddingSiteWindow_SetDimensions(nsIEmbeddingSiteWindow * iface,UINT32 flags,LONG x,LONG y,LONG cx,LONG cy)1715 static nsresult NSAPI nsEmbeddingSiteWindow_SetDimensions(nsIEmbeddingSiteWindow *iface,
1716 UINT32 flags, LONG x, LONG y, LONG cx, LONG cy)
1717 {
1718 NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
1719 WARN("(%p)->(%08x %d %d %d %d)\n", This, flags, x, y, cx, cy);
1720 return NS_ERROR_NOT_IMPLEMENTED;
1721 }
1722
nsEmbeddingSiteWindow_GetDimensions(nsIEmbeddingSiteWindow * iface,UINT32 flags,LONG * x,LONG * y,LONG * cx,LONG * cy)1723 static nsresult NSAPI nsEmbeddingSiteWindow_GetDimensions(nsIEmbeddingSiteWindow *iface,
1724 UINT32 flags, LONG *x, LONG *y, LONG *cx, LONG *cy)
1725 {
1726 NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
1727 RECT r;
1728
1729 TRACE("(%p)->(%x %p %p %p %p)\n", This, flags, x, y, cx, cy);
1730
1731 if(!GetWindowRect(This->hwnd, &r)) {
1732 ERR("GetWindowRect failed\n");
1733 return NS_ERROR_FAILURE;
1734 }
1735
1736 if(x)
1737 *x = r.left;
1738 if(y)
1739 *y = r.top;
1740 if(cx)
1741 *cx = r.right-r.left;
1742 if(cy)
1743 *cy = r.bottom-r.top;
1744 return NS_OK;
1745 }
1746
nsEmbeddingSiteWindow_SetFocus(nsIEmbeddingSiteWindow * iface)1747 static nsresult NSAPI nsEmbeddingSiteWindow_SetFocus(nsIEmbeddingSiteWindow *iface)
1748 {
1749 NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
1750
1751 TRACE("(%p)\n", This);
1752
1753 return nsIBaseWindow_SetFocus(This->window);
1754 }
1755
nsEmbeddingSiteWindow_GetVisibility(nsIEmbeddingSiteWindow * iface,cpp_bool * aVisibility)1756 static nsresult NSAPI nsEmbeddingSiteWindow_GetVisibility(nsIEmbeddingSiteWindow *iface,
1757 cpp_bool *aVisibility)
1758 {
1759 NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
1760
1761 TRACE("(%p)->(%p)\n", This, aVisibility);
1762
1763 *aVisibility = This->doc && This->doc->hwnd && IsWindowVisible(This->doc->hwnd);
1764 return NS_OK;
1765 }
1766
nsEmbeddingSiteWindow_SetVisibility(nsIEmbeddingSiteWindow * iface,cpp_bool aVisibility)1767 static nsresult NSAPI nsEmbeddingSiteWindow_SetVisibility(nsIEmbeddingSiteWindow *iface,
1768 cpp_bool aVisibility)
1769 {
1770 NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
1771
1772 TRACE("(%p)->(%x)\n", This, aVisibility);
1773
1774 return NS_OK;
1775 }
1776
nsEmbeddingSiteWindow_GetTitle(nsIEmbeddingSiteWindow * iface,PRUnichar ** aTitle)1777 static nsresult NSAPI nsEmbeddingSiteWindow_GetTitle(nsIEmbeddingSiteWindow *iface,
1778 PRUnichar **aTitle)
1779 {
1780 NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
1781 WARN("(%p)->(%p)\n", This, aTitle);
1782 return NS_ERROR_NOT_IMPLEMENTED;
1783 }
1784
nsEmbeddingSiteWindow_SetTitle(nsIEmbeddingSiteWindow * iface,const PRUnichar * aTitle)1785 static nsresult NSAPI nsEmbeddingSiteWindow_SetTitle(nsIEmbeddingSiteWindow *iface,
1786 const PRUnichar *aTitle)
1787 {
1788 NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
1789 WARN("(%p)->(%s)\n", This, debugstr_w(aTitle));
1790 return NS_ERROR_NOT_IMPLEMENTED;
1791 }
1792
nsEmbeddingSiteWindow_GetSiteWindow(nsIEmbeddingSiteWindow * iface,void ** aSiteWindow)1793 static nsresult NSAPI nsEmbeddingSiteWindow_GetSiteWindow(nsIEmbeddingSiteWindow *iface,
1794 void **aSiteWindow)
1795 {
1796 NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
1797
1798 TRACE("(%p)->(%p)\n", This, aSiteWindow);
1799
1800 *aSiteWindow = This->hwnd;
1801 return NS_OK;
1802 }
1803
1804 static const nsIEmbeddingSiteWindowVtbl nsEmbeddingSiteWindowVtbl = {
1805 nsEmbeddingSiteWindow_QueryInterface,
1806 nsEmbeddingSiteWindow_AddRef,
1807 nsEmbeddingSiteWindow_Release,
1808 nsEmbeddingSiteWindow_SetDimensions,
1809 nsEmbeddingSiteWindow_GetDimensions,
1810 nsEmbeddingSiteWindow_SetFocus,
1811 nsEmbeddingSiteWindow_GetVisibility,
1812 nsEmbeddingSiteWindow_SetVisibility,
1813 nsEmbeddingSiteWindow_GetTitle,
1814 nsEmbeddingSiteWindow_SetTitle,
1815 nsEmbeddingSiteWindow_GetSiteWindow
1816 };
1817
impl_from_nsITooltipListener(nsITooltipListener * iface)1818 static inline NSContainer *impl_from_nsITooltipListener(nsITooltipListener *iface)
1819 {
1820 return CONTAINING_RECORD(iface, NSContainer, nsITooltipListener_iface);
1821 }
1822
nsTooltipListener_QueryInterface(nsITooltipListener * iface,nsIIDRef riid,void ** result)1823 static nsresult NSAPI nsTooltipListener_QueryInterface(nsITooltipListener *iface, nsIIDRef riid,
1824 void **result)
1825 {
1826 NSContainer *This = impl_from_nsITooltipListener(iface);
1827 return nsIWebBrowserChrome_QueryInterface(&This->nsIWebBrowserChrome_iface, riid, result);
1828 }
1829
nsTooltipListener_AddRef(nsITooltipListener * iface)1830 static nsrefcnt NSAPI nsTooltipListener_AddRef(nsITooltipListener *iface)
1831 {
1832 NSContainer *This = impl_from_nsITooltipListener(iface);
1833 return nsIWebBrowserChrome_AddRef(&This->nsIWebBrowserChrome_iface);
1834 }
1835
nsTooltipListener_Release(nsITooltipListener * iface)1836 static nsrefcnt NSAPI nsTooltipListener_Release(nsITooltipListener *iface)
1837 {
1838 NSContainer *This = impl_from_nsITooltipListener(iface);
1839 return nsIWebBrowserChrome_Release(&This->nsIWebBrowserChrome_iface);
1840 }
1841
nsTooltipListener_OnShowTooltip(nsITooltipListener * iface,LONG aXCoord,LONG aYCoord,const PRUnichar * aTipText)1842 static nsresult NSAPI nsTooltipListener_OnShowTooltip(nsITooltipListener *iface,
1843 LONG aXCoord, LONG aYCoord, const PRUnichar *aTipText)
1844 {
1845 NSContainer *This = impl_from_nsITooltipListener(iface);
1846
1847 if (This->doc)
1848 show_tooltip(This->doc, aXCoord, aYCoord, aTipText);
1849
1850 return NS_OK;
1851 }
1852
nsTooltipListener_OnHideTooltip(nsITooltipListener * iface)1853 static nsresult NSAPI nsTooltipListener_OnHideTooltip(nsITooltipListener *iface)
1854 {
1855 NSContainer *This = impl_from_nsITooltipListener(iface);
1856
1857 if (This->doc)
1858 hide_tooltip(This->doc);
1859
1860 return NS_OK;
1861 }
1862
1863 static const nsITooltipListenerVtbl nsTooltipListenerVtbl = {
1864 nsTooltipListener_QueryInterface,
1865 nsTooltipListener_AddRef,
1866 nsTooltipListener_Release,
1867 nsTooltipListener_OnShowTooltip,
1868 nsTooltipListener_OnHideTooltip
1869 };
1870
impl_from_nsIInterfaceRequestor(nsIInterfaceRequestor * iface)1871 static inline NSContainer *impl_from_nsIInterfaceRequestor(nsIInterfaceRequestor *iface)
1872 {
1873 return CONTAINING_RECORD(iface, NSContainer, nsIInterfaceRequestor_iface);
1874 }
1875
nsInterfaceRequestor_QueryInterface(nsIInterfaceRequestor * iface,nsIIDRef riid,void ** result)1876 static nsresult NSAPI nsInterfaceRequestor_QueryInterface(nsIInterfaceRequestor *iface,
1877 nsIIDRef riid, void **result)
1878 {
1879 NSContainer *This = impl_from_nsIInterfaceRequestor(iface);
1880 return nsIWebBrowserChrome_QueryInterface(&This->nsIWebBrowserChrome_iface, riid, result);
1881 }
1882
nsInterfaceRequestor_AddRef(nsIInterfaceRequestor * iface)1883 static nsrefcnt NSAPI nsInterfaceRequestor_AddRef(nsIInterfaceRequestor *iface)
1884 {
1885 NSContainer *This = impl_from_nsIInterfaceRequestor(iface);
1886 return nsIWebBrowserChrome_AddRef(&This->nsIWebBrowserChrome_iface);
1887 }
1888
nsInterfaceRequestor_Release(nsIInterfaceRequestor * iface)1889 static nsrefcnt NSAPI nsInterfaceRequestor_Release(nsIInterfaceRequestor *iface)
1890 {
1891 NSContainer *This = impl_from_nsIInterfaceRequestor(iface);
1892 return nsIWebBrowserChrome_Release(&This->nsIWebBrowserChrome_iface);
1893 }
1894
nsInterfaceRequestor_GetInterface(nsIInterfaceRequestor * iface,nsIIDRef riid,void ** result)1895 static nsresult NSAPI nsInterfaceRequestor_GetInterface(nsIInterfaceRequestor *iface,
1896 nsIIDRef riid, void **result)
1897 {
1898 NSContainer *This = impl_from_nsIInterfaceRequestor(iface);
1899
1900 if(IsEqualGUID(&IID_nsIDOMWindow, riid)) {
1901 TRACE("(%p)->(IID_nsIDOMWindow %p)\n", This, result);
1902 return nsIWebBrowser_GetContentDOMWindow(This->webbrowser, (nsIDOMWindow**)result);
1903 }
1904
1905 return nsIWebBrowserChrome_QueryInterface(&This->nsIWebBrowserChrome_iface, riid, result);
1906 }
1907
1908 static const nsIInterfaceRequestorVtbl nsInterfaceRequestorVtbl = {
1909 nsInterfaceRequestor_QueryInterface,
1910 nsInterfaceRequestor_AddRef,
1911 nsInterfaceRequestor_Release,
1912 nsInterfaceRequestor_GetInterface
1913 };
1914
impl_from_nsISupportsWeakReference(nsISupportsWeakReference * iface)1915 static inline NSContainer *impl_from_nsISupportsWeakReference(nsISupportsWeakReference *iface)
1916 {
1917 return CONTAINING_RECORD(iface, NSContainer, nsISupportsWeakReference_iface);
1918 }
1919
nsSupportsWeakReference_QueryInterface(nsISupportsWeakReference * iface,nsIIDRef riid,void ** result)1920 static nsresult NSAPI nsSupportsWeakReference_QueryInterface(nsISupportsWeakReference *iface,
1921 nsIIDRef riid, void **result)
1922 {
1923 NSContainer *This = impl_from_nsISupportsWeakReference(iface);
1924 return nsIWebBrowserChrome_QueryInterface(&This->nsIWebBrowserChrome_iface, riid, result);
1925 }
1926
nsSupportsWeakReference_AddRef(nsISupportsWeakReference * iface)1927 static nsrefcnt NSAPI nsSupportsWeakReference_AddRef(nsISupportsWeakReference *iface)
1928 {
1929 NSContainer *This = impl_from_nsISupportsWeakReference(iface);
1930 return nsIWebBrowserChrome_AddRef(&This->nsIWebBrowserChrome_iface);
1931 }
1932
nsSupportsWeakReference_Release(nsISupportsWeakReference * iface)1933 static nsrefcnt NSAPI nsSupportsWeakReference_Release(nsISupportsWeakReference *iface)
1934 {
1935 NSContainer *This = impl_from_nsISupportsWeakReference(iface);
1936 return nsIWebBrowserChrome_Release(&This->nsIWebBrowserChrome_iface);
1937 }
1938
nsSupportsWeakReference_GetWeakReference(nsISupportsWeakReference * iface,nsIWeakReference ** _retval)1939 static nsresult NSAPI nsSupportsWeakReference_GetWeakReference(nsISupportsWeakReference *iface,
1940 nsIWeakReference **_retval)
1941 {
1942 NSContainer *This = impl_from_nsISupportsWeakReference(iface);
1943
1944 TRACE("(%p)->(%p)\n", This, _retval);
1945
1946 if(!This->weak_reference) {
1947 This->weak_reference = heap_alloc(sizeof(nsWeakReference));
1948 if(!This->weak_reference)
1949 return NS_ERROR_OUT_OF_MEMORY;
1950
1951 This->weak_reference->nsIWeakReference_iface.lpVtbl = &nsWeakReferenceVtbl;
1952 This->weak_reference->ref = 1;
1953 This->weak_reference->nscontainer = This;
1954 }
1955
1956 *_retval = &This->weak_reference->nsIWeakReference_iface;
1957 nsIWeakReference_AddRef(*_retval);
1958 return NS_OK;
1959 }
1960
1961 static const nsISupportsWeakReferenceVtbl nsSupportsWeakReferenceVtbl = {
1962 nsSupportsWeakReference_QueryInterface,
1963 nsSupportsWeakReference_AddRef,
1964 nsSupportsWeakReference_Release,
1965 nsSupportsWeakReference_GetWeakReference
1966 };
1967
init_nscontainer(NSContainer * nscontainer)1968 static HRESULT init_nscontainer(NSContainer *nscontainer)
1969 {
1970 nsIWebBrowserSetup *wbsetup;
1971 nsIScrollable *scrollable;
1972 nsresult nsres;
1973
1974 nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr, NS_WEBBROWSER_CONTRACTID,
1975 NULL, &IID_nsIWebBrowser, (void**)&nscontainer->webbrowser);
1976 if(NS_FAILED(nsres)) {
1977 ERR("Creating WebBrowser failed: %08x\n", nsres);
1978 return E_FAIL;
1979 }
1980
1981 nsres = nsIWebBrowser_SetContainerWindow(nscontainer->webbrowser, &nscontainer->nsIWebBrowserChrome_iface);
1982 if(NS_FAILED(nsres)) {
1983 ERR("SetContainerWindow failed: %08x\n", nsres);
1984 return E_FAIL;
1985 }
1986
1987 nsres = nsIWebBrowser_QueryInterface(nscontainer->webbrowser, &IID_nsIBaseWindow,
1988 (void**)&nscontainer->window);
1989 if(NS_FAILED(nsres)) {
1990 ERR("Could not get nsIBaseWindow interface: %08x\n", nsres);
1991 return E_FAIL;
1992 }
1993
1994 nsres = nsIWebBrowser_QueryInterface(nscontainer->webbrowser, &IID_nsIWebBrowserSetup,
1995 (void**)&wbsetup);
1996 if(NS_SUCCEEDED(nsres)) {
1997 nsres = nsIWebBrowserSetup_SetProperty(wbsetup, SETUP_IS_CHROME_WRAPPER, FALSE);
1998 nsIWebBrowserSetup_Release(wbsetup);
1999 if(NS_FAILED(nsres)) {
2000 ERR("SetProperty(SETUP_IS_CHROME_WRAPPER) failed: %08x\n", nsres);
2001 return E_FAIL;
2002 }
2003 }else {
2004 ERR("Could not get nsIWebBrowserSetup interface\n");
2005 return E_FAIL;
2006 }
2007
2008 nsres = nsIWebBrowser_QueryInterface(nscontainer->webbrowser, &IID_nsIWebNavigation,
2009 (void**)&nscontainer->navigation);
2010 if(NS_FAILED(nsres)) {
2011 ERR("Could not get nsIWebNavigation interface: %08x\n", nsres);
2012 return E_FAIL;
2013 }
2014
2015 nsres = nsIWebBrowser_QueryInterface(nscontainer->webbrowser, &IID_nsIWebBrowserFocus,
2016 (void**)&nscontainer->focus);
2017 if(NS_FAILED(nsres)) {
2018 ERR("Could not get nsIWebBrowserFocus interface: %08x\n", nsres);
2019 return E_FAIL;
2020 }
2021
2022 if(!nscontainer_class) {
2023 register_nscontainer_class();
2024 if(!nscontainer_class)
2025 return E_FAIL;
2026 }
2027
2028 nscontainer->hwnd = CreateWindowExW(0, wszNsContainer, NULL,
2029 WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, 100, 100,
2030 GetDesktopWindow(), NULL, hInst, nscontainer);
2031 if(!nscontainer->hwnd) {
2032 WARN("Could not create window\n");
2033 return E_FAIL;
2034 }
2035
2036 nsres = nsIBaseWindow_InitWindow(nscontainer->window, nscontainer->hwnd, NULL, 0, 0, 100, 100);
2037 if(NS_SUCCEEDED(nsres)) {
2038 nsres = nsIBaseWindow_Create(nscontainer->window);
2039 if(NS_FAILED(nsres)) {
2040 WARN("Creating window failed: %08x\n", nsres);
2041 return E_FAIL;
2042 }
2043
2044 nsIBaseWindow_SetVisibility(nscontainer->window, FALSE);
2045 nsIBaseWindow_SetEnabled(nscontainer->window, FALSE);
2046 }else {
2047 ERR("InitWindow failed: %08x\n", nsres);
2048 return E_FAIL;
2049 }
2050
2051 nsres = nsIWebBrowser_SetParentURIContentListener(nscontainer->webbrowser,
2052 &nscontainer->nsIURIContentListener_iface);
2053 if(NS_FAILED(nsres))
2054 ERR("SetParentURIContentListener failed: %08x\n", nsres);
2055
2056 nsres = nsIWebBrowser_QueryInterface(nscontainer->webbrowser, &IID_nsIScrollable, (void**)&scrollable);
2057 if(NS_SUCCEEDED(nsres)) {
2058 nsres = nsIScrollable_SetDefaultScrollbarPreferences(scrollable,
2059 ScrollOrientation_Y, Scrollbar_Always);
2060 if(NS_FAILED(nsres))
2061 ERR("Could not set default Y scrollbar prefs: %08x\n", nsres);
2062
2063 nsres = nsIScrollable_SetDefaultScrollbarPreferences(scrollable,
2064 ScrollOrientation_X, Scrollbar_Auto);
2065 if(NS_FAILED(nsres))
2066 ERR("Could not set default X scrollbar prefs: %08x\n", nsres);
2067
2068 nsIScrollable_Release(scrollable);
2069 }else {
2070 ERR("Could not get nsIScrollable: %08x\n", nsres);
2071 }
2072
2073 return S_OK;
2074 }
2075
create_nscontainer(HTMLDocumentObj * doc,NSContainer ** _ret)2076 HRESULT create_nscontainer(HTMLDocumentObj *doc, NSContainer **_ret)
2077 {
2078 NSContainer *ret;
2079 HRESULT hres;
2080
2081 if(!load_gecko())
2082 return CLASS_E_CLASSNOTAVAILABLE;
2083
2084 ret = heap_alloc_zero(sizeof(NSContainer));
2085 if(!ret)
2086 return E_OUTOFMEMORY;
2087
2088 ret->nsIWebBrowserChrome_iface.lpVtbl = &nsWebBrowserChromeVtbl;
2089 ret->nsIContextMenuListener_iface.lpVtbl = &nsContextMenuListenerVtbl;
2090 ret->nsIURIContentListener_iface.lpVtbl = &nsURIContentListenerVtbl;
2091 ret->nsIEmbeddingSiteWindow_iface.lpVtbl = &nsEmbeddingSiteWindowVtbl;
2092 ret->nsITooltipListener_iface.lpVtbl = &nsTooltipListenerVtbl;
2093 ret->nsIInterfaceRequestor_iface.lpVtbl = &nsInterfaceRequestorVtbl;
2094 ret->nsISupportsWeakReference_iface.lpVtbl = &nsSupportsWeakReferenceVtbl;
2095
2096 ret->doc = doc;
2097 ret->ref = 1;
2098
2099 hres = init_nscontainer(ret);
2100 if(SUCCEEDED(hres))
2101 *_ret = ret;
2102 else
2103 nsIWebBrowserChrome_Release(&ret->nsIWebBrowserChrome_iface);
2104 return hres;
2105 }
2106
NSContainer_Release(NSContainer * This)2107 void NSContainer_Release(NSContainer *This)
2108 {
2109 TRACE("(%p)\n", This);
2110
2111 This->doc = NULL;
2112
2113 ShowWindow(This->hwnd, SW_HIDE);
2114 SetParent(This->hwnd, NULL);
2115
2116 nsIBaseWindow_SetVisibility(This->window, FALSE);
2117 nsIBaseWindow_Destroy(This->window);
2118
2119 nsIWebBrowser_SetContainerWindow(This->webbrowser, NULL);
2120
2121 nsIWebBrowser_Release(This->webbrowser);
2122 This->webbrowser = NULL;
2123
2124 nsIWebNavigation_Release(This->navigation);
2125 This->navigation = NULL;
2126
2127 nsIBaseWindow_Release(This->window);
2128 This->window = NULL;
2129
2130 nsIWebBrowserFocus_Release(This->focus);
2131 This->focus = NULL;
2132
2133 if(This->editor_controller) {
2134 nsIController_Release(This->editor_controller);
2135 This->editor_controller = NULL;
2136 }
2137
2138 if(This->editor) {
2139 nsIEditor_Release(This->editor);
2140 This->editor = NULL;
2141 }
2142
2143 if(This->content_listener) {
2144 nsIURIContentListener_Release(This->content_listener);
2145 This->content_listener = NULL;
2146 }
2147
2148 if(This->hwnd) {
2149 DestroyWindow(This->hwnd);
2150 This->hwnd = NULL;
2151 }
2152
2153 nsIWebBrowserChrome_Release(&This->nsIWebBrowserChrome_iface);
2154 }
2155
create_nsxhr(nsIDOMWindow * nswindow)2156 nsIXMLHttpRequest *create_nsxhr(nsIDOMWindow *nswindow)
2157 {
2158 nsIScriptSecurityManager *secman;
2159 nsIPrincipal *nspri;
2160 nsIGlobalObject *nsglo;
2161 nsIXMLHttpRequest *nsxhr;
2162 nsresult nsres;
2163
2164 nsres = nsIServiceManager_GetServiceByContractID(pServMgr,
2165 NS_SCRIPTSECURITYMANAGER_CONTRACTID,
2166 &IID_nsIScriptSecurityManager, (void**)&secman);
2167 if(NS_FAILED(nsres)) {
2168 ERR("Could not get sec manager service: %08x\n", nsres);
2169 return NULL;
2170 }
2171
2172 nsres = nsIScriptSecurityManager_GetSystemPrincipal(secman, &nspri);
2173 nsIScriptSecurityManager_Release(secman);
2174 if(NS_FAILED(nsres)) {
2175 ERR("GetSystemPrincipal failed: %08x\n", nsres);
2176 return NULL;
2177 }
2178
2179 nsres = nsIDOMWindow_QueryInterface(nswindow, &IID_nsIGlobalObject, (void **)&nsglo);
2180 assert(nsres == NS_OK);
2181
2182 nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr,
2183 NS_XMLHTTPREQUEST_CONTRACTID, NULL, &IID_nsIXMLHttpRequest,
2184 (void**)&nsxhr);
2185 if(NS_FAILED(nsres)) {
2186 ERR("Could not get nsIXMLHttpRequest: %08x\n", nsres);
2187 nsISupports_Release(nspri);
2188 nsIGlobalObject_Release(nsglo);
2189 return NULL;
2190 }
2191
2192 nsres = nsIXMLHttpRequest_Init(nsxhr, nspri, NULL, nsglo, NULL, NULL);
2193
2194 nsISupports_Release(nspri);
2195 nsIGlobalObject_Release(nsglo);
2196 if(NS_FAILED(nsres)) {
2197 ERR("nsIXMLHttpRequest_Init failed: %08x\n", nsres);
2198 nsIXMLHttpRequest_Release(nsxhr);
2199 return NULL;
2200 }
2201 return nsxhr;
2202 }
2203