diff options
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT Mozilla/carbon/org/eclipse/swt/browser/MozillaDelegate.java')
-rw-r--r-- | bundles/org.eclipse.swt/Eclipse SWT Mozilla/carbon/org/eclipse/swt/browser/MozillaDelegate.java | 260 |
1 files changed, 260 insertions, 0 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Mozilla/carbon/org/eclipse/swt/browser/MozillaDelegate.java b/bundles/org.eclipse.swt/Eclipse SWT Mozilla/carbon/org/eclipse/swt/browser/MozillaDelegate.java new file mode 100644 index 0000000000..ad94e4c92e --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT Mozilla/carbon/org/eclipse/swt/browser/MozillaDelegate.java @@ -0,0 +1,260 @@ +/******************************************************************************* + * Copyright (c) 2003, 2009 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.browser; + +import java.util.Hashtable; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.browser.Browser; +import org.eclipse.swt.internal.*; +import org.eclipse.swt.internal.carbon.*; +import org.eclipse.swt.internal.cocoa.*; +import org.eclipse.swt.internal.mozilla.*; +import org.eclipse.swt.widgets.*; + +class MozillaDelegate { + Browser browser; + Listener listener; + boolean hasFocus; + static Callback Callback3; + static Hashtable handles = new Hashtable (); + +MozillaDelegate (Browser browser) { + super (); + this.browser = browser; +} + +static Browser findBrowser (int handle) { + LONG value = (LONG)handles.get (new LONG (handle)); + if (value != null) { + Display display = Display.getCurrent (); + return (Browser)display.findWidget (value.value); + } + return null; +} + +static char[] mbcsToWcs (String codePage, byte [] buffer) { + int encoding = OS.CFStringGetSystemEncoding (); + int cfstring = OS.CFStringCreateWithBytes (OS.kCFAllocatorDefault, buffer, buffer.length, encoding, false); + char[] chars = null; + if (cfstring != 0) { + int length = OS.CFStringGetLength (cfstring); + chars = new char [length]; + if (length != 0) { + CFRange range = new CFRange (); + range.length = length; + OS.CFStringGetCharacters (cfstring, range, chars); + } + OS.CFRelease (cfstring); + } + return chars; +} + +static byte[] wcsToMbcs (String codePage, String string, boolean terminate) { + char[] chars = new char [string.length()]; + string.getChars (0, chars.length, chars, 0); + int cfstring = OS.CFStringCreateWithCharacters (OS.kCFAllocatorDefault, chars, chars.length); + byte[] buffer = null; + if (cfstring != 0) { + CFRange range = new CFRange (); + range.length = chars.length; + int encoding = OS.CFStringGetSystemEncoding (); + int[] size = new int[1]; + int numChars = OS.CFStringGetBytes (cfstring, range, encoding, (byte)'?', true, null, 0, size); + buffer = new byte [size[0] + (terminate ? 1 : 0)]; + if (numChars != 0) { + numChars = OS.CFStringGetBytes (cfstring, range, encoding, (byte)'?', true, buffer, size[0], size); + } + OS.CFRelease (cfstring); + } + return buffer; +} + +static int eventProc3 (int nextHandler, int theEvent, int userData) { + Widget widget = Display.getCurrent ().findWidget (userData); + if (widget instanceof Browser) { + Browser browser = (Browser) widget; + switch (OS.GetEventClass (theEvent)) { + case OS.kEventClassMouse: + browser.getShell ().forceActive (); + ((Mozilla)browser.webBrowser).Activate (); + break; + case OS.kEventClassKeyboard: + /* + * Bug in Carbon. OSX crashes if a HICocoaView is disposed during a key event, + * presumably as a result of attempting to use it after its refcount has reached + * 0. The workaround is to temporarily add an extra ref to the view while the + * DOM listener is handling the event, in case the Browser gets disposed in a + * callback. + */ + int handle = browser.handle; + OS.CFRetain (handle); + int result = OS.CallNextEventHandler (nextHandler, theEvent); + OS.CFRelease (handle); + return result; + } + } + return OS.eventNotHandledErr; +} + +void addWindowSubclass () { +} + +int createBaseWindow (nsIBaseWindow baseWindow) { + /* + * Feature of Mozilla on OSX. Mozilla replaces the OSX application menu whenever + * a browser's base window is created. The workaround is to restore the previous + * menu after creating the base window. + */ + int application = Cocoa.objc_msgSend (Cocoa.C_NSApplication, Cocoa.S_sharedApplication); + int mainMenu = Cocoa.objc_msgSend (application, Cocoa.S_mainMenu); + Cocoa.objc_msgSend (mainMenu, Cocoa.S_retain); + int rc = baseWindow.Create (); + Cocoa.objc_msgSend (application, Cocoa.S_setMainMenu, mainMenu); + Cocoa.objc_msgSend (mainMenu, Cocoa.S_release); + return rc; +} + +int getHandle () { + int embedHandle = Cocoa.objc_msgSend (Cocoa.C_NSImageView, Cocoa.S_alloc); + if (embedHandle == 0) { + browser.dispose (); + SWT.error (SWT.ERROR_NO_HANDLES); + } + NSRect r = new NSRect (); + embedHandle = Cocoa.objc_msgSend (embedHandle, Cocoa.S_initWithFrame, r); + int rc; + int[] outControl = new int[1]; + rc = Cocoa.HICocoaViewCreate (embedHandle, 0, outControl); /* OSX >= 10.5 */ + if (rc == OS.noErr && outControl[0] != 0) { + Cocoa.objc_msgSend (embedHandle, Cocoa.S_release); + } else { + /* will succeed on OSX 10.4 with an updated vm containing HIJavaViewCreateWithCocoaView */ + try { + System.loadLibrary ("frameembedding"); //$NON-NLS-1$ + } catch (UnsatisfiedLinkError e) {} + rc = Cocoa.HIJavaViewCreateWithCocoaView (outControl, embedHandle); + if (!(rc == OS.noErr && outControl[0] != 0)) { + browser.dispose (); + SWT.error (SWT.ERROR_NO_HANDLES); + } + } + int subHIView = outControl[0]; + HILayoutInfo newLayoutInfo = new HILayoutInfo (); + newLayoutInfo.version = 0; + OS.HIViewGetLayoutInfo (subHIView, newLayoutInfo); + HISideBinding biding = newLayoutInfo.binding.top; + biding.toView = 0; + biding.kind = OS.kHILayoutBindMin; + biding.offset = 0; + biding = newLayoutInfo.binding.left; + biding.toView = 0; + biding.kind = OS.kHILayoutBindMin; + biding.offset = 0; + biding = newLayoutInfo.binding.bottom; + biding.toView = 0; + biding.kind = OS.kHILayoutBindMax; + biding.offset = 0; + biding = newLayoutInfo.binding.right; + biding.toView = 0; + biding.kind = OS.kHILayoutBindMax; + biding.offset = 0; + OS.HIViewSetLayoutInfo (subHIView, newLayoutInfo); + OS.HIViewChangeFeatures (subHIView, OS.kHIViewFeatureIsOpaque, 0); + OS.HIViewSetVisible (subHIView, true); + int parentHandle = browser.handle; + OS.HIViewAddSubview (browser.handle, subHIView); + CGRect rect = new CGRect (); + OS.HIViewGetFrame (parentHandle, rect); + rect.x = rect.y = 0; + OS.HIViewSetFrame (subHIView, rect); + handles.put (new LONG (embedHandle), new LONG (browser.handle)); + + if (Callback3 == null) Callback3 = new Callback (this.getClass (), "eventProc3", 3); //$NON-NLS-1$ + int callback3Address = Callback3.getAddress (); + if (callback3Address == 0) { + browser.dispose (); + SWT.error (SWT.ERROR_NO_MORE_CALLBACKS); + } + int [] mask = new int [] { + OS.kEventClassMouse, OS.kEventMouseDown, + OS.kEventClassKeyboard, OS.kEventRawKeyDown, + }; + int controlTarget = OS.GetControlEventTarget (subHIView); + OS.InstallEventHandler (controlTarget, callback3Address, mask.length / 2, mask, browser.handle, null); + + return embedHandle; +} + +String getJSLibraryName () { + return "libmozjs.dylib"; //$NON-NLS-1$ +} + +String getLibraryName () { + return "libxpcom.dylib"; //$NON-NLS-1$ +} + +String getSWTInitLibraryName () { + return "swt-xulrunner"; //$NON-NLS-1$ +} + +void handleFocus () { + if (hasFocus) return; + hasFocus = true; + ((Mozilla)browser.webBrowser).Activate (); + browser.setFocus (); + listener = new Listener () { + public void handleEvent (Event event) { + if (event.widget == browser) return; + ((Mozilla)browser.webBrowser).Deactivate (); + hasFocus = false; + browser.getDisplay ().removeFilter (SWT.FocusIn, this); + browser.getShell ().removeListener (SWT.Deactivate, this); + listener = null; + } + + }; + browser.getDisplay ().addFilter (SWT.FocusIn, listener); + browser.getShell ().addListener (SWT.Deactivate, listener); +} + +void handleMouseDown () { +} + +boolean hookEnterExit () { + return true; +} + +void init () { +} + +boolean needsSpinup () { + return false; +} + +void onDispose (int embedHandle) { + handles.remove (new LONG (embedHandle)); + if (listener != null) { + browser.getDisplay ().removeFilter (SWT.FocusIn, listener); + browser.getShell ().removeListener (SWT.Deactivate, listener); + listener = null; + } + browser = null; +} + +void removeWindowSubclass () { +} + +void setSize (int embedHandle, int width, int height) { + // TODO +} + +} |