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