1 /*******************************************************************************
2  * Copyright (c) 2003, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  * Port to the D programming language:
11  *      John Reimer <terminal.node@gmail.com>
12  *******************************************************************************/
13 module org.eclipse.swt.browser.WindowCreator2;
14 
15 import java.lang.all;
16 
17 import org.eclipse.swt.SWT;
18 import org.eclipse.swt.graphics.Point;
19 
20 import org.eclipse.swt.internal.Platform;
21 import org.eclipse.swt.internal.mozilla.Common;
22 
23 import XPCOM = org.eclipse.swt.internal.mozilla.XPCOM;
24 
25 import org.eclipse.swt.internal.mozilla.nsIBaseWindow;
26 import org.eclipse.swt.internal.mozilla.nsID;
27 import org.eclipse.swt.internal.mozilla.nsISupports;
28 import org.eclipse.swt.internal.mozilla.nsIURI;
29 import org.eclipse.swt.internal.mozilla.nsIWebBrowser;
30 import org.eclipse.swt.internal.mozilla.nsIWebBrowserChrome;
31 import org.eclipse.swt.internal.mozilla.nsIWindowCreator;
32 import org.eclipse.swt.internal.mozilla.nsIWindowCreator2;
33 import org.eclipse.swt.internal.mozilla.nsStringAPI;
34 import org.eclipse.swt.internal.mozilla.nsEmbedString;
35 
36 import org.eclipse.swt.layout.FillLayout;
37 import org.eclipse.swt.widgets.Shell;
38 
39 import org.eclipse.swt.browser.Browser;
40 import org.eclipse.swt.browser.Mozilla;
41 import org.eclipse.swt.browser.VisibilityWindowListener;
42 import org.eclipse.swt.browser.CloseWindowListener;
43 import org.eclipse.swt.browser.WindowEvent;
44 
45 class WindowCreator2 : nsIWindowCreator2 {
46     int refCount = 0;
47 
48 this () {}
49 
50 extern(System)
51 nsrefcnt AddRef () {
52     refCount++;
53     return refCount;
54 }
55 
56 extern(System)
57 nsresult QueryInterface (in cnsID* riid, void** ppvObject) {
58     if (riid is null || ppvObject is null) return XPCOM.NS_ERROR_NO_INTERFACE;
59     //nsID guid = new nsID ();
60     //XPCOM.memmove (guid, riid, nsID.sizeof);
61     
62     if (*riid == nsISupports.IID) {
63         *ppvObject = cast(void*)cast(nsISupports)this;
64         AddRef ();
65         return XPCOM.NS_OK;
66     }
67     if (*riid == nsIWindowCreator.IID) {
68         *ppvObject = cast(void*)cast(nsIWindowCreator)this;
69         AddRef ();
70         return XPCOM.NS_OK;
71     }
72     if (*riid == nsIWindowCreator2.IID) {
73         *ppvObject = cast(void*)cast(nsIWindowCreator2)this;
74         AddRef ();
75         return XPCOM.NS_OK;
76     }
77 
78     *ppvObject = null;
79     return XPCOM.NS_ERROR_NO_INTERFACE;
80 }
81 
82 extern(System)
83 nsresult Release () {
84     refCount--;
85     //if (refCount is 0) disposeCOMInterfaces ();
86     return refCount;
87 }
88 
89 /* nsIWindowCreator */
90 
91 extern(System)
92 nsresult CreateChromeWindow (nsIWebBrowserChrome parent, PRUint32 chromeFlags, nsIWebBrowserChrome* _retval) {
93     return CreateChromeWindow2 (parent, chromeFlags, 0, null, null, _retval);
94 }
95 
96 /* nsIWindowCreator2 */
97 
98 extern(System)
99 nsresult CreateChromeWindow2 (nsIWebBrowserChrome parent, PRUint32 chromeFlags, PRUint32 contextFlags, nsIURI uri, PRBool* cancel, nsIWebBrowserChrome* _retval) {
100     if (parent is null && (chromeFlags & nsIWebBrowserChrome.CHROME_OPENAS_CHROME) is 0) {
101         return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
102     }
103     Browser src = null; 
104     if (parent !is null) {
105         //nsIWebBrowserChrome browserChromeParent = new nsIWebBrowserChrome (parent);
106         nsIWebBrowser webBrowser;
107         int rc = parent.GetWebBrowser (&webBrowser);
108         if (rc !is XPCOM.NS_OK) Mozilla.error (rc);
109         if (webBrowser is null) Mozilla.error (XPCOM.NS_ERROR_NO_INTERFACE);
110 
111         //nsIWebBrowser webBrowser = new nsIWebBrowser (aWebBrowser[0]);
112         nsIBaseWindow baseWindow;
113         rc = webBrowser.QueryInterface (&nsIBaseWindow.IID, cast(void**)&baseWindow);
114         if (rc !is XPCOM.NS_OK) Mozilla.error (rc);
115         if (baseWindow is null) Mozilla.error (XPCOM.NS_ERROR_NO_INTERFACE);
116         webBrowser.Release ();
117 
118         //nsIBaseWindow baseWindow = new nsIBaseWindow (result[0]);
119         //result[0] = 0;
120         nativeWindow aParentNativeWindow;  // nativeWindow is "void*" (represents GtkWidget*)
121         rc = baseWindow.GetParentNativeWindow (&aParentNativeWindow);
122         if (rc !is XPCOM.NS_OK) Mozilla.error (rc);
123         if (aParentNativeWindow is null) Mozilla.error (XPCOM.NS_ERROR_NO_INTERFACE);
124         baseWindow.Release ();
125 
126         src = Mozilla.findBrowser (aParentNativeWindow);
127     }
128     Browser browser;
129     bool doit = true;
130     if ((chromeFlags & nsIWebBrowserChrome.CHROME_OPENAS_CHROME) !is 0) {
131         /*
132         * Mozilla will request a new Browser in a modal window in order to emulate a native
133         * dialog that is not available to it (eg.- a print dialog on Linux).  For this
134         * reason modal requests are handled here so that the user is not exposed to them.
135         */
136         int style = SWT.DIALOG_TRIM;
137         if ((chromeFlags & nsIWebBrowserChrome.CHROME_MODAL) !is 0) style |= SWT.APPLICATION_MODAL; 
138         Shell shell = src is null ?
139             new Shell (style) :
140             new Shell (src.getShell(), style);
141         shell.setLayout (new FillLayout ());
142         browser = new Browser (shell, src is null ? SWT.MOZILLA : src.getStyle () & SWT.MOZILLA);
143         browser.addVisibilityWindowListener (new class(shell) VisibilityWindowListener {
144             Shell sh;
145             this (Shell shell) { this.sh = shell; }
146             public void hide (WindowEvent event) {
147             }
148             public void show (WindowEvent event) {
149                 if (event.location !is null) sh.setLocation (event.location);
150                 if (event.size !is null) {
151                     Point size = event.size;
152                     sh.setSize (sh.computeSize (size.x, size.y));
153                 }
154                 shell.open ();
155             }
156         });
157         browser.addCloseWindowListener (new class(shell) CloseWindowListener {
158             Shell sh;
159             this (Shell shell) { this.sh = shell; }
160             public void close (WindowEvent event) {
161                 sh.close ();
162             }
163         });
164         if (uri !is null) {
165             //nsIURI location = new nsIURI (uri);
166             scope auto aSpec = new nsEmbedCString;
167             if (uri.GetSpec (cast(nsACString*)aSpec) is XPCOM.NS_OK) {
168                 int span = aSpec.toString().length;
169                 if (span > 0) {
170                     //ptrdiff_t buffer = XPCOM.nsEmbedCString_get (aSpec);
171                     // byte[] dest = new byte[length];
172                     //XPCOM.memmove (dest, buffer, length);
173                     browser.setUrl (aSpec.toString);
174                 }
175             }
176             //XPCOM.nsEmbedCString_delete (aSpec);
177         }
178     } else {
179         WindowEvent event = new WindowEvent (src);
180         event.display = src.getDisplay ();
181         event.widget = src;
182         event.required = true;
183         for (int i = 0; i < src.webBrowser.openWindowListeners.length; i++) {
184             src.webBrowser.openWindowListeners[i].open (event);
185         }
186         browser = event.browser;
187 
188         /* Ensure that the Browser provided by the client is valid for use */ 
189         doit = browser !is null && !browser.isDisposed ();
190         if (doit) {
191             String platform = Platform.PLATFORM;
192             bool isMozillaNativePlatform = platform == "gtk" || platform == "motif"; //$NON-NLS-1$ //$NON-NLS-2$
193             doit = isMozillaNativePlatform || (browser.getStyle () & SWT.MOZILLA) !is 0;
194         }
195     }
196     if (doit) {
197         // STRANGE but TRUE:  browser.webBrowser is always instantiated as Mozilla (on this platform),
198         // so it can be cast back to the subclass Mozilla safely.  Looks very dangerous, though... 
199         // considering the next few lines of code that cast the Mozilla class to the interface, 
200         // nsIWebBrowserChrome.
201         // This is an ugly D conversion hack because interfaces are implemented differently than 
202         // in the Java SWT version.  Watch this code section carefully for errors/bugs. -JJR
203         Mozilla mozilla = cast(Mozilla)browser.webBrowser;
204         mozilla.isChild = true;
205         // And since Mozilla class implements the nsIWebBrowserChrome interface....
206         nsIWebBrowserChrome chrome;
207         nsresult rc = mozilla.QueryInterface( &nsIWebBrowserChrome.IID, cast(void**)&chrome);
208         if (rc !is XPCOM.NS_OK) Mozilla.error (rc);
209         //nsIWebBrowserChrome webBrowserChrome = new nsIWebBrowserChrome (chromePtr);
210         chrome.SetChromeFlags (chromeFlags);
211         //chrome.AddRef ();
212         //XPCOM.memmove (_retval, new ptrdiff_t[] {chromePtr}, C.PTR_SIZEOF);
213         *_retval = chrome;
214     } else {
215         if (cancel !is null) {
216             *cancel = 1;   /* PRBool */
217         }
218     }
219     return doit ? XPCOM.NS_OK : XPCOM.NS_ERROR_NOT_IMPLEMENTED;
220 }
221 }