MSHTML: Use Gecko to render HTML

Jacek Caban jack at itma.pwr.wroc.pl
Thu Jul 28 14:45:57 CDT 2005


Changelog:
    - Use Gecko to render HTML
    - Get rid of Mozilla ActiveX Control in MSHTML
-------------- next part --------------
Index: dlls/mshtml/.cvsignore
===================================================================
RCS file: /home/wine/wine/dlls/mshtml/.cvsignore,v
retrieving revision 1.4
diff -u -p -r1.4 .cvsignore
--- dlls/mshtml/.cvsignore	25 Jun 2005 17:58:35 -0000	1.4
+++ dlls/mshtml/.cvsignore	28 Jul 2005 19:40:44 -0000
@@ -1,4 +1,5 @@
 Makefile
 libmshtml.def
 mshtml.dll.dbg.c
+nsiface.h
 rsrc.res
Index: dlls/mshtml/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/mshtml/Makefile.in,v
retrieving revision 1.18
diff -u -p -r1.18 Makefile.in
--- dlls/mshtml/Makefile.in	18 Jul 2005 09:13:32 -0000	1.18
+++ dlls/mshtml/Makefile.in	28 Jul 2005 19:40:44 -0000
@@ -11,6 +11,7 @@ EXTRADEFS = -DCOM_NO_WINDOWS_H
 C_SRCS = \
 	htmldoc.c \
 	main.c \
+	nsembed.c \
 	oleobj.c \
 	olewnd.c \
 	persist.c \
@@ -19,6 +20,8 @@ C_SRCS = \
 	view.c
 
 RC_SRCS = rsrc.rc
+
+IDL_SRCS = nsiface.idl
 
 SUBDIRS = tests
 
Index: dlls/mshtml/htmldoc.c
===================================================================
RCS file: /home/wine/wine/dlls/mshtml/htmldoc.c,v
retrieving revision 1.12
diff -u -p -r1.12 htmldoc.c
--- dlls/mshtml/htmldoc.c	14 Jul 2005 10:14:33 -0000	1.12
+++ dlls/mshtml/htmldoc.c	28 Jul 2005 19:40:45 -0000
@@ -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_Query
 
 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(
 
 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
             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 *pU
     HTMLDocument_View_Init(ret);
     HTMLDocument_Window_Init(ret);
     HTMLDocument_Service_Init(ret);
+    HTMLDocument_NSContainer_Init(ret);
 
     return hres;
 }
Index: dlls/mshtml/main.c
===================================================================
RCS file: /home/wine/wine/dlls/mshtml/main.c,v
retrieving revision 1.16
diff -u -p -r1.16 main.c
--- dlls/mshtml/main.c	14 Jul 2005 12:18:30 -0000	1.16
+++ dlls/mshtml/main.c	28 Jul 2005 19:40:45 -0000
@@ -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(REFII
 
 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(
 
 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;
 }
 
 /***********************************************************************
Index: dlls/mshtml/mshtml_private.h
===================================================================
RCS file: /home/wine/wine/dlls/mshtml/mshtml_private.h,v
retrieving revision 1.16
diff -u -p -r1.16 mshtml_private.h
--- dlls/mshtml/mshtml_private.h	18 Jul 2005 09:13:32 -0000	1.16
+++ dlls/mshtml/mshtml_private.h	28 Jul 2005 19:40:45 -0000
@@ -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,8 +94,13 @@ void HTMLDocument_OleObj_Init(HTMLDocume
 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);
Index: dlls/mshtml/persist.c
===================================================================
RCS file: /home/wine/wine/dlls/mshtml/persist.c,v
retrieving revision 1.4
diff -u -p -r1.4 persist.c
--- dlls/mshtml/persist.c	12 Jul 2005 17:00:58 -0000	1.4
+++ dlls/mshtml/persist.c	28 Jul 2005 19:40:45 -0000
@@ -79,7 +79,34 @@ static HRESULT WINAPI PersistMoniker_IsD
 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;
 }
 
Index: dlls/mshtml/view.c
===================================================================
RCS file: /home/wine/wine/dlls/mshtml/view.c,v
retrieving revision 1.10
diff -u -p -r1.10 view.c
--- dlls/mshtml/view.c	18 Jul 2005 09:13:32 -0000	1.10
+++ dlls/mshtml/view.c	28 Jul 2005 19:40:46 -0000
@@ -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(voi
     serverwnd_class = RegisterClassExW(&wndclass);
 }
 
-
 /**********************************************************
  * IOleDocumentView implementation
  */
@@ -269,10 +331,13 @@ static HRESULT WINAPI OleDocumentView_UI
                     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);
--- /dev/null	1970-01-01 01:00:00.000000000 +0100
+++ dlls/mshtml/nsiface.idl	2005-07-28 21:41:24.000000000 +0200
@@ -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);
+}
--- /dev/null	1970-01-01 01:00:00.000000000 +0100
+++ dlls/mshtml/nsembed.c	2005-07-28 21:44:34.000000000 +0200
@@ -0,0 +1,295 @@
+/*
+ * 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);
+}
+


More information about the wine-patches mailing list