diff dwt/browser/MozillaDelegate.d @ 278:93409d9838c5

Commit more browser/xpcom updates, including still uncoverted source.
author John Reimer<terminal.node@gmail.com>
date Thu, 31 Jul 2008 19:17:51 -0700
parents
children 44258e0b6687
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/browser/MozillaDelegate.d	Thu Jul 31 19:17:51 2008 -0700
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2007 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
+ *******************************************************************************/
+module dwt.browser.MozillaDelegate;
+
+import dwt.dwthelper.utils;
+
+import dwt.DWT;
+import dwt.internal.Callback;
+import dwt.internal.Converter;
+import dwt.internal.gtk.GdkEvent;
+import dwt.internal.gtk.OS;
+import dwt.widgets.Display;
+import dwt.widgets.Event;
+import dwt.widgets.Listener;
+import dwt.widgets.Widget;
+
+class MozillaDelegate {
+    Browser browser;
+    int /*long*/ mozillaHandle, embedHandle;
+    bool hasFocus;
+    Listener listener;
+    static Callback eventCallback;
+    static int /*long*/ eventProc;
+    static final int STOP_PROPOGATE = 1;
+
+    static bool IsLinux;
+    static {
+        String osName = System.getProperty ("os.name").toLowerCase (); //$NON-NLS-1$
+        IsLinux = osName.startsWith ("linux"); //$NON-NLS-1$
+    }
+
+MozillaDelegate (Browser browser) {
+    super ();
+    if (!IsLinux) {
+        browser.dispose ();
+        DWT.error (DWT.ERROR_NO_HANDLES, null, " [Unsupported platform]"); //$NON-NLS-1$
+    }
+    this.browser = browser;
+}
+
+static int /*long*/ eventProc (int /*long*/ handle, int /*long*/ gdkEvent, int /*long*/ pointer) {
+    int /*long*/ parent = OS.gtk_widget_get_parent (handle);
+    parent = OS.gtk_widget_get_parent (parent);
+    if (parent is 0) return 0;
+    Widget widget = Display.getCurrent ().findWidget (parent);
+    if (widget !is null && widget instanceof Browser) {
+        return ((Mozilla)((Browser)widget).webBrowser).delegate.gtk_event (handle, gdkEvent, pointer);
+    }
+    return 0;
+}
+
+static Browser findBrowser (int /*long*/ handle) {
+    /*
+    * Note.  On GTK, Mozilla is embedded into a GtkHBox handle
+    * and not directly into the parent Composite handle.
+    */
+    int /*long*/ parent = OS.gtk_widget_get_parent (handle);
+    Display display = Display.getCurrent ();
+    return (Browser)display.findWidget (parent); 
+}
+
+static char[] mbcsToWcs (String codePage, byte [] buffer) {
+    return Converter.mbcsToWcs (codePage, buffer);
+}
+
+static byte[] wcsToMbcs (String codePage, String string, bool terminate) {
+    return Converter.wcsToMbcs (codePage, string, terminate);
+}
+
+int /*long*/ getHandle () {
+    /*
+    * Bug in Mozilla Linux GTK.  Embedding Mozilla into a GtkFixed
+    * handle causes problems with some Mozilla plug-ins.  For some
+    * reason, the Flash plug-in causes the child of the GtkFixed
+    * handle to be resized to 1 when the Flash document is loaded.
+    * That could be due to gtk_container_resize_children being called
+    * by Mozilla - or one of its plug-ins - on the GtkFixed handle,
+    * causing the child of the GtkFixed handle to be resized to 1.
+    * The workaround is to embed Mozilla into a GtkHBox handle.
+    */
+    embedHandle = OS.gtk_hbox_new (false, 0);
+    OS.gtk_container_add (browser.handle, embedHandle);
+    OS.gtk_widget_show (embedHandle);
+    return embedHandle;
+}
+
+String getLibraryName () {
+    return "libxpcom.so"; //$NON-NLS-1$
+}
+
+String getSWTInitLibraryName () {
+    return "swt-xpcominit"; //$NON-NLS-1$
+}
+
+int /*long*/ gtk_event (int /*long*/ handle, int /*long*/ gdkEvent, int /*long*/ pointer) {
+    GdkEvent event = new GdkEvent ();
+    OS.memmove (event, gdkEvent, GdkEvent.sizeof);
+    if (event.type is OS.GDK_BUTTON_PRESS) {
+        if (!hasFocus) browser.setFocus ();
+    }
+
+    /* 
+    * Stop the propagation of events that are not consumed by Mozilla, before
+    * they reach the parent embedder.  These event have already been received.
+    */
+    if (pointer is STOP_PROPOGATE) return 1;
+    return 0;
+}
+
+void handleFocus () {
+    if (hasFocus) return;
+    hasFocus = true;
+    listener = new Listener () {
+        public void handleEvent (Event event) {
+            if (event.widget is browser) return;
+            ((Mozilla)browser.webBrowser).Deactivate ();
+            hasFocus = false;
+            browser.getDisplay ().removeFilter (DWT.FocusIn, this);
+            browser.getShell ().removeListener (DWT.Deactivate, this);
+            listener = null;
+        }
+    };
+    browser.getDisplay ().addFilter (DWT.FocusIn, listener);
+    browser.getShell ().addListener (DWT.Deactivate, listener);
+}
+
+void handleMouseDown () {
+    int shellStyle = browser.getShell ().getStyle (); 
+    if ((shellStyle & DWT.ON_TOP) !is 0 && (((shellStyle & DWT.NO_FOCUS) is 0) || ((browser.getStyle () & DWT.NO_FOCUS) is 0))) {
+        browser.getDisplay ().asyncExec (new Runnable () {
+            public void run () {
+                if (browser is null || browser.isDisposed ()) return;
+                ((Mozilla)browser.webBrowser).Activate ();
+            }
+        });
+    }
+}
+
+bool hookEnterExit () {
+    return false;
+}
+
+void init () {
+    if (eventCallback is null) {
+        eventCallback = new Callback (getClass (), "eventProc", 3); //$NON-NLS-1$
+        eventProc = eventCallback.getAddress ();
+        if (eventProc is 0) {
+            browser.dispose ();
+            Mozilla.error (DWT.ERROR_NO_MORE_CALLBACKS);
+        }
+    }
+
+    /*
+    * Feature in Mozilla.  GtkEvents such as key down, key pressed may be consumed
+    * by Mozilla and never be received by the parent embedder.  The workaround
+    * is to find the top Mozilla gtk widget that receives all the Mozilla GtkEvents,
+    * i.e. the first child of the parent embedder. Then hook event callbacks and
+    * forward the event to the parent embedder before Mozilla received and consumed
+    * them.
+    */
+    int /*long*/ list = OS.gtk_container_get_children (embedHandle);
+    if (list !is 0) {
+        mozillaHandle = OS.g_list_data (list);
+        OS.g_list_free (list);
+        
+        if (mozillaHandle !is 0) {          
+            /* Note. Callback to get events before Mozilla receives and consumes them. */
+            OS.g_signal_connect (mozillaHandle, OS.event, eventProc, 0);
+            
+            /* 
+            * Note.  Callback to get the events not consumed by Mozilla - and to block 
+            * them so that they don't get propagated to the parent handle twice.  
+            * This hook is set after Mozilla and is therefore called after Mozilla's 
+            * handler because GTK dispatches events in their order of registration.
+            */
+            OS.g_signal_connect (mozillaHandle, OS.key_press_event, eventProc, STOP_PROPOGATE);
+            OS.g_signal_connect (mozillaHandle, OS.key_release_event, eventProc, STOP_PROPOGATE);
+            OS.g_signal_connect (mozillaHandle, OS.button_press_event, eventProc, STOP_PROPOGATE);
+        }
+    }
+}
+
+bool needsSpinup () {
+    return true;
+}
+
+void onDispose (int /*long*/ embedHandle) {
+    if (listener !is null) {
+        browser.getDisplay ().removeFilter (DWT.FocusIn, listener);
+        browser.getShell ().removeListener (DWT.Deactivate, listener);
+        listener = null;
+    }
+    browser = null;
+}
+
+void setSize (int /*long*/ embedHandle, int width, int height) {
+    OS.gtk_widget_set_size_request (embedHandle, width, height);
+}
+
+}