comparison 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
comparison
equal deleted inserted replaced
277:687f261028b8 278:93409d9838c5
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 *******************************************************************************/
11 module dwt.browser.MozillaDelegate;
12
13 import dwt.dwthelper.utils;
14
15 import dwt.DWT;
16 import dwt.internal.Callback;
17 import dwt.internal.Converter;
18 import dwt.internal.gtk.GdkEvent;
19 import dwt.internal.gtk.OS;
20 import dwt.widgets.Display;
21 import dwt.widgets.Event;
22 import dwt.widgets.Listener;
23 import dwt.widgets.Widget;
24
25 class MozillaDelegate {
26 Browser browser;
27 int /*long*/ mozillaHandle, embedHandle;
28 bool hasFocus;
29 Listener listener;
30 static Callback eventCallback;
31 static int /*long*/ eventProc;
32 static final int STOP_PROPOGATE = 1;
33
34 static bool IsLinux;
35 static {
36 String osName = System.getProperty ("os.name").toLowerCase (); //$NON-NLS-1$
37 IsLinux = osName.startsWith ("linux"); //$NON-NLS-1$
38 }
39
40 MozillaDelegate (Browser browser) {
41 super ();
42 if (!IsLinux) {
43 browser.dispose ();
44 DWT.error (DWT.ERROR_NO_HANDLES, null, " [Unsupported platform]"); //$NON-NLS-1$
45 }
46 this.browser = browser;
47 }
48
49 static int /*long*/ eventProc (int /*long*/ handle, int /*long*/ gdkEvent, int /*long*/ pointer) {
50 int /*long*/ parent = OS.gtk_widget_get_parent (handle);
51 parent = OS.gtk_widget_get_parent (parent);
52 if (parent is 0) return 0;
53 Widget widget = Display.getCurrent ().findWidget (parent);
54 if (widget !is null && widget instanceof Browser) {
55 return ((Mozilla)((Browser)widget).webBrowser).delegate.gtk_event (handle, gdkEvent, pointer);
56 }
57 return 0;
58 }
59
60 static Browser findBrowser (int /*long*/ handle) {
61 /*
62 * Note. On GTK, Mozilla is embedded into a GtkHBox handle
63 * and not directly into the parent Composite handle.
64 */
65 int /*long*/ parent = OS.gtk_widget_get_parent (handle);
66 Display display = Display.getCurrent ();
67 return (Browser)display.findWidget (parent);
68 }
69
70 static char[] mbcsToWcs (String codePage, byte [] buffer) {
71 return Converter.mbcsToWcs (codePage, buffer);
72 }
73
74 static byte[] wcsToMbcs (String codePage, String string, bool terminate) {
75 return Converter.wcsToMbcs (codePage, string, terminate);
76 }
77
78 int /*long*/ getHandle () {
79 /*
80 * Bug in Mozilla Linux GTK. Embedding Mozilla into a GtkFixed
81 * handle causes problems with some Mozilla plug-ins. For some
82 * reason, the Flash plug-in causes the child of the GtkFixed
83 * handle to be resized to 1 when the Flash document is loaded.
84 * That could be due to gtk_container_resize_children being called
85 * by Mozilla - or one of its plug-ins - on the GtkFixed handle,
86 * causing the child of the GtkFixed handle to be resized to 1.
87 * The workaround is to embed Mozilla into a GtkHBox handle.
88 */
89 embedHandle = OS.gtk_hbox_new (false, 0);
90 OS.gtk_container_add (browser.handle, embedHandle);
91 OS.gtk_widget_show (embedHandle);
92 return embedHandle;
93 }
94
95 String getLibraryName () {
96 return "libxpcom.so"; //$NON-NLS-1$
97 }
98
99 String getSWTInitLibraryName () {
100 return "swt-xpcominit"; //$NON-NLS-1$
101 }
102
103 int /*long*/ gtk_event (int /*long*/ handle, int /*long*/ gdkEvent, int /*long*/ pointer) {
104 GdkEvent event = new GdkEvent ();
105 OS.memmove (event, gdkEvent, GdkEvent.sizeof);
106 if (event.type is OS.GDK_BUTTON_PRESS) {
107 if (!hasFocus) browser.setFocus ();
108 }
109
110 /*
111 * Stop the propagation of events that are not consumed by Mozilla, before
112 * they reach the parent embedder. These event have already been received.
113 */
114 if (pointer is STOP_PROPOGATE) return 1;
115 return 0;
116 }
117
118 void handleFocus () {
119 if (hasFocus) return;
120 hasFocus = true;
121 listener = new Listener () {
122 public void handleEvent (Event event) {
123 if (event.widget is browser) return;
124 ((Mozilla)browser.webBrowser).Deactivate ();
125 hasFocus = false;
126 browser.getDisplay ().removeFilter (DWT.FocusIn, this);
127 browser.getShell ().removeListener (DWT.Deactivate, this);
128 listener = null;
129 }
130 };
131 browser.getDisplay ().addFilter (DWT.FocusIn, listener);
132 browser.getShell ().addListener (DWT.Deactivate, listener);
133 }
134
135 void handleMouseDown () {
136 int shellStyle = browser.getShell ().getStyle ();
137 if ((shellStyle & DWT.ON_TOP) !is 0 && (((shellStyle & DWT.NO_FOCUS) is 0) || ((browser.getStyle () & DWT.NO_FOCUS) is 0))) {
138 browser.getDisplay ().asyncExec (new Runnable () {
139 public void run () {
140 if (browser is null || browser.isDisposed ()) return;
141 ((Mozilla)browser.webBrowser).Activate ();
142 }
143 });
144 }
145 }
146
147 bool hookEnterExit () {
148 return false;
149 }
150
151 void init () {
152 if (eventCallback is null) {
153 eventCallback = new Callback (getClass (), "eventProc", 3); //$NON-NLS-1$
154 eventProc = eventCallback.getAddress ();
155 if (eventProc is 0) {
156 browser.dispose ();
157 Mozilla.error (DWT.ERROR_NO_MORE_CALLBACKS);
158 }
159 }
160
161 /*
162 * Feature in Mozilla. GtkEvents such as key down, key pressed may be consumed
163 * by Mozilla and never be received by the parent embedder. The workaround
164 * is to find the top Mozilla gtk widget that receives all the Mozilla GtkEvents,
165 * i.e. the first child of the parent embedder. Then hook event callbacks and
166 * forward the event to the parent embedder before Mozilla received and consumed
167 * them.
168 */
169 int /*long*/ list = OS.gtk_container_get_children (embedHandle);
170 if (list !is 0) {
171 mozillaHandle = OS.g_list_data (list);
172 OS.g_list_free (list);
173
174 if (mozillaHandle !is 0) {
175 /* Note. Callback to get events before Mozilla receives and consumes them. */
176 OS.g_signal_connect (mozillaHandle, OS.event, eventProc, 0);
177
178 /*
179 * Note. Callback to get the events not consumed by Mozilla - and to block
180 * them so that they don't get propagated to the parent handle twice.
181 * This hook is set after Mozilla and is therefore called after Mozilla's
182 * handler because GTK dispatches events in their order of registration.
183 */
184 OS.g_signal_connect (mozillaHandle, OS.key_press_event, eventProc, STOP_PROPOGATE);
185 OS.g_signal_connect (mozillaHandle, OS.key_release_event, eventProc, STOP_PROPOGATE);
186 OS.g_signal_connect (mozillaHandle, OS.button_press_event, eventProc, STOP_PROPOGATE);
187 }
188 }
189 }
190
191 bool needsSpinup () {
192 return true;
193 }
194
195 void onDispose (int /*long*/ embedHandle) {
196 if (listener !is null) {
197 browser.getDisplay ().removeFilter (DWT.FocusIn, listener);
198 browser.getShell ().removeListener (DWT.Deactivate, listener);
199 listener = null;
200 }
201 browser = null;
202 }
203
204 void setSize (int /*long*/ embedHandle, int width, int height) {
205 OS.gtk_widget_set_size_request (embedHandle, width, height);
206 }
207
208 }