From 068fa0aa212a0c8a3eac5c0ef3e62a1ae96e2144 Mon Sep 17 00:00:00 2001 From: Jacek Caban <jack@itma.pwr.wroc.pl> Date: Mon, 1 Aug 2005 10:59:45 +0000 Subject: [PATCH] - Use Gecko to render HTML. - Get rid of Mozilla ActiveX Control in MSHTML. --- dlls/mshtml/.cvsignore | 1 + dlls/mshtml/Makefile.in | 3 + dlls/mshtml/htmldoc.c | 11 +- dlls/mshtml/main.c | 92 +---------- dlls/mshtml/mshtml_private.h | 29 ++++ dlls/mshtml/nsembed.c | 294 +++++++++++++++++++++++++++++++++++ dlls/mshtml/nsiface.idl | 241 ++++++++++++++++++++++++++++ dlls/mshtml/persist.c | 27 ++++ dlls/mshtml/view.c | 73 ++++++++- 9 files changed, 675 insertions(+), 96 deletions(-) create mode 100644 dlls/mshtml/nsembed.c create mode 100644 dlls/mshtml/nsiface.idl diff --git a/dlls/mshtml/.cvsignore b/dlls/mshtml/.cvsignore index bd852edae90..e88ede7bbb4 100644 --- a/dlls/mshtml/.cvsignore +++ b/dlls/mshtml/.cvsignore @@ -1,4 +1,5 @@ Makefile libmshtml.def mshtml.dll.dbg.c +nsiface.h rsrc.res diff --git a/dlls/mshtml/Makefile.in b/dlls/mshtml/Makefile.in index 9353b647ebb..11977afb49a 100644 --- a/dlls/mshtml/Makefile.in +++ b/dlls/mshtml/Makefile.in @@ -11,6 +11,7 @@ EXTRADEFS = -DCOM_NO_WINDOWS_H C_SRCS = \ htmldoc.c \ main.c \ + nsembed.c \ oleobj.c \ olewnd.c \ persist.c \ @@ -20,6 +21,8 @@ C_SRCS = \ RC_SRCS = rsrc.rc +IDL_SRCS = nsiface.idl + SUBDIRS = tests @MAKE_DLL_RULES@ diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index 632829d7e39..f27be357aea 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -38,9 +38,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); +#define HTMLDOC_THIS(iface) DEFINE_THIS(HTMLDocument, HTMLDocument2, iface) + static HRESULT WINAPI HTMLDocument_QueryInterface(IHTMLDocument2 *iface, REFIID riid, void **ppvObject) { - HTMLDocument *This = (HTMLDocument*)iface; + HTMLDocument *This = HTMLDOC_THIS(iface); *ppvObject = NULL; if(IsEqualGUID(&IID_IUnknown, riid)) { @@ -113,7 +115,7 @@ static HRESULT WINAPI HTMLDocument_QueryInterface(IHTMLDocument2 *iface, REFIID static ULONG WINAPI HTMLDocument_AddRef(IHTMLDocument2 *iface) { - HTMLDocument *This = (HTMLDocument*)iface; + HTMLDocument *This = HTMLDOC_THIS(iface); ULONG ref = InterlockedIncrement(&This->ref); TRACE("(%p) ref = %lu\n", This, ref); return ref; @@ -121,7 +123,7 @@ static ULONG WINAPI HTMLDocument_AddRef(IHTMLDocument2 *iface) static ULONG WINAPI HTMLDocument_Release(IHTMLDocument2 *iface) { - HTMLDocument *This = (HTMLDocument*)iface; + HTMLDocument *This = HTMLDOC_THIS(iface); ULONG ref = InterlockedDecrement(&This->ref); TRACE("(%p) ref = %lu\n", This, ref); @@ -135,6 +137,8 @@ static ULONG WINAPI HTMLDocument_Release(IHTMLDocument2 *iface) IOleDocumentView_SetInPlaceSite(DOCVIEW(This), NULL); if(This->hwnd) DestroyWindow(This->hwnd); + if(This->nscontainer) + HTMLDocument_NSContainer_Destroy(This); HeapFree(GetProcessHeap(), 0, This); } @@ -978,6 +982,7 @@ HRESULT HTMLDocument_Create(IUnknown *pUnkOuter, REFIID riid, void** ppvObject) HTMLDocument_View_Init(ret); HTMLDocument_Window_Init(ret); HTMLDocument_Service_Init(ret); + HTMLDocument_NSContainer_Init(ret); return hres; } diff --git a/dlls/mshtml/main.c b/dlls/mshtml/main.c index 20fb460d9d1..88e1aa41106 100644 --- a/dlls/mshtml/main.c +++ b/dlls/mshtml/main.c @@ -47,75 +47,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); -DEFINE_GUID( CLSID_MozillaBrowser, 0x1339B54C,0x3453,0x11D2,0x93,0xB9,0x00,0x00,0x00,0x00,0x00,0x00); - -typedef HRESULT (WINAPI *fnGetClassObject)(REFCLSID rclsid, REFIID iid, LPVOID *ppv); -typedef BOOL (WINAPI *fnCanUnloadNow)(); - -static HMODULE hMozCtl; - HINSTANCE hInst; -/* convert a guid to a wide character string */ -static void MSHTML_guid2wstr( const GUID *guid, LPWSTR wstr ) -{ - char str[40]; - - sprintf(str, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", - guid->Data1, guid->Data2, guid->Data3, - guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], - guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] ); - MultiByteToWideChar( CP_ACP, 0, str, -1, wstr, 40 ); -} - -static BOOL MSHTML_GetMozctlPath( LPWSTR szPath, DWORD sz ) -{ - DWORD r, type; - BOOL ret = FALSE; - HKEY hkey; - static const WCHAR szPre[] = { - 'S','o','f','t','w','a','r','e','\\', - 'C','l','a','s','s','e','s','\\', - 'C','L','S','I','D','\\',0 }; - static const WCHAR szPost[] = { - '\\','I','n','p','r','o','c','S','e','r','v','e','r','3','2',0 }; - WCHAR szRegPath[(sizeof(szPre)+sizeof(szPost))/sizeof(WCHAR)+40]; - - strcpyW( szRegPath, szPre ); - MSHTML_guid2wstr( &CLSID_MozillaBrowser, &szRegPath[strlenW(szRegPath)] ); - strcatW( szRegPath, szPost ); - - TRACE("key = %s\n", debugstr_w( szRegPath ) ); - - r = RegOpenKeyW( HKEY_LOCAL_MACHINE, szRegPath, &hkey ); - if( r != ERROR_SUCCESS ) - return FALSE; - - r = RegQueryValueExW( hkey, NULL, NULL, &type, (LPBYTE)szPath, &sz ); - ret = ( r == ERROR_SUCCESS ) && ( type == REG_SZ ); - RegCloseKey( hkey ); - - return ret; -} - BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) { - WCHAR szPath[MAX_PATH]; - switch(fdwReason) { case DLL_PROCESS_ATTACH: - if(MSHTML_GetMozctlPath(szPath, sizeof szPath)) { - hMozCtl = LoadLibraryExW(szPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); - if(!hMozCtl) - ERR("Can't load the Mozilla ActiveX control\n"); - }else { - TRACE("Not found Mozilla ActiveX Control. HTML rendering will be disabled.\n"); - } hInst = hInstDLL; break; case DLL_PROCESS_DETACH: - if(hMozCtl) - FreeLibrary( hMozCtl ); + close_gecko(); break; } return TRUE; @@ -205,20 +146,6 @@ static HRESULT ClassFactory_Create(REFIID riid, void **ppv, CreateInstanceFunc f HRESULT WINAPI MSHTML_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { - HRESULT hres; - fnGetClassObject pGetClassObject; - - if(hMozCtl && IsEqualGUID(&CLSID_HTMLDocument, rclsid)) { - pGetClassObject = (fnGetClassObject) GetProcAddress(hMozCtl, "DllGetClassObject"); - if(pGetClassObject) { - hres = pGetClassObject(&CLSID_MozillaBrowser, riid, ppv); - if(SUCCEEDED(hres)) { - TRACE("returning Mozilla ActiveX Control hres = %08lx *ppv = %p\n", hres, *ppv); - return hres; - } - } - } - if(IsEqualGUID(&CLSID_HTMLDocument, rclsid)) { TRACE("(CLSID_HTMLDocument %s %p)\n", debugstr_guid(riid), ppv); return ClassFactory_Create(riid, ppv, HTMLDocument_Create); @@ -245,21 +172,8 @@ HRESULT WINAPI MSHTML_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *pp HRESULT WINAPI MSHTML_DllCanUnloadNow(void) { - fnCanUnloadNow pCanUnloadNow = NULL; - HRESULT hres; - - TRACE("()\n"); - - if(hMozCtl) - pCanUnloadNow = (fnCanUnloadNow) GetProcAddress(hMozCtl, "DllCanUnloadNow"); - if(!pCanUnloadNow) - return S_FALSE; - - hres = pCanUnloadNow(); - - TRACE("hres = %08lx\n", hres); - - return hres; + FIXME("()\n"); + return S_FALSE; } /*********************************************************************** diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 095bb61e82c..eff57a28b34 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -16,6 +16,17 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "nsiface.h" + +#define NS_OK ((nsresult)0x00000000L) +#define NS_NOINTERFACE ((nsresult)0x80004002L) +#define NS_ERROR_NOT_IMPLEMENTED ((nsresult)0x80004001L) + +#define NS_FAILED(res) ((res) & 0x80000000) +#define NS_SUCCEEDED(res) (!NS_FAILED(res)) + +typedef struct NSContainer NSContainer; + typedef struct { const IHTMLDocument2Vtbl *lpHTMLDocument2Vtbl; const IPersistMonikerVtbl *lpPersistMonikerVtbl; @@ -32,6 +43,8 @@ typedef struct { LONG ref; + NSContainer *nscontainer; + IOleClientSite *client; IDocHostUIHandler *hostui; IOleInPlaceSite *ipsite; @@ -44,6 +57,17 @@ typedef struct { BOOL has_key_path; } HTMLDocument; +struct NSContainer { + nsIWebBrowser *webbrowser; + nsIWebNavigation *navigation; + nsIBaseWindow *window; + + HWND hwnd; + + LPWSTR url; /* hack! */ +}; + + #define HTMLDOC(x) ((IHTMLDocument2*) &(x)->lpHTMLDocument2Vtbl) #define PERSIST(x) ((IPersist*) &(x)->lpPersistFileVtbl) #define PERSISTMON(x) ((IPersistMoniker*) &(x)->lpPersistMonikerVtbl) @@ -70,9 +94,14 @@ void HTMLDocument_OleObj_Init(HTMLDocument*); void HTMLDocument_View_Init(HTMLDocument*); void HTMLDocument_Window_Init(HTMLDocument*); void HTMLDocument_Service_Init(HTMLDocument*); +void HTMLDocument_NSContainer_Init(HTMLDocument*); + +void HTMLDocument_NSContainer_Destroy(HTMLDocument*); HRESULT ProtocolFactory_Create(REFCLSID,REFIID,void**); +void close_gecko(void); + DEFINE_GUID(CLSID_AboutProtocol, 0x3050F406, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B); DEFINE_GUID(CLSID_JSProtocol, 0x3050F3B2, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B); DEFINE_GUID(CLSID_MailtoProtocol, 0x3050F3DA, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B); diff --git a/dlls/mshtml/nsembed.c b/dlls/mshtml/nsembed.c new file mode 100644 index 00000000000..e3fd1f16a34 --- /dev/null +++ b/dlls/mshtml/nsembed.c @@ -0,0 +1,294 @@ +/* + * Copyright 2005 Jacek Caban + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" + +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winreg.h" +#include "ole2.h" +#include "docobj.h" + +#include "mshtml.h" +#include "mshtmhst.h" + +#include "wine/debug.h" +#include "wine/unicode.h" + +#include "mshtml_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mshtml); + +DEFINE_GUID(CLSID_StartupNotifier, 0x1f59b001,0x02c9,0x11d5,0xae,0x76,0xcc,0x92,0xf7,0xdb,0x9e,0x03); +DEFINE_GUID(CLSID_nsWebBrowser, 0xf1eac761,0x87e9,0x11d3,0xaf,0x80,0x00,0xa0,0x24,0xff,0xc0,0x8c); + +#define NS_APPSTARTUPNOTIFIER_CONTRACTID "@mozilla.org/embedcomp/appstartup-notifier;1" +#define NS_WEBBROWSER_CONTRACTID "@mozilla.org/embedding/browser/nsWebBrowser;1" + +#define APPSTARTUP_TOPIC "app-startup" + +#define PR_UINT32_MAX 0xffffffff + +typedef struct { + void *d1; + PRUint32 d2; + void *d3; +} nsString; + +static nsresult (*NS_InitXPCOM2)(nsIServiceManager**,void*,void*); +static nsresult (*NS_ShutdownXPCOM)(nsIServiceManager*); +static nsresult (*NS_StringContainerInit)(nsString*); +static nsresult (*NS_StringContainerFinish)(nsString*); +static nsresult (*NS_StringSetData)(nsString*,const PRUnichar*,PRUint32); +static nsresult (*NS_NewLocalFile)(const nsString*,PRBool,nsIFile**); + +static HINSTANCE hXPCOM = NULL; + +static nsIServiceManager *pServMgr = NULL; +static nsIComponentManager *pCompMgr = NULL; + +static BOOL get_mozilla_path(PRUnichar *gre_path) +{ + DWORD res, type, i, size = MAX_PATH; + HKEY mozilla_key, hkey; + WCHAR key_name[100]; + BOOL ret = FALSE; + + static const WCHAR wszGreKey[] = + {'S','o','f','t','w','a','r','e','\\', + 'm','o','z','i','l','l','a','.','o','r','g','\\', + 'G','R','E',0}; + + static const WCHAR wszGreHome[] = {'G','r','e','H','o','m','e',0}; + + res = RegOpenKeyW(HKEY_LOCAL_MACHINE, wszGreKey, &mozilla_key); + if(res != ERROR_SUCCESS) { + TRACE("Could not open key %s\n", debugstr_w(wszGreKey)); + return FALSE; + } + + for(i=0; !ret && RegEnumKeyW(mozilla_key, i, key_name, sizeof(key_name)/sizeof(WCHAR)) == ERROR_SUCCESS; i++) { + RegOpenKeyW(mozilla_key, key_name, &hkey); + res = RegQueryValueExW(hkey, wszGreHome, NULL, &type, (LPBYTE)gre_path, &size); + if(res == ERROR_SUCCESS) + ret = TRUE; + RegCloseKey(hkey); + } + + RegCloseKey(mozilla_key); + return ret; +} + +static BOOL get_mozctl_path(PRUnichar *gre_path) +{ + HKEY hkey; + DWORD res, type, size = MAX_PATH; + + static const WCHAR wszMozCtlKey[] = + {'S','o','f','t','w','a','r','e','\\','M','o','z','i','l','l','a',0}; + static const WCHAR wszBinDirectoryPath[] = + {'B','i','n','D','i','r','e','c','t','o','r','y','P','a','t','h',0}; + + res = RegOpenKeyW(HKEY_LOCAL_MACHINE, wszMozCtlKey, &hkey); + if(res != ERROR_SUCCESS) { + TRACE("Could not open key %s\n", debugstr_w(wszMozCtlKey)); + return FALSE; + } + + res = RegQueryValueExW(hkey, wszBinDirectoryPath, NULL, &type, (LPBYTE)gre_path, &size); + if(res != ERROR_SUCCESS) { + ERR("Could not get value %s\n", debugstr_w(wszBinDirectoryPath)); + return FALSE; + } + + return TRUE; +} + + + +static BOOL load_gecko() +{ + nsresult nsres; + nsIObserver *pStartNotif; + nsString path; + nsIFile *gre_dir; + PRUnichar gre_path[MAX_PATH]; + + static BOOL tried_load = FALSE; + static const WCHAR strXPCOM[] = {'x','p','c','o','m','.','d','l','l',0}; + + TRACE("()\n"); + + if(tried_load) + return pCompMgr != NULL; + tried_load = TRUE; + + if(!(get_mozctl_path(gre_path) || get_mozilla_path(gre_path))) { + MESSAGE("Could not load Mozilla. HTML rendering will be disabled.\n"); + return FALSE; + } + + TRACE("found path %s\n", debugstr_w(gre_path)); + + hXPCOM = LoadLibraryW(strXPCOM); + if(!hXPCOM) { + /* FIXME: + * We don't have any SetDllDirectory implementation so we have to modify PATH, + * as XPCOM loads other DLLs from this directory. + */ + WCHAR path_env[MAX_PATH]; + static WCHAR wszPATH[] = {'P','A','T','H',0}; + int len; + + TRACE("here\n"); + + GetEnvironmentVariableW(wszPATH, path_env, sizeof(path_env)/sizeof(WCHAR)); + len = strlenW(path_env); + path_env[len++] = ';'; + strcpyW(path_env+len, gre_path); + SetEnvironmentVariableW(wszPATH, path_env); + + hXPCOM = LoadLibraryW(strXPCOM); + if(!hXPCOM) { + ERR("Could not load XPCOM: %ld\n", GetLastError()); + return FALSE; + } + } + +#define NS_DLSYM(func) \ + func = (typeof(func))GetProcAddress(hXPCOM, #func); \ + if(!func) \ + ERR("Could not GetProcAddress(" #func ") failed\n"); + + NS_DLSYM(NS_InitXPCOM2) + NS_DLSYM(NS_ShutdownXPCOM) + NS_DLSYM(NS_StringContainerInit) + NS_DLSYM(NS_StringContainerFinish) + NS_DLSYM(NS_StringSetData) + NS_DLSYM(NS_NewLocalFile) + +#undef NS_DLSYM + + NS_StringContainerInit(&path); + NS_StringSetData(&path, gre_path, PR_UINT32_MAX); + nsres = NS_NewLocalFile(&path, FALSE, &gre_dir); + NS_StringContainerFinish(&path); + if(NS_FAILED(nsres)) { + ERR("NS_NewLocalFile failed: %08lx\n", nsres); + FreeLibrary(hXPCOM); + return FALSE; + } + + nsres = NS_InitXPCOM2(&pServMgr, gre_dir, NULL); + if(NS_FAILED(nsres)) { + ERR("NS_InitXPCOM2 failed: %08lx\n", nsres); + FreeLibrary(hXPCOM); + return FALSE; + } + + nsres = nsIServiceManager_QueryInterface(pServMgr, &IID_nsIComponentManager, (void**)&pCompMgr); + if(NS_FAILED(nsres)) + ERR("Could not get nsIComponentManager: %08lx\n", nsres); + + nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr, NS_APPSTARTUPNOTIFIER_CONTRACTID, + NULL, &IID_nsIObserver, (void**)&pStartNotif); + if(NS_SUCCEEDED(nsres)) { + nsres = nsIObserver_Observe(pStartNotif, NULL, APPSTARTUP_TOPIC, NULL); + if(NS_FAILED(nsres)) + ERR("Observe failed: %08lx\n", nsres); + + nsIObserver_Release(pStartNotif); + }else { + ERR("could not get appstartup-notifier: %08lx\n", nsres); + } + + return TRUE; +} + +void close_gecko() +{ + TRACE("()\n"); + + if(pCompMgr) + nsIComponentManager_Release(pCompMgr); + + if(pServMgr) + nsIServiceManager_Release(pServMgr); + + if(hXPCOM) + FreeLibrary(hXPCOM); +} + +void HTMLDocument_NSContainer_Init(HTMLDocument *This) +{ + NSContainer *ret; + nsIWebBrowserSetup *wbsetup; + nsresult nsres; + + This->nscontainer = NULL; + + if(!load_gecko()) + return; + + ret = HeapAlloc(GetProcessHeap(), 0, sizeof(NSContainer)); + ret->url = NULL; + + nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr, + NS_WEBBROWSER_CONTRACTID, NULL, &IID_nsIWebBrowser, (void**)&ret->webbrowser); + if(NS_FAILED(nsres)) + ERR("Creating WebBrowser failed: %08lx\n", nsres); + + nsres = nsIWebBrowser_QueryInterface(ret->webbrowser, &IID_nsIBaseWindow, + (void**)&ret->window); + if(NS_FAILED(nsres)) + ERR("Could not get nsIBaseWindow interface: %08lx\n", nsres); + + nsres = nsIWebBrowser_QueryInterface(ret->webbrowser, + &IID_nsIWebBrowserSetup, (void**)&wbsetup); + if(NS_SUCCEEDED(nsres)) { + nsres = nsIWebBrowserSetup_SetProperty(wbsetup, SETUP_IS_CHROME_WRAPPER, TRUE); + if(NS_FAILED(nsres)) + ERR("SetProperty failed: %08lx\n", nsres); + nsIWebBrowserSetup_Release(wbsetup); + }else { + ERR("Could not get nsIWebBrowserSetup interface\n"); + } + + nsres = nsIWebBrowser_QueryInterface(ret->webbrowser, &IID_nsIWebNavigation, + (void**)&ret->navigation); + if(NS_FAILED(nsres)) + ERR("Could not get nsIWebNavigation interface: %08lx\n", nsres); + + This->nscontainer = ret; +} + +void HTMLDocument_NSContainer_Destroy(HTMLDocument *This) +{ + TRACE("(%p)\n", This); + + nsIWebBrowser_Release(This->nscontainer->webbrowser); + nsIWebNavigation_Release(This->nscontainer->navigation); + nsIBaseWindow_Release(This->nscontainer->window); + + HeapFree(GetProcessHeap(), 0, This->nscontainer); +} diff --git a/dlls/mshtml/nsiface.idl b/dlls/mshtml/nsiface.idl new file mode 100644 index 00000000000..05b1160887b --- /dev/null +++ b/dlls/mshtml/nsiface.idl @@ -0,0 +1,241 @@ +/* + * Copyright 2005 Jacek Caban + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * NOTE: + * This file is not an usual idl file. Interfaces in this file are XPCOM interfaces + * (NOT MSCOM!), but we generate the header file with WIDL compatibile with XPCOM, + * useable in C code. + */ + +import "wtypes.idl"; + +typedef HRESULT nsresult; +typedef ULONG nsrefcnt; + +typedef IID nsIID; +typedef nsIID nsCID; +typedef REFIID nsIIDRef; +typedef nsIIDRef nsCIDRef; + +typedef void** nsQIResult; +typedef LPSTR nsstring; +typedef WCHAR PRUnichar; +typedef LPWSTR nswstring; +typedef ULONG PRUint32; +typedef LONG PRInt32; +typedef BOOL PRBool; +typedef LARGE_INTEGER PRInt64; + +typedef int nsAString; +typedef int nsACString; + +interface nsIWebBrowserChrome; + +[ + object, + uuid(00000000-0000-0000-c000-000000000046) +] +interface nsISupports +{ + nsresult QueryInterface(nsIIDRef riid, nsQIResult result); + nsrefcnt AddRef(); + nsrefcnt Release(); +} + +/* Currently we don't need a full declaration of these interfaces */ +typedef nsISupports nsIWeakReference; +typedef nsISupports nsIURIContentListener; +typedef nsISupports nsIDOMWindow; +typedef nsISupports nsIInputStream; +typedef nsISupports nsIDOMDocument; +typedef nsISupports nsIURI; +typedef nsISupports nsISHistory; +typedef nsISupports nsISimpleEnumerator; +typedef nsISupports nsIWidget; + +[ + object, + uuid(8bb35ed9-e332-462d-9155-4a002ab5c958) +] +interface nsIServiceManager : nsISupports +{ + nsresult GetService(nsCIDRef aClass, nsIIDRef aIID, void **result); + nsresult GetServiceByContactID(nsstring aContactID, nsIIDRef aIID, void **result); + nsresult IsServiceInstantiated(nsCIDRef aClass, nsIIDRef aIID, BOOL *_retval); + nsresult IsServiceInstantiatedByContractID(nsstring aContractID, nsIIDRef aIID, BOOL *_retval); +} + +[ + object, + uuid(db242e01-e4d9-11d2-9dde-000064657374) +] +interface nsIObserver : nsISupports +{ + nsresult Observe(nsISupports *aSubject, nsstring aTopic, nswstring aData); +} + +[ + object, + uuid(a88e5a60-205a-4bb1-94e1-2628daf51eae) +] +interface nsIComponentManager : nsISupports +{ + nsresult GetClassObject(nsCIDRef aClass, nsIIDRef aIID, nsQIResult result); + nsresult GetClassObjectByContractID(nsstring aContractID, nsIIDRef aIID, nsQIResult result); + nsresult CreateInstance(nsCIDRef aClass, nsISupports *aDelegate, nsIIDRef aIID, + nsQIResult result); + nsresult CreateInstanceByContractID(nsstring aContractID, nsISupports *aDelegate, + nsIIDRef aIID, nsQIResult result); +} + +[ + object, + uuid(69e5df00-7b8b-11d3-af61-00a024ffc08c) +] +interface nsIWebBrowser : nsISupports +{ + nsresult AddWebBrowserListener(nsIWeakReference *aListener, const nsIID *aIID); + nsresult RemoveWebBrowserListener(nsIWeakReference *aListener, const nsIID *aIID); + nsresult GetContainerWindow(nsIWebBrowserChrome **aContainerWindow); + nsresult SetContainerWindow(nsIWebBrowserChrome *aContainerWindow); + nsresult GetParentURIContentListener(nsIURIContentListener **aParentURIContentListener); + nsresult SetParentURIContentListener(nsIURIContentListener *aParentURIContentListener); + nsresult GetContentDOMWindow(nsIDOMWindow **aContentDOMWindow); +} + +cpp_quote("#define SETUP_IS_CHROME_WRAPPER 7"); + +[ + object, + uuid(f15398a0-8018-11d3-af70-00a024ffc08c) +] +interface nsIWebBrowserSetup : nsISupports +{ + nsresult SetProperty(PRUint32 aId, PRUint32 aValue); +} + +typedef void* nativeWindow; + +[ + object, + uuid(046bc8a0-8015-11d3-af70-00a024ffc08c) +] +interface nsIBaseWindow : nsISupports +{ + nsresult InitWindow(nativeWindow parentNativeWindow, nsIWidget *parentWidget, PRInt32 x, + PRInt32 y, PRInt32 cx, PRInt32 cy); + nsresult Create(); + nsresult Destroy(); + nsresult SetPosition(PRInt32 x, PRInt32 y); + nsresult GetPosition(PRInt32 *x, PRInt32 *y); + nsresult SetSize(PRInt32 cx, PRInt32 cy, PRBool fRepaint); + nsresult GetSize(PRInt32 *cx, PRInt32 *cy); + nsresult SetPositionAndSize(PRInt32 x, PRInt32 y, PRInt32 cx, PRInt32 cy, PRBool fRepaint); + nsresult GetPositionAndSize(PRInt32 *x, PRInt32 *y, PRInt32 *cx, PRInt32 *cy); + nsresult Repaint(PRBool force); + nsresult GetParentWidget(nsIWidget **aParentWidget); + nsresult SetParentWidget(nsIWidget *aParentWidget); + nsresult GetParentNativeWindow(nativeWindow *aParentNativeWindow); + nsresult SetParentNativeWindow(nativeWindow aParentNativeWindow); + nsresult GetVisibility(PRBool *aVisibility); + nsresult SetVisibility(PRBool aVisibility); + nsresult GetEnabled(PRBool *aEnabled); + nsresult SetEnabled(PRBool aEnabled); + nsresult GetBlurSuppression(PRBool *aBlurSuppression); + nsresult SetBlurSuppression(PRBool aBlurSuppression); + nsresult GetMainWidget(nsIWidget **aMainWidget); + nsresult SetFocus(); + nsresult GetTitle(PRUnichar **aTitle); + nsresult SetTitle(const PRUnichar *aTitle); +} + +cpp_quote("#define LOAD_FLAGS_NONE 0"); + +[ + object, + uuid(f5d9e7b0-d930-11d3-b057-00a024ffc08c) +] +interface nsIWebNavigation : nsISupports +{ + nsresult GetCanGoBack(PRBool *aCanGoBack); + nsresult GetCanGoForward(PRBool *aCanGoForward); + nsresult GoBack(); + nsresult GoForward(); + nsresult GotoIndex(PRInt32 index); + nsresult LoadURI(const PRUnichar *aURI, PRUint32 aLoadFlags, nsIURI *aReferrer, + nsIInputStream *aPostData, nsIInputStream *aHeaders); + nsresult Reload(PRUint32 aReloadFlags); + nsresult Stop(PRUint32 aStopFlags); + nsresult GetDocument(nsIDOMDocument **aDocument); + nsresult GetCurrentURI(nsIURI **aCurrentURI); + nsresult GetReferringURI(nsIURI **aReferringURI); + nsresult GetSessionHistory(nsISHistory **aSessionHistory); + nsresult SetSessionHistory(nsISHistory *aSessionHistory); +} + +[ + object, + uuid(c8c0a080-0868-11d3-915f-d9d889d48e3c) +] +interface nsIFile : nsISupports +{ + nsresult Append(const nsAString *node); + nsresult AppendNative(const nsAString *node); + nsresult Normalize(); + nsresult Create(PRUint32 type, PRUint32 permission); + nsresult GetLeafName(nsAString *aLeafName); + nsresult SetLeafName(const nsAString *aLeafName); + nsresult GetNativeLeafName(nsAString *aLeafName); + nsresult SetNativeLeafName(const nsAString *aLeafName); + nsresult CopyTo(nsIFile *newParentDir, const nsAString *newName); + nsresult CopyToNative(nsIFile *newParentDir, const nsAString *newName); + nsresult CopyToFollowingLinks(nsIFile *newParentDir, const nsAString *newName); + nsresult CopyToFollowingLinksNative(nsIFile *newParentDir, const nsAString *newName); + nsresult MoveTo(nsIFile *newParentDir, const nsAString *newName); + nsresult MoveToNative(nsIFile *newParentDir, const nsAString *newName); + nsresult Remove(PRBool recursive); + nsresult GetPermissions(PRUint32 *aPermissions); + nsresult SetPermissions(PRUint32 pPermissions); + nsresult GetPermissionsOfLink(PRUint32 *aPermissions); + nsresult SetPermissionsOfLink(PRUint32 pPermissions); + nsresult GetLastModifiedTime(PRInt64 *aLastModifiedTime); + nsresult SetLastModifiedTime(PRInt64 aLastModifiedTime); + nsresult GetFileSize(PRInt64 *aFileSize); + nsresult SetFileSize(PRInt64 aFileSize); + nsresult GetFileSizeOfLink(PRInt64 *aFileSizeOfLink); + nsresult GetTarget(nsAString *aTarget); + nsresult GetNativeTarget(nsACString *aNativeTarget); + nsresult GetPath(nsAString *aPath); + nsresult GetNativePath(nsACString *aNativePath); + nsresult Exists(PRBool *_retval); + nsresult IsWritable(PRBool *_retval); + nsresult IsReadable(PRBool *_retval); + nsresult IsExecutable(PRBool *_retval); + nsresult IsHidden(PRBool *_retval); + nsresult IsDirectory(PRBool *_retval); + nsresult IsFile(PRBool *_retval); + nsresult IsSymlink(PRBool *_retval); + nsresult IsSpecial(PRBool *_retval); + nsresult CreateUnique(PRUint32 type, PRUint32 permission); + nsresult Clone(nsIFile **_retval); + nsresult Equals(nsIFile *inFile, PRBool *_retval); + nsresult Contains(nsIFile *inFile, PRBool recir, PRBool *_retval); + nsresult GetParent(nsIFile **aParent); + nsresult GetDirectoryEntries(nsISimpleEnumerator **aDirectoryEntries); +} diff --git a/dlls/mshtml/persist.c b/dlls/mshtml/persist.c index eff8d5ba949..2e08d4accf5 100644 --- a/dlls/mshtml/persist.c +++ b/dlls/mshtml/persist.c @@ -79,7 +79,34 @@ static HRESULT WINAPI PersistMoniker_IsDirty(IPersistMoniker *iface) static HRESULT WINAPI PersistMoniker_Load(IPersistMoniker *iface, BOOL fFullyAvailable, IMoniker *pimkName, LPBC pibc, DWORD grfMode) { + PERSISTMON_THIS + LPWSTR url; + HRESULT hres; + nsresult nsres; + FIXME("(%p)->(%x %p %p %08lx)\n", iface, fFullyAvailable, pimkName, pibc, grfMode); + + /* FIXME: + * This is a HACK, we should use moniker's BindToStorage instead of Gecko's LoadURI. + */ + if(This->nscontainer) { + hres = IMoniker_GetDisplayName(pimkName, pibc, NULL, &url); + if(FAILED(hres)) { + WARN("GetDiaplayName failed: %08lx\n", hres); + return hres; + } + TRACE("got url: %s\n", debugstr_w(url)); + + if(This->hwnd) { + nsres = nsIWebNavigation_LoadURI(This->nscontainer->navigation, url, + LOAD_FLAGS_NONE, NULL, NULL, NULL); + if(NS_FAILED(nsres)) + WARN("LoadURI failed: %08lx\n", nsres); + }else { + This->nscontainer->url = url; + } + } + return S_OK; } diff --git a/dlls/mshtml/view.c b/dlls/mshtml/view.c index d2f8ce6ddf5..f4d8b14f2ba 100644 --- a/dlls/mshtml/view.c +++ b/dlls/mshtml/view.c @@ -69,10 +69,73 @@ static void paint_disabled(HWND hwnd) { DeleteObject(brush); } +static void activate_gecko(HTMLDocument *This) +{ + RECT rect; + nsresult nsres; + + TRACE("(%p) %p\n", This, This->nscontainer->window); + + GetClientRect(This->hwnd, &rect); + + nsres = nsIBaseWindow_InitWindow(This->nscontainer->window, This->hwnd, NULL, + 0, 0, rect.right, rect.bottom); + + if(nsres == NS_OK) { + nsres = nsIBaseWindow_Create(This->nscontainer->window); + if(NS_FAILED(nsres)) + WARN("Creating window failed: %08lx\n", nsres); + + nsIBaseWindow_SetVisibility(This->nscontainer->window, TRUE); + nsIBaseWindow_SetEnabled(This->nscontainer->window, TRUE); + }else { + ERR("Initializing window failed: %08lx\n", nsres); + } + + if(This->nscontainer->url) { + TRACE("Loading url: %s\n", debugstr_w(This->nscontainer->url)); + nsres = nsIWebNavigation_LoadURI(This->nscontainer->navigation, This->nscontainer->url, + LOAD_FLAGS_NONE, NULL, NULL, NULL); + if(NS_FAILED(nsres)) + ERR("LoadURI failed: %08lx\n", nsres); + This->nscontainer->url = NULL; + } +} + static LRESULT WINAPI serverwnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if(msg == WM_PAINT) - paint_disabled(hwnd); + HTMLDocument *This; + + static const WCHAR wszTHIS[] = {'T','H','I','S',0}; + + if(msg == WM_CREATE) { + This = *(HTMLDocument**)lParam; + SetPropW(hwnd, wszTHIS, This); + }else { + This = (HTMLDocument*)GetPropW(hwnd, wszTHIS); + } + + switch(msg) { + case WM_CREATE: + This->hwnd = hwnd; + if(This->nscontainer) + activate_gecko(This); + break; + case WM_PAINT: + if(!This->nscontainer) + paint_disabled(hwnd); + break; + case WM_SIZE: + TRACE("(%p)->(WM_SIZE)\n", This); + + if(This->nscontainer) { + nsresult nsres; + nsres = nsIBaseWindow_SetSize(This->nscontainer->window, + LOWORD(lParam), HIWORD(lParam), TRUE); + if(NS_FAILED(nsres)) + WARN("SetSize failed: %08lx\n", nsres); + } + } return DefWindowProcW(hwnd, msg, wParam, lParam); } @@ -91,7 +154,6 @@ static void register_serverwnd_class(void) serverwnd_class = RegisterClassExW(&wndclass); } - /********************************************************** * IOleDocumentView implementation */ @@ -269,10 +331,13 @@ static HRESULT WINAPI OleDocumentView_UIActivate(IOleDocumentView *iface, BOOL f posrect.left, posrect.top, posrect.right-posrect.left, posrect.bottom-posrect.top, SWP_NOACTIVATE | SWP_SHOWWINDOW); }else { - This->hwnd = CreateWindowExW(0, wszInternetExplorer_Server, NULL, + CreateWindowExW(0, wszInternetExplorer_Server, NULL, WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, posrect.left, posrect.top, posrect.right-posrect.left, posrect.bottom-posrect.top, parent_hwnd, NULL, hInst, This); + + TRACE("Created window %p\n", This->hwnd); + SetWindowPos(This->hwnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE | SWP_SHOWWINDOW); RedrawWindow(This->hwnd, NULL, NULL, RDW_INVALIDATE | RDW_NOERASE | RDW_ALLCHILDREN); -- GitLab