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 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 92 static inline nsSingletonEnumerator *impl_from_nsISimpleEnumerator(nsISimpleEnumerator *iface) 93 { 94 return CONTAINING_RECORD(iface, nsSingletonEnumerator, nsISimpleEnumerator_iface); 95 } 96 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 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 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 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 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 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 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 214 static nsrefcnt NSAPI nsDirectoryServiceProvider2_AddRef(nsIDirectoryServiceProvider2 *iface) 215 { 216 return 2; 217 } 218 219 static nsrefcnt NSAPI nsDirectoryServiceProvider2_Release(nsIDirectoryServiceProvider2 *iface) 220 { 221 return 1; 222 } 223 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 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 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 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 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__ 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 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 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 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 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 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 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 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 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 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 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 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 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 778 void *nsalloc(size_t size) 779 { 780 return NS_Alloc(size); 781 } 782 783 void nsfree(void *mem) 784 { 785 NS_Free(mem); 786 } 787 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 */ 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 802 void nsACString_SetData(nsACString *str, const char *data) 803 { 804 NS_CStringSetData(str, data, PR_UINT32_MAX); 805 } 806 807 UINT32 nsACString_GetData(const nsACString *str, const char **data) 808 { 809 return NS_CStringGetData(str, data, NULL); 810 } 811 812 void nsACString_Finish(nsACString *str) 813 { 814 NS_CStringContainerFinish(str); 815 } 816 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 */ 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 831 UINT32 nsAString_GetData(const nsAString *str, const PRUnichar **data) 832 { 833 return NS_StringGetData(str, data, NULL); 834 } 835 836 void nsAString_Finish(nsAString *str) 837 { 838 NS_StringContainerFinish(str); 839 } 840 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 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 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 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 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 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 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 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 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 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 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 1160 static inline nsWeakReference *impl_from_nsIWeakReference(nsIWeakReference *iface) 1161 { 1162 return CONTAINING_RECORD(iface, nsWeakReference, nsIWeakReference_iface); 1163 } 1164 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 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 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 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 1233 static inline NSContainer *impl_from_nsIWebBrowserChrome(nsIWebBrowserChrome *iface) 1234 { 1235 return CONTAINING_RECORD(iface, NSContainer, nsIWebBrowserChrome_iface); 1236 } 1237 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 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 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 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 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 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 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 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 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 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 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 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 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 1419 static inline NSContainer *impl_from_nsIContextMenuListener(nsIContextMenuListener *iface) 1420 { 1421 return CONTAINING_RECORD(iface, NSContainer, nsIContextMenuListener_iface); 1422 } 1423 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 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 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 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 1520 static inline NSContainer *impl_from_nsIURIContentListener(nsIURIContentListener *iface) 1521 { 1522 return CONTAINING_RECORD(iface, NSContainer, nsIURIContentListener_iface); 1523 } 1524 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 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 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 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 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 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 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 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 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 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 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 1691 static inline NSContainer *impl_from_nsIEmbeddingSiteWindow(nsIEmbeddingSiteWindow *iface) 1692 { 1693 return CONTAINING_RECORD(iface, NSContainer, nsIEmbeddingSiteWindow_iface); 1694 } 1695 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 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 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 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 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 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 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 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 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 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 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 1818 static inline NSContainer *impl_from_nsITooltipListener(nsITooltipListener *iface) 1819 { 1820 return CONTAINING_RECORD(iface, NSContainer, nsITooltipListener_iface); 1821 } 1822 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 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 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 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 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 1871 static inline NSContainer *impl_from_nsIInterfaceRequestor(nsIInterfaceRequestor *iface) 1872 { 1873 return CONTAINING_RECORD(iface, NSContainer, nsIInterfaceRequestor_iface); 1874 } 1875 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 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 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 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 1915 static inline NSContainer *impl_from_nsISupportsWeakReference(nsISupportsWeakReference *iface) 1916 { 1917 return CONTAINING_RECORD(iface, NSContainer, nsISupportsWeakReference_iface); 1918 } 1919 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 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 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 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 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 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 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 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