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 }