comparison dwt/widgets/Display.d @ 240:ce446666f5a2

Update to SWT 3.4M7
author Frank Benoit <benoit@tionex.de>
date Mon, 12 May 2008 19:13:01 +0200
parents 380bad9f6852
children 8bca790583c3
comparison
equal deleted inserted replaced
239:06a1f6829310 240:ce446666f5a2
30 import dwt.internal.Lock; 30 import dwt.internal.Lock;
31 import dwt.internal.LONG; 31 import dwt.internal.LONG;
32 import dwt.internal.gtk.OS; 32 import dwt.internal.gtk.OS;
33 import dwt.widgets.Caret; 33 import dwt.widgets.Caret;
34 import dwt.widgets.Control; 34 import dwt.widgets.Control;
35 import dwt.widgets.Dialog;
35 import dwt.widgets.Event; 36 import dwt.widgets.Event;
36 import dwt.widgets.EventTable; 37 import dwt.widgets.EventTable;
37 import dwt.widgets.Listener; 38 import dwt.widgets.Listener;
38 import dwt.widgets.Menu; 39 import dwt.widgets.Menu;
39 import dwt.widgets.Monitor; 40 import dwt.widgets.Monitor;
142 143
143 CallbackData*[int] windowProcCallbackDatas; // to prevent GC from collect 144 CallbackData*[int] windowProcCallbackDatas; // to prevent GC from collect
144 145
145 CallbackData filterProcCallbackData; 146 CallbackData filterProcCallbackData;
146 EventTable eventTable, filterTable; 147 EventTable eventTable, filterTable;
147 static String APP_NAME = "DWT"; 148 static String APP_NAME = "DWT"; //$NON-NLS-1$
148 static const String DISPATCH_EVENT_KEY = "dwt.internal.gtk.dispatchEvent"; 149 static const String DISPATCH_EVENT_KEY = "dwt.internal.gtk.dispatchEvent";
149 static const String ADD_WIDGET_KEY = "dwt.internal.addWidget"; 150 static const String ADD_WIDGET_KEY = "dwt.internal.addWidget";
150 GClosure*[] closures; 151 GClosure*[] closures;
151 int [] signalIds; 152 int [] signalIds;
152 153
159 const static int GROW_SIZE = 1024; 160 const static int GROW_SIZE = 1024;
160 static int SWT_OBJECT_INDEX; 161 static int SWT_OBJECT_INDEX;
161 static int SWT_OBJECT_INDEX1; 162 static int SWT_OBJECT_INDEX1;
162 static int SWT_OBJECT_INDEX2; 163 static int SWT_OBJECT_INDEX2;
163 164
165 /* Modality */
166 Shell [] modalShells;
167 Dialog modalDialog;
168 static final String GET_MODAL_DIALOG = "dwt.internal.gtk.getModalDialog"; //$NON-NLS-1$
169 static final String SET_MODAL_DIALOG = "dwt.internal.gtk.setModalDialog"; //$NON-NLS-1$
170
164 /* Focus */ 171 /* Focus */
165 int focusEvent; 172 int focusEvent;
166 Control focusControl; 173 Control focusControl;
167 Shell activeShell; 174 Shell activeShell;
168 bool activePending; 175 bool activePending;
210 GClosure* shellMapProcClosure; 217 GClosure* shellMapProcClosure;
211 218
212 /* Idle proc callback */ 219 /* Idle proc callback */
213 CallbackData idleProcCallbackData; 220 CallbackData idleProcCallbackData;
214 int idleHandle; 221 int idleHandle;
215 static const String ADD_IDLE_PROC_KEY = "dwt.internal.gtk2.addIdleProc"; 222 static const String ADD_IDLE_PROC_KEY = "dwt.internal.gtk.addIdleProc";
216 static const String REMOVE_IDLE_PROC_KEY = "dwt.internal.gtk2.removeIdleProc"; 223 static const String REMOVE_IDLE_PROC_KEY = "dwt.internal.gtk.removeIdleProc";
217
218 Object idleLock; 224 Object idleLock;
219 bool idleNeeded; 225 bool idleNeeded;
220 226
221 /* GtkTreeView callbacks */ 227 /* GtkTreeView callbacks */
222 int[] treeSelection; 228 int[] treeSelection;
223 int treeSelectionLength; 229 int treeSelectionLength;
224 230
225 /* Set direction callback */ 231 /* Set direction callback */
226 CallbackData setDirectionProcCallbackData; 232 CallbackData setDirectionProcCallbackData;
233 static const String GET_DIRECTION_PROC_KEY = "dwt.internal.gtk.getDirectionProc"; //$NON-NLS-1$
234
235 /* Set emissionProc callback */
236 CallbackData emissionProcCallbackData;
237 static const String GET_EMISSION_PROC_KEY = "dwt.internal.gtk.getEmissionProc"; //$NON-NLS-1$
227 238
228 /* Get all children callback */ 239 /* Get all children callback */
229 CallbackData allChildrenProcCallbackData; 240 CallbackData allChildrenProcCallbackData;
230 GList* allChildren; 241 GList* allChildren;
231 242
277 int lastEventTime, lastUserEventTime; 288 int lastEventTime, lastUserEventTime;
278 289
279 /* Fixed Subclass */ 290 /* Fixed Subclass */
280 static int /*long*/ fixed_type; 291 static int /*long*/ fixed_type;
281 static int /*long*/ fixed_info_ptr; 292 static int /*long*/ fixed_info_ptr;
293 static extern(C) void function(GtkWidget* handle, GtkAllocation* allocation) oldFixedSizeAllocateProc;
294
282 295
283 /* Renderer Subclass */ 296 /* Renderer Subclass */
284 static int /*long*/ text_renderer_type, pixbuf_renderer_type, toggle_renderer_type; 297 static int /*long*/ text_renderer_type, pixbuf_renderer_type, toggle_renderer_type;
285 static int /*long*/ text_renderer_info_ptr, pixbuf_renderer_info_ptr, toggle_renderer_info_ptr; 298 static int /*long*/ text_renderer_info_ptr, pixbuf_renderer_info_ptr, toggle_renderer_info_ptr;
286 299
389 // String name = Display.class.getName (); 402 // String name = Display.class.getName ();
390 // int index = name.lastIndexOf ('.'); 403 // int index = name.lastIndexOf ('.');
391 // PACKAGE_NAME = name.substring (0, index + 1); 404 // PACKAGE_NAME = name.substring (0, index + 1);
392 // } 405 // }
393 406
394 /*
395 * In order to support CLDC, .class cannot be used because
396 * it does not compile on some Java compilers when they are
397 * targeted for CLDC. Use Class.forName() instead.
398 */
399 //synchronized static void static_this() {
400 static this() { 407 static this() {
401 Displays = new Display [4]; 408 Displays = new Display [4];
402 initDeviceFinder(); 409 initDeviceFinder();
403 SWT_OBJECT_INDEX = OS.g_quark_from_string ("SWT_OBJECT_INDEX"); 410 SWT_OBJECT_INDEX = OS.g_quark_from_string ("SWT_OBJECT_INDEX");
404 SWT_OBJECT_INDEX1 = OS.g_quark_from_string ("SWT_OBJECT_INDEX1"); 411 SWT_OBJECT_INDEX1 = OS.g_quark_from_string ("SWT_OBJECT_INDEX1");
405 SWT_OBJECT_INDEX2 = OS.g_quark_from_string ("SWT_OBJECT_INDEX2"); 412 SWT_OBJECT_INDEX2 = OS.g_quark_from_string ("SWT_OBJECT_INDEX2");
406 } 413 }
407 414
408 /* GTK Version */ 415 /* GTK Version */
409 static const int MAJOR = 2; 416 static const int MAJOR = 2;
410 static const int MINOR = 0; 417 static const int MINOR = 0;
692 * </ul> 699 * </ul>
693 * 700 *
694 * @see #syncExec 701 * @see #syncExec
695 */ 702 */
696 public void asyncExec (Runnable runnable) { 703 public void asyncExec (Runnable runnable) {
697 if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED); 704 synchronized (Device.classinfo) {
698 synchronized (idleLock) { 705 if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED);
699 if (idleNeeded && idleHandle is 0) { 706 synchronized (idleLock) {
700 //NOTE: calling unlocked function in OS 707 if (idleNeeded && idleHandle is 0) {
701 idleHandle = OS.g_idle_add (&idleProcFunc, cast(void*) this); 708 //NOTE: calling unlocked function in OS
709 idleHandle = OS.g_idle_add (&idleProcFunc, cast(void*) this);
710 }
702 } 711 }
703 } 712 synchronizer.asyncExec (runnable);
704 synchronizer.asyncExec (runnable); 713 }
705 } 714 }
706 715
707 /** 716 /**
708 * Causes the system hardware to emit a short sound 717 * Causes the system hardware to emit a short sound
709 * (if it supports this capability). 718 * (if it supports this capability).
758 if (thread is null) error (DWT.ERROR_WIDGET_DISPOSED); 767 if (thread is null) error (DWT.ERROR_WIDGET_DISPOSED);
759 if (thread !is Thread.getThis ()) error (DWT.ERROR_THREAD_INVALID_ACCESS); 768 if (thread !is Thread.getThis ()) error (DWT.ERROR_THREAD_INVALID_ACCESS);
760 if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED); 769 if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED);
761 } 770 }
762 771
763 static synchronized void checkDisplay (Thread thread, bool multiple) { 772 static void checkDisplay (Thread thread, bool multiple) {
764 for (int i=0; i<Displays.length; i++) { 773 synchronized (Device.classinfo) {
765 if (Displays [i] !is null) { 774 for (int i=0; i<Displays.length; i++) {
766 if (!multiple) DWT.error (DWT.ERROR_NOT_IMPLEMENTED, null, " [multiple displays]"); 775 if (Displays [i] !is null) {
767 if (Displays [i].thread is thread) DWT.error (DWT.ERROR_THREAD_INVALID_ACCESS); 776 if (!multiple) DWT.error (DWT.ERROR_NOT_IMPLEMENTED, null, " [multiple displays]"); //$NON-NLS-1$
777 if (Displays [i].thread is thread) DWT.error (DWT.ERROR_THREAD_INVALID_ACCESS);
778 }
768 } 779 }
769 } 780 }
770 } 781 }
771 782
772 private static extern(C) int checkIfEventProcFunc (void* display, XEvent* xEvent, char* userData) { 783 private static extern(C) int checkIfEventProcFunc (void* display, XEvent* xEvent, char* userData) {
846 */ 857 */
847 protected void checkSubclass () { 858 protected void checkSubclass () {
848 //PORTING_TODO if (!isValidClass (getClass ())) error (DWT.ERROR_INVALID_SUBCLASS); 859 //PORTING_TODO if (!isValidClass (getClass ())) error (DWT.ERROR_INVALID_SUBCLASS);
849 } 860 }
850 861
862 void clearModal (Shell shell) {
863 if (modalShells is null) return;
864 int index = 0, length_ = modalShells.length;
865 while (index < length_) {
866 if (modalShells [index] is shell) break;
867 if (modalShells [index] is null) return;
868 index++;
869 }
870 if (index is length_) return;
871 System.arraycopy (modalShells, index + 1, modalShells, index, --length_ - index);
872 modalShells [length_] = null;
873 if (index is 0 && modalShells [0] is null) modalShells = null;
874 Shell [] shells = getShells ();
875 for (int i=0; i<shells.length; i++) shells [i].updateModal ();
876 }
877
851 /** 878 /**
852 * Requests that the connection between DWT and the underlying 879 * Requests that the connection between DWT and the underlying
853 * operating system be closed. 880 * operating system be closed.
854 * 881 *
855 * @exception DWTException <ul> 882 * @exception DWTException <ul>
882 */ 909 */
883 protected override void create (DeviceData data) { 910 protected override void create (DeviceData data) {
884 checkSubclass (); 911 checkSubclass ();
885 checkDisplay(thread = Thread.getThis (), false); 912 checkDisplay(thread = Thread.getThis (), false);
886 createDisplay (data); 913 createDisplay (data);
887 register (); 914 register (this);
888 if (Default is null) Default = this; 915 if (Default is null) Default = this;
889 } 916 }
890 917
891 private static extern(C) int XErrorHandler( void*, XErrorEvent* ){ 918 private static extern(C) int XErrorHandler( void*, XErrorEvent* ){
892 Stdout.formatln ("*** XError" ); 919 Stdout.formatln ("*** XError" );
893 byte* p; 920 byte* p;
894 *p = 3; 921 *p = 3;
895 return 0; 922 return 0;
896 } 923 }
897 924
898 synchronized void createDisplay (DeviceData data) { 925 void createDisplay (DeviceData data) {
899 /* Required for g_main_context_wakeup */ 926 /* Required for g_main_context_wakeup */
900 if (!OS.g_thread_supported ()) { 927 if (!OS.g_thread_supported ()) {
901 OS.g_thread_init (null); 928 OS.g_thread_init (null);
902 } 929 }
903 OS.gtk_set_locale(); 930 OS.gtk_set_locale();
904 int cnt = 2; 931 int cnt = 2;
905 char*[] args = [ "name".ptr, "--sync".ptr, null ]; 932 char*[] args = [ "name".ptr, "--sync".ptr, null ];
906 char** a = args.ptr; 933 char** a = args.ptr;
907 if (!OS.gtk_init_check (&cnt, &a )) { 934 if (!OS.gtk_init_check (&cnt, &a )) {
908 DWT.error (DWT.ERROR_NO_HANDLES, null, " [gtk_init_check() failed]");
909 } 935 }
910 assert( cnt is 1 ); 936 assert( cnt is 1 );
911 if (OS.GDK_WINDOWING_X11 ()) xDisplay = cast(void*) OS.GDK_DISPLAY (); 937 if (OS.GDK_WINDOWING_X11 ()) xDisplay = cast(void*) OS.GDK_DISPLAY ();
912 938
913 OS.XSetErrorHandler( &Display.XErrorHandler ); 939 OS.XSetErrorHandler( &Display.XErrorHandler );
1075 } 1101 }
1076 } 1102 }
1077 return pixbuf; 1103 return pixbuf;
1078 } 1104 }
1079 1105
1080 synchronized void deregister () { 1106 static void deregister (Display display) {
1081 for (int i=0; i<Displays.length; i++) { 1107 synchronized (Device.classinfo) {
1082 if (this is Displays [i]) Displays [i] = null; 1108 for (int i=0; i<Displays.length; i++) {
1109 if (display is Displays [i]) Displays [i] = null;
1110 }
1083 } 1111 }
1084 } 1112 }
1085 1113
1086 /** 1114 /**
1087 * Destroys the device in the operating system and releases 1115 * Destroys the device in the operating system and releases
1093 * @see Device#dispose 1121 * @see Device#dispose
1094 * @see #release 1122 * @see #release
1095 */ 1123 */
1096 protected override void destroy () { 1124 protected override void destroy () {
1097 if (this is Default) Default = null; 1125 if (this is Default) Default = null;
1098 deregister (); 1126 deregister (this);
1099 destroyDisplay (); 1127 destroyDisplay ();
1100 } 1128 }
1101 1129
1102 void destroyDisplay () { 1130 void destroyDisplay () {
1131 }
1132
1133 static extern(C) int /*long*/ emissionFunc (GSignalInvocationHint* ihint, uint n_param_values, GValue* param_values, void* data) {
1134 auto cb = cast(CallbackData*)data;
1135 return cb.display.emissionProc( ihint, n_param_values, param_values, cb.data );
1136 }
1137
1138 int /*long*/ emissionProc (GSignalInvocationHint* ihint, uint n_param_values, GValue* param_values, void* data) {
1139 if (OS.gtk_widget_get_toplevel (OS.g_value_peek_pointer(param_values)) is data) {
1140 OS.gtk_widget_set_direction (OS.g_value_peek_pointer(param_values), OS.GTK_TEXT_DIR_RTL);
1141 }
1142 return 1;
1103 } 1143 }
1104 1144
1105 /** 1145 /**
1106 * Returns the display which the given thread is the 1146 * Returns the display which the given thread is the
1107 * user-interface thread for, or null if the given thread 1147 * user-interface thread for, or null if the given thread
1110 * for the display. 1150 * for the display.
1111 * 1151 *
1112 * @param thread the user-interface thread 1152 * @param thread the user-interface thread
1113 * @return the display for the given thread 1153 * @return the display for the given thread
1114 */ 1154 */
1115 public static synchronized Display findDisplay (Thread thread) { 1155 public static Display findDisplay (Thread thread) {
1116 for (int i=0; i<Displays.length; i++) { 1156 synchronized (Device.classinfo) {
1117 Display display = Displays [i]; 1157 for (int i=0; i<Displays.length; i++) {
1118 if (display !is null && display.thread is thread) { 1158 Display display = Displays [i];
1119 return display; 1159 if (display !is null && display.thread is thread) {
1160 return display;
1161 }
1120 } 1162 }
1121 } 1163 return null;
1122 return null; 1164 }
1123 } 1165 }
1124 1166
1125 /** 1167 /**
1126 * Causes the <code>run()</code> method of the runnable to 1168 * Causes the <code>run()</code> method of the runnable to
1127 * be invoked by the user-interface thread just before the 1169 * be invoked by the user-interface thread just before the
1198 } 1240 }
1199 if (!dispatch) { 1241 if (!dispatch) {
1200 addGdkEvent (OS.gdk_event_copy (event)); 1242 addGdkEvent (OS.gdk_event_copy (event));
1201 return 0; 1243 return 0;
1202 } 1244 }
1203 /*
1204 * Feature in GTK. GTK implements modality by adding a grab
1205 * to the GTK top level window. Normally, all mouse and
1206 * keyboard events are delivered to child widgets and the
1207 * shell when the grab is active. When an override redirect
1208 * shell is created as a child of a dialog, then events are
1209 * grabbed by the dialog instead of the override redirect
1210 * shell. The fix is to add a temporary grab to the override
1211 * redirect window when there is not already a grab in a
1212 * child widget of the override redirect shell (for example,
1213 * in a scroll bar).
1214 */
1215 Shell shell = null;
1216 Control control = null;
1217 auto grabHandle = OS.gtk_grab_get_current ();
1218 if (grabHandle !is null && OS.GTK_IS_WINDOW (cast(GTypeInstance*)grabHandle) && OS.gtk_window_get_modal (cast(GtkWindow*)grabHandle)) {
1219 switch (eventType) {
1220 case OS.GDK_KEY_PRESS:
1221 case OS.GDK_KEY_RELEASE:
1222 case OS.GDK_ENTER_NOTIFY:
1223 case OS.GDK_LEAVE_NOTIFY:
1224 case OS.GDK_BUTTON_PRESS:
1225 case OS.GDK_2BUTTON_PRESS:
1226 case OS.GDK_3BUTTON_PRESS:
1227 case OS.GDK_BUTTON_RELEASE:
1228 case OS.GDK_MOTION_NOTIFY: {
1229 auto window = OS.GDK_EVENT_WINDOW (cast(GdkEventAny*)event);
1230 do {
1231 GtkWidget* handle;
1232 OS.gdk_window_get_user_data (window, cast(void**) &handle);
1233 if (handle !is null) {
1234 Widget widget = getWidget (handle);
1235 if (widget !is null && (null !is cast(Control)widget)) {
1236 control = cast(Control) widget;
1237 break;
1238 }
1239 }
1240 } while ((window = OS.gdk_window_get_parent (window)) !is null);
1241 default:
1242 }
1243 }
1244 if (control !is null) {
1245 shell = control.getShell ();
1246 if ((shell.style & DWT.ON_TOP) !is 0) {
1247 OS.gtk_grab_add (shell.shellHandle);
1248 }
1249 }
1250 }
1251 OS.gtk_main_do_event (event); 1245 OS.gtk_main_do_event (event);
1252 if (dispatchEvents is null) putGdkEvents (); 1246 if (dispatchEvents is null) putGdkEvents ();
1253 if (control !is null) {
1254 if (shell !is null && !shell.isDisposed () && (shell.style & DWT.ON_TOP) !is 0) {
1255 OS.gtk_grab_remove (shell.shellHandle);
1256 }
1257 }
1258 return 0; 1247 return 0;
1259 } 1248 }
1260 1249
1261 /** 1250 /**
1262 * Given the operating system handle for a widget, returns 1251 * Given the operating system handle for a widget, returns
1323 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> 1312 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
1324 * </ul> 1313 * </ul>
1325 * 1314 *
1326 * @since 3.3 1315 * @since 3.3
1327 */ 1316 */
1328 public Widget findWidget (Widget widget, int id) { 1317 public Widget findWidget (Widget widget, int /*long*/ id) {
1329 checkDevice (); 1318 checkDevice ();
1330 return null; 1319 return null;
1331 } 1320 }
1332 1321
1333 private static extern(C) void fixedClassInitProcFunc (void* g_class, void* class_data) { 1322 private static extern(C) void fixedClassInitProcFunc (void* g_class, void* class_data) {
1334 version(LOG) Stderr.formatln( "Display {}:", __LINE__ ).flush; 1323 version(LOG) Stderr.formatln( "Display {}:", __LINE__ ).flush;
1335 GtkWidgetClass* klass = cast(GtkWidgetClass*)g_class; 1324 GtkWidgetClass* klass = cast(GtkWidgetClass*)g_class;
1336 klass.map = &fixedMapProcFunc; 1325 klass.map = &fixedMapProcFunc;
1326 oldFixedSizeAllocateProc = klass.size_allocate;
1327 klass.size_allocate = &fixedSizeAllocateProc;
1337 } 1328 }
1338 1329
1339 private static extern(C) void fixedMapProcFunc (GtkWidget * handle) { 1330 private static extern(C) void fixedMapProcFunc (GtkWidget * handle) {
1340 version(LOG) Stderr.formatln( "Display {}:", __LINE__ ).flush; 1331 version(LOG) Stderr.formatln( "Display {}:", __LINE__ ).flush;
1341 Display display = getCurrent (); 1332 Display display = getCurrent ();
1342 Widget widget = display.getWidget (handle); 1333 Widget widget = display.getWidget (handle);
1343 if (widget !is null) widget.fixedMapProc (handle); 1334 if (widget !is null) widget.fixedMapProc (handle);
1344 } 1335 }
1345 1336
1337 private static extern(C) static void fixedSizeAllocateProc (GtkWidget* handle, GtkAllocation* allocation) {
1338 Display display = getCurrent ();
1339 Widget widget = display.getWidget (handle);
1340 if (widget !is null) return widget.fixedSizeAllocateProc (handle, allocation);
1341 return oldFixedSizeAllocateProc(handle, allocation);
1342 }
1343
1346 private static extern(C) void rendererClassInitProcFunc (void* g_class, void* class_data) { 1344 private static extern(C) void rendererClassInitProcFunc (void* g_class, void* class_data) {
1347 version(LOG) Stderr.formatln( "Display {}:", __LINE__ ).flush; 1345 version(LOG) Stderr.formatln( "Display {}:", __LINE__ ).flush;
1348 GtkCellRendererClass* klass = cast(GtkCellRendererClass*)g_class; 1346 GtkCellRendererClass* klass = cast(GtkCellRendererClass*)g_class;
1349 klass.render = &rendererRenderProcFunc; 1347 klass.render = &rendererRenderProcFunc;
1350 klass.get_size = &rendererGetSizeProcFunc; 1348 klass.get_size = &rendererGetSizeProcFunc;
1349
1351 } 1350 }
1352 private static extern(C) void rendererGetSizeProcFunc( 1351 private static extern(C) void rendererGetSizeProcFunc(
1353 GtkCellRenderer *cell, 1352 GtkCellRenderer *cell,
1354 GtkWidget *handle, 1353 GtkWidget *handle,
1355 GdkRectangle *cell_area, 1354 GdkRectangle *cell_area,
1421 * the user-interface thread for, or null if the currently 1420 * the user-interface thread for, or null if the currently
1422 * running thread is not a user-interface thread for any display. 1421 * running thread is not a user-interface thread for any display.
1423 * 1422 *
1424 * @return the current display 1423 * @return the current display
1425 */ 1424 */
1426 public static synchronized Display getCurrent () { 1425 public static Display getCurrent () {
1427 Thread current = Thread.getThis (); 1426 return findDisplay (Thread.getThis ());
1428 for (int i=0; i<Displays.length; i++) {
1429 Display display = Displays [i];
1430 if (display !is null && display.thread is current) return display;
1431 }
1432 return null;
1433 } 1427 }
1434 1428
1435 int getCaretBlinkTime () { 1429 int getCaretBlinkTime () {
1436 // checkDevice (); 1430 // checkDevice ();
1437 auto settings = OS.gtk_settings_get_default (); 1431 auto settings = OS.gtk_settings_get_default ();
1462 * </ul> 1456 * </ul>
1463 */ 1457 */
1464 public Control getCursorControl () { 1458 public Control getCursorControl () {
1465 checkDevice(); 1459 checkDevice();
1466 int x, y; 1460 int x, y;
1461 GtkWidget* handle;
1462 GtkWidget* user_data;
1467 auto window = OS.gdk_window_at_pointer (&x, &y); 1463 auto window = OS.gdk_window_at_pointer (&x, &y);
1468 if (window is null) return null; 1464 if (window !is null) {
1469 GtkWidget* handle; 1465 OS.gdk_window_get_user_data (window, cast(void**)&user_data);
1470 OS.gdk_window_get_user_data (window, cast(void**)&handle); 1466 handle = user_data;
1467 } else {
1468 /*
1469 * Feature in GTK. gdk_window_at_pointer() will not return a window
1470 * if the pointer is over a foreign embedded window. The fix is to use
1471 * XQueryPointer to find the containing GDK window.
1472 */
1473 if (!OS.GDK_WINDOWING_X11 ()) return null;
1474 OS.gdk_error_trap_push ();
1475 int unusedInt;
1476 uint unusedUInt;
1477 uint unusedPtr;
1478 uint buffer;
1479 uint xWindow, xParent = OS.XDefaultRootWindow (xDisplay);
1480 do {
1481 if (OS.XQueryPointer (xDisplay, xParent, &unusedPtr, &buffer, &unusedInt, &unusedInt, &unusedInt, &unusedInt, &unusedUInt) is 0) {
1482 handle = null;
1483 break;
1484 }
1485 if ((xWindow = buffer) !is 0) {
1486 xParent = xWindow;
1487 auto gdkWindow = OS.gdk_window_lookup (xWindow);
1488 if (gdkWindow !is null) {
1489 OS.gdk_window_get_user_data (gdkWindow, cast(void**)&user_data);
1490 if (user_data !is null) handle = user_data;
1491 }
1492 }
1493 } while (xWindow !is 0);
1494 OS.gdk_error_trap_pop ();
1495 }
1471 if (handle is null) return null; 1496 if (handle is null) return null;
1472 do { 1497 do {
1473 Widget widget = getWidget (handle); 1498 Widget widget = getWidget (handle);
1474 if (widget !is null && (null !is cast(Control)widget)) { 1499 if (widget !is null && (null !is cast(Control)widget)) {
1475 Control control = cast(Control) widget; 1500 Control control = cast(Control) widget;
1585 * @see #disposeExec(Runnable) 1610 * @see #disposeExec(Runnable)
1586 */ 1611 */
1587 public Object getData (String key) { 1612 public Object getData (String key) {
1588 checkDevice (); 1613 checkDevice ();
1589 if (key is null) error (DWT.ERROR_NULL_ARGUMENT); 1614 if (key is null) error (DWT.ERROR_NULL_ARGUMENT);
1590 if (key ==/*eq*/ DISPATCH_EVENT_KEY) { 1615 if (key.equals (DISPATCH_EVENT_KEY)) {
1591 return new ArrayWrapperInt(dispatchEvents); 1616 return new ArrayWrapperInt(dispatchEvents);
1617 }
1618 if (key.equals (GET_MODAL_DIALOG)) {
1619 return modalDialog;
1620 }
1621 if (key.equals (GET_DIRECTION_PROC_KEY)) {
1622 return new LONG (cast(int) &setDirectionProcFunc);
1623 }
1624 if (key.equals (GET_EMISSION_PROC_KEY)) {
1625 return new LONG (cast(int) &emissionFunc);
1592 } 1626 }
1593 if (keys is null) return null; 1627 if (keys is null) return null;
1594 for (int i=0; i<keys.length; i++) { 1628 for (int i=0; i<keys.length; i++) {
1595 if (keys [i] ==/*eq*/ key) return values [i]; 1629 if (keys [i].equals(key)) return values [i];
1596 } 1630 }
1597 return null; 1631 return null;
1598 } 1632 }
1599 1633
1600 /** 1634 /**
1665 * thread that invokes this method its user-interface thread) 1699 * thread that invokes this method its user-interface thread)
1666 * if it did not already exist. 1700 * if it did not already exist.
1667 * 1701 *
1668 * @return the default display 1702 * @return the default display
1669 */ 1703 */
1670 public static synchronized Display getDefault () { 1704 public static Display getDefault () {
1671 if (Default is null) Default = new Display (); 1705 synchronized (Device.classinfo) {
1672 return Default; 1706 if (Default is null) Default = new Display ();
1707 return Default;
1708 }
1673 } 1709 }
1674 1710
1675 // /+static bool isValidClass (Class clazz) { 1711 // /+static bool isValidClass (Class clazz) {
1676 // //PORTING_TODO String name = clazz.getName (); 1712 // //PORTING_TODO String name = clazz.getName ();
1677 // //PORTING_TODO int index = name.lastIndexOf ('.'); 1713 // //PORTING_TODO int index = name.lastIndexOf ('.');
1822 return lastEventTime; 1858 return lastEventTime;
1823 } 1859 }
1824 1860
1825 int getMessageCount () { 1861 int getMessageCount () {
1826 return synchronizer.getMessageCount (); 1862 return synchronizer.getMessageCount ();
1863 }
1864
1865 Dialog getModalDialog () {
1866 return modalDialog;
1827 } 1867 }
1828 1868
1829 /** 1869 /**
1830 * Returns the work area, an EWMH property to store the size 1870 * Returns the work area, an EWMH property to store the size
1831 * and position of the screen not covered by dock and panel 1871 * and position of the screen not covered by dock and panel
1970 System.arraycopy (result, 0, newResult, 0, index); 2010 System.arraycopy (result, 0, newResult, 0, index);
1971 return newResult; 2011 return newResult;
1972 } 2012 }
1973 2013
1974 /** 2014 /**
2015 * Gets the synchronizer used by the display.
2016 *
2017 * @return the receiver's synchronizer
2018 *
2019 * @exception DWTException <ul>
2020 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2021 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
2022 * </ul>
2023 *
2024 * @since 3.4
2025 */
2026 public Synchronizer getSynchronizer () {
2027 checkDevice ();
2028 return synchronizer;
2029 }
2030
2031 /**
1975 * Returns the thread that has invoked <code>syncExec</code> 2032 * Returns the thread that has invoked <code>syncExec</code>
1976 * or null if no such runnable is currently being invoked by 2033 * or null if no such runnable is currently being invoked by
1977 * the user-interface thread. 2034 * the user-interface thread.
1978 * <p> 2035 * <p>
1979 * Note: If a runnable invoked by asyncExec is currently 2036 * Note: If a runnable invoked by asyncExec is currently
1985 * @exception DWTException <ul> 2042 * @exception DWTException <ul>
1986 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> 2043 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
1987 * </ul> 2044 * </ul>
1988 */ 2045 */
1989 public Thread getSyncThread () { 2046 public Thread getSyncThread () {
1990 if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED); 2047 synchronized (Device.classinfo) {
1991 return synchronizer.syncThread; 2048 if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED);
2049 return synchronizer.syncThread;
2050 }
1992 } 2051 }
1993 2052
1994 /** 2053 /**
1995 * Returns the matching standard color for the given 2054 * Returns the matching standard color for the given
1996 * constant, which should be one of the color constants 2055 * constant, which should be one of the color constants
2120 public Image getSystemImage (int id) { 2179 public Image getSystemImage (int id) {
2121 checkDevice (); 2180 checkDevice ();
2122 switch (id) { 2181 switch (id) {
2123 case DWT.ICON_ERROR: 2182 case DWT.ICON_ERROR:
2124 if (errorImage is null) { 2183 if (errorImage is null) {
2125 errorImage = createImage ("gtk-dialog-error"); 2184 errorImage = createImage ("gtk-dialog-error"); //$NON-NLS-1$
2126 } 2185 }
2127 return errorImage; 2186 return errorImage;
2128 case DWT.ICON_INFORMATION: 2187 case DWT.ICON_INFORMATION:
2129 case DWT.ICON_WORKING: 2188 case DWT.ICON_WORKING:
2130 if (infoImage is null) { 2189 if (infoImage is null) {
2131 infoImage = createImage ("gtk-dialog-info"); 2190 infoImage = createImage ("gtk-dialog-info"); //$NON-NLS-1$
2132 } 2191 }
2133 return infoImage; 2192 return infoImage;
2134 case DWT.ICON_QUESTION: 2193 case DWT.ICON_QUESTION:
2135 if (questionImage is null) { 2194 if (questionImage is null) {
2136 questionImage = createImage ("gtk-dialog-question"); 2195 questionImage = createImage ("gtk-dialog-question"); //$NON-NLS-1$
2137 } 2196 }
2138 return questionImage; 2197 return questionImage;
2139 case DWT.ICON_WARNING: 2198 case DWT.ICON_WARNING:
2140 if (warningImage is null) { 2199 if (warningImage is null) {
2141 warningImage = createImage ("gtk-dialog-warning"); 2200 warningImage = createImage ("gtk-dialog-warning"); //$NON-NLS-1$
2142 } 2201 }
2143 return warningImage; 2202 return warningImage;
2144 default: 2203 default:
2145 } 2204 }
2146 return null; 2205 return null;
2277 * @exception DWTException <ul> 2336 * @exception DWTException <ul>
2278 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> 2337 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
2279 * </ul> 2338 * </ul>
2280 */ 2339 */
2281 public Thread getThread () { 2340 public Thread getThread () {
2282 if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED); 2341 synchronized (Device.classinfo) {
2283 return thread; 2342 if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED);
2343 return thread;
2344 }
2284 } 2345 }
2285 2346
2286 Widget getWidget (GtkWidget* handle) { 2347 Widget getWidget (GtkWidget* handle) {
2287 if (handle is null) return null; 2348 if (handle is null) return null;
2288 if (lastWidget !is null && lastHandle is handle) return lastWidget; 2349 if (lastWidget !is null && lastHandle is handle) return lastWidget;
2417 closures [Widget.MAP_EVENT] = do_cclosure_new (windowProc3, Widget.MAP_EVENT, 0); 2478 closures [Widget.MAP_EVENT] = do_cclosure_new (windowProc3, Widget.MAP_EVENT, 0);
2418 closures [Widget.MNEMONIC_ACTIVATE] = do_cclosure_new (windowProc3, Widget.MNEMONIC_ACTIVATE, 0); 2479 closures [Widget.MNEMONIC_ACTIVATE] = do_cclosure_new (windowProc3, Widget.MNEMONIC_ACTIVATE, 0);
2419 closures [Widget.MOTION_NOTIFY_EVENT] = do_cclosure_new (windowProc3, Widget.MOTION_NOTIFY_EVENT, 0); 2480 closures [Widget.MOTION_NOTIFY_EVENT] = do_cclosure_new (windowProc3, Widget.MOTION_NOTIFY_EVENT, 0);
2420 closures [Widget.MOTION_NOTIFY_EVENT_INVERSE] = do_cclosure_new (windowProc3, Widget.MOTION_NOTIFY_EVENT_INVERSE, 0); 2481 closures [Widget.MOTION_NOTIFY_EVENT_INVERSE] = do_cclosure_new (windowProc3, Widget.MOTION_NOTIFY_EVENT_INVERSE, 0);
2421 closures [Widget.MOVE_FOCUS] = do_cclosure_new (windowProc3, Widget.MOVE_FOCUS, 0); 2482 closures [Widget.MOVE_FOCUS] = do_cclosure_new (windowProc3, Widget.MOVE_FOCUS, 0);
2483 closures [Widget.POPULATE_POPUP] = do_cclosure_new (windowProc3, Widget.POPULATE_POPUP, 0);
2422 closures [Widget.SCROLL_EVENT] = do_cclosure_new (windowProc3, Widget.SCROLL_EVENT, 0); 2484 closures [Widget.SCROLL_EVENT] = do_cclosure_new (windowProc3, Widget.SCROLL_EVENT, 0);
2423 closures [Widget.SHOW_HELP] = do_cclosure_new (windowProc3, Widget.SHOW_HELP, 0); 2485 closures [Widget.SHOW_HELP] = do_cclosure_new (windowProc3, Widget.SHOW_HELP, 0);
2424 closures [Widget.SIZE_ALLOCATE] = do_cclosure_new (windowProc3, Widget.SIZE_ALLOCATE, 0); 2486 closures [Widget.SIZE_ALLOCATE] = do_cclosure_new (windowProc3, Widget.SIZE_ALLOCATE, 0);
2425 closures [Widget.STYLE_SET] = do_cclosure_new (windowProc3, Widget.STYLE_SET, 0); 2487 closures [Widget.STYLE_SET] = do_cclosure_new (windowProc3, Widget.STYLE_SET, 0);
2426 closures [Widget.TOGGLED] = do_cclosure_new (windowProc3, Widget.TOGGLED, 0); 2488 closures [Widget.TOGGLED] = do_cclosure_new (windowProc3, Widget.TOGGLED, 0);
2452 OS.g_closure_ref (shellMapProcClosure); 2514 OS.g_closure_ref (shellMapProcClosure);
2453 } 2515 }
2454 2516
2455 void* getWindowProcUserData( int value ){ 2517 void* getWindowProcUserData( int value ){
2456 return windowProcCallbackDatas[ value ]; 2518 return windowProcCallbackDatas[ value ];
2519
2457 } 2520 }
2458 2521
2459 void initializeSystemSettings () { 2522 void initializeSystemSettings () {
2460 styleSetProcCallbackData.display = this; 2523 styleSetProcCallbackData.display = this;
2461 styleSetProcCallbackData.data = null; 2524 styleSetProcCallbackData.data = null;
2485 indexTable [GROW_SIZE - 1] = -1; 2548 indexTable [GROW_SIZE - 1] = -1;
2486 } 2549 }
2487 2550
2488 void initializeWindowManager () { 2551 void initializeWindowManager () {
2489 /* Get the window manager name */ 2552 /* Get the window manager name */
2490 windowManager = ""; 2553 windowManager = ""; //$NON-NLS-1$
2491 if (OS.GTK_VERSION >= OS.buildVERSION (2, 2, 0)) { 2554 if (OS.GTK_VERSION >= OS.buildVERSION (2, 2, 0)) {
2492 auto screen = OS.gdk_screen_get_default (); 2555 auto screen = OS.gdk_screen_get_default ();
2493 if (screen !is null) { 2556 if (screen !is null) {
2494 auto ptr2 = OS.gdk_x11_screen_get_window_manager_name (screen); 2557 auto ptr2 = OS.gdk_x11_screen_get_window_manager_name (screen);
2495 windowManager = fromStringz( ptr2 ); 2558 windowManager = fromStringz( ptr2 );
2547 } 2610 }
2548 data.device = this; 2611 data.device = this;
2549 data.drawable = root; 2612 data.drawable = root;
2550 data.background = getSystemColor (DWT.COLOR_WHITE).handle; 2613 data.background = getSystemColor (DWT.COLOR_WHITE).handle;
2551 data.foreground = getSystemColor (DWT.COLOR_BLACK).handle; 2614 data.foreground = getSystemColor (DWT.COLOR_BLACK).handle;
2552 data.font = getSystemFont ().handle; 2615 data.font = getSystemFont ();
2553 } 2616 }
2554 return gdkGC; 2617 return gdkGC;
2555 return null; 2618 return null;
2556 } 2619 }
2557 2620
2645 if (from is to) return point; 2708 if (from is to) return point;
2646 if (from !is null) { 2709 if (from !is null) {
2647 auto window = from.eventWindow (); 2710 auto window = from.eventWindow ();
2648 int origin_x, origin_y; 2711 int origin_x, origin_y;
2649 OS.gdk_window_get_origin (window, &origin_x, &origin_y); 2712 OS.gdk_window_get_origin (window, &origin_x, &origin_y);
2713 if ((from.style & DWT.MIRRORED) !is 0) point.x = from.getClientWidth () - point.x;
2650 point.x += origin_x; 2714 point.x += origin_x;
2651 point.y += origin_y; 2715 point.y += origin_y;
2652 } 2716 }
2653 if (to !is null) { 2717 if (to !is null) {
2654 auto window = to.eventWindow (); 2718 auto window = to.eventWindow ();
2655 int origin_x, origin_y; 2719 int origin_x, origin_y;
2656 OS.gdk_window_get_origin (window, &origin_x, &origin_y); 2720 OS.gdk_window_get_origin (window, &origin_x, &origin_y);
2657 point.x -= origin_x; 2721 point.x -= origin_x;
2658 point.y -= origin_y; 2722 point.y -= origin_y;
2723 if ((to.style & DWT.MIRRORED) !is 0) point.x = to.getClientWidth () - point.x;
2659 } 2724 }
2660 return point; 2725 return point;
2661 } 2726 }
2662 2727
2663 /** 2728 /**
2786 checkDevice(); 2851 checkDevice();
2787 if (from !is null && from.isDisposed()) error (DWT.ERROR_INVALID_ARGUMENT); 2852 if (from !is null && from.isDisposed()) error (DWT.ERROR_INVALID_ARGUMENT);
2788 if (to !is null && to.isDisposed()) error (DWT.ERROR_INVALID_ARGUMENT); 2853 if (to !is null && to.isDisposed()) error (DWT.ERROR_INVALID_ARGUMENT);
2789 Rectangle rect = new Rectangle (x, y, width, height); 2854 Rectangle rect = new Rectangle (x, y, width, height);
2790 if (from is to) return rect; 2855 if (from is to) return rect;
2856 bool fromRTL = false, toRTL = false;
2791 if (from !is null) { 2857 if (from !is null) {
2792 auto window = from.eventWindow (); 2858 auto window = from.eventWindow ();
2793 int origin_x, origin_y; 2859 int origin_x, origin_y;
2794 OS.gdk_window_get_origin (window, &origin_x, &origin_y); 2860 OS.gdk_window_get_origin (window, &origin_x, &origin_y);
2861 fromRTL = (from.style & DWT.MIRRORED) !is 0;
2862 if (fromRTL) rect.x = from.getClientWidth() - rect.x;
2795 rect.x += origin_x; 2863 rect.x += origin_x;
2796 rect.y += origin_y; 2864 rect.y += origin_y;
2797 } 2865 }
2798 if (to !is null) { 2866 if (to !is null) {
2799 auto window = to.eventWindow (); 2867 auto window = to.eventWindow ();
2800 int origin_x, origin_y; 2868 int origin_x, origin_y;
2801 OS.gdk_window_get_origin (window, &origin_x, &origin_y); 2869 OS.gdk_window_get_origin (window, &origin_x, &origin_y);
2802 rect.x -= origin_x; 2870 rect.x -= origin_x;
2803 rect.y -= origin_y; 2871 rect.y -= origin_y;
2804 } 2872 toRTL = (to.style & DWT.MIRRORED) !is 0;
2873 if (toRTL) rect.x = to.getClientWidth () - rect.x;
2874 }
2875 if (fromRTL !is toRTL) rect.x -= rect.width;
2805 return rect; 2876 return rect;
2806 } 2877 }
2807 2878
2808 private static extern(C) int /*long*/ mouseHoverProcFunc ( void* user_data) { 2879 private static extern(C) int /*long*/ mouseHoverProcFunc ( void* user_data) {
2809 version(LOG) Stderr.formatln( "Display {}:", __LINE__ ).flush; 2880 version(LOG) Stderr.formatln( "Display {}:", __LINE__ ).flush;
2868 * 2939 *
2869 * @since 3.0 2940 * @since 3.0
2870 * 2941 *
2871 */ 2942 */
2872 public bool post (Event event) { 2943 public bool post (Event event) {
2873 if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED); 2944 synchronized (Device.classinfo) {
2874 if (event is null) error (DWT.ERROR_NULL_ARGUMENT); 2945 if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED);
2875 if (!OS.GDK_WINDOWING_X11()) return false; 2946 if (event is null) error (DWT.ERROR_NULL_ARGUMENT);
2876 auto xDisplay = OS.GDK_DISPLAY (); 2947 if (!OS.GDK_WINDOWING_X11()) return false;
2877 int type = event.type; 2948 auto xDisplay = OS.GDK_DISPLAY ();
2878 switch (type) { 2949 int type = event.type;
2879 case DWT.KeyDown: 2950 switch (type) {
2880 case DWT.KeyUp: { 2951 case DWT.KeyDown:
2881 int keyCode = 0; 2952 case DWT.KeyUp: {
2882 auto keysym = untranslateKey (event.keyCode); 2953 int keyCode = 0;
2883 if (keysym !is 0) keyCode = OS.XKeysymToKeycode (xDisplay, keysym); 2954 auto keysym = untranslateKey (event.keyCode);
2884 if (keyCode is 0) { 2955 if (keysym !is 0) keyCode = OS.XKeysymToKeycode (xDisplay, keysym);
2885 char key = event.character; 2956 if (keyCode is 0) {
2886 switch (key) { 2957 char key = event.character;
2887 case DWT.BS: keysym = OS.GDK_BackSpace; break; 2958 switch (key) {
2888 case DWT.CR: keysym = OS.GDK_Return; break; 2959 case DWT.BS: keysym = OS.GDK_BackSpace; break;
2889 case DWT.DEL: keysym = OS.GDK_Delete; break; 2960 case DWT.CR: keysym = OS.GDK_Return; break;
2890 case DWT.ESC: keysym = OS.GDK_Escape; break; 2961 case DWT.DEL: keysym = OS.GDK_Delete; break;
2891 case DWT.TAB: keysym = OS.GDK_Tab; break; 2962 case DWT.ESC: keysym = OS.GDK_Escape; break;
2892 case DWT.LF: keysym = OS.GDK_Linefeed; break; 2963 case DWT.TAB: keysym = OS.GDK_Tab; break;
2893 default: 2964 case DWT.LF: keysym = OS.GDK_Linefeed; break;
2894 keysym = wcsToMbcs (key); 2965 default:
2966 keysym = key;
2967 }
2968 keyCode = OS.XKeysymToKeycode (xDisplay, keysym);
2969 if (keyCode is 0) return false;
2895 } 2970 }
2896 keyCode = OS.XKeysymToKeycode (xDisplay, keysym); 2971 OS.XTestFakeKeyEvent (xDisplay, keyCode, type is DWT.KeyDown, 0);
2897 if (keyCode is 0) return false; 2972 return true;
2898 } 2973 }
2899 OS.XTestFakeKeyEvent (xDisplay, keyCode, type is DWT.KeyDown, 0); 2974 case DWT.MouseDown:
2900 return true; 2975 case DWT.MouseMove:
2976 case DWT.MouseUp: {
2977 if (type is DWT.MouseMove) {
2978 OS.XTestFakeMotionEvent (xDisplay, -1, event.x, event.y, 0);
2979 } else {
2980 int button = event.button;
2981 switch (button) {
2982 case 1:
2983 case 2:
2984 case 3: break;
2985 case 4: button = 6; break;
2986 case 5: button = 7; break;
2987 default: return false;
2988 }
2989 OS.XTestFakeButtonEvent (xDisplay, button, type is DWT.MouseDown, 0);
2990 }
2991 return true;
2992 default:
2993 }
2994 /*
2995 * This code is intentionally commented. After posting a
2996 * mouse wheel event the system may respond unpredictably
2997 * to subsequent mouse actions.
2998 */
2999 // case DWT.MouseWheel: {
3000 // if (event.count is 0) return false;
3001 // int button = event.count < 0 ? 5 : 4;
3002 // OS.XTestFakeButtonEvent (xDisplay, button, type is DWT.MouseWheel, 0);
3003 // }
2901 } 3004 }
2902 case DWT.MouseDown: 3005 return false;
2903 case DWT.MouseMove: 3006 }
2904 case DWT.MouseUp: {
2905 if (type is DWT.MouseMove) {
2906 OS.XTestFakeMotionEvent (xDisplay, -1, event.x, event.y, 0);
2907 } else {
2908 int button = event.button;
2909 switch (button) {
2910 case 1:
2911 case 2:
2912 case 3: break;
2913 case 4: button = 6; break;
2914 case 5: button = 7; break;
2915 default: return false;
2916 }
2917 OS.XTestFakeButtonEvent (xDisplay, button, type is DWT.MouseDown, 0);
2918 }
2919 return true;
2920 default:
2921 }
2922 /*
2923 * This code is intentionally commented. After posting a
2924 * mouse wheel event the system may respond unpredictably
2925 * to subsequent mouse actions.
2926 */
2927 // case DWT.MouseWheel: {
2928 // if (event.count is 0) return false;
2929 // int button = event.count < 0 ? 5 : 4;
2930 // OS.XTestFakeButtonEvent (xDisplay, button, type is DWT.MouseWheel, 0);
2931 // }
2932 }
2933 return false;
2934 } 3007 }
2935 3008
2936 void postEvent (Event event) { 3009 void postEvent (Event event) {
2937 /* 3010 /*
2938 * Place the event at the end of the event queue. 3011 * Place the event at the end of the event queue.
3006 return true; 3079 return true;
3007 } 3080 }
3008 return runAsyncMessages (false); 3081 return runAsyncMessages (false);
3009 } 3082 }
3010 3083
3011 synchronized void register () { 3084 static void register (Display display) {
3012 for (int i=0; i<Displays.length; i++) { 3085 synchronized (Device.classinfo) {
3013 if (Displays [i] is null) { 3086 for (int i=0; i<Displays.length; i++) {
3014 Displays [i] = this; 3087 if (Displays [i] is null) {
3015 return; 3088 Displays [i] = display;
3089 return;
3090 }
3016 } 3091 }
3017 } 3092 Display [] newDisplays = new Display [Displays.length + 4];
3018 Display [] newDisplays = new Display [Displays.length + 4]; 3093 System.arraycopy (Displays, 0, newDisplays, 0, Displays.length);
3019 System.arraycopy (Displays, 0, newDisplays, 0, Displays.length); 3094 newDisplays [Displays.length] = display;
3020 newDisplays [Displays.length] = this; 3095 Displays = newDisplays;
3021 Displays = newDisplays; 3096 }
3022 } 3097 }
3023 3098
3024 /** 3099 /**
3025 * Releases any internal resources back to the operating 3100 * Releases any internal resources back to the operating
3026 * system and clears all fields except the device handle. 3101 * system and clears all fields except the device handle.
3068 } 3143 }
3069 3144
3070 void releaseDisplay () { 3145 void releaseDisplay () {
3071 3146
3072 /* Dispose xfilter callback */ 3147 /* Dispose xfilter callback */
3148 OS.gdk_window_remove_filter(null, &filterProcFunc, null);
3073 3149
3074 /* Dispose checkIfEvent callback */ 3150 /* Dispose checkIfEvent callback */
3075 3151
3076 /* Dispose preedit window */ 3152 /* Dispose preedit window */
3077 if (preeditWindow !is null) OS.gtk_widget_destroy ( &preeditWindow.bin.container.widget); 3153 if (preeditWindow !is null) OS.gtk_widget_destroy ( &preeditWindow.bin.container.widget);
3088 idleHandle = 0; 3164 idleHandle = 0;
3089 3165
3090 /* Dispose GtkTreeView callbacks */ 3166 /* Dispose GtkTreeView callbacks */
3091 3167
3092 /* Dispose the set direction callback */ 3168 /* Dispose the set direction callback */
3169
3170 /* Dispose the emission proc callback */
3093 3171
3094 /* Dispose the set direction callback */ 3172 /* Dispose the set direction callback */
3095 3173
3096 /* Dispose the caret callback */ 3174 /* Dispose the caret callback */
3097 if (caretId !is 0) OS.gtk_timeout_remove (caretId); 3175 if (caretId !is 0) OS.gtk_timeout_remove (caretId);
3144 3222
3145 /* Release the System Colors */ 3223 /* Release the System Colors */
3146 COLOR_WIDGET_DARK_SHADOW = COLOR_WIDGET_NORMAL_SHADOW = COLOR_WIDGET_LIGHT_SHADOW = 3224 COLOR_WIDGET_DARK_SHADOW = COLOR_WIDGET_NORMAL_SHADOW = COLOR_WIDGET_LIGHT_SHADOW =
3147 COLOR_WIDGET_HIGHLIGHT_SHADOW = COLOR_WIDGET_BACKGROUND = COLOR_WIDGET_BORDER = 3225 COLOR_WIDGET_HIGHLIGHT_SHADOW = COLOR_WIDGET_BACKGROUND = COLOR_WIDGET_BORDER =
3148 COLOR_LIST_FOREGROUND = COLOR_LIST_BACKGROUND = COLOR_LIST_SELECTION = COLOR_LIST_SELECTION_TEXT = 3226 COLOR_LIST_FOREGROUND = COLOR_LIST_BACKGROUND = COLOR_LIST_SELECTION = COLOR_LIST_SELECTION_TEXT =
3227 COLOR_WIDGET_FOREGROUND = COLOR_TITLE_FOREGROUND = COLOR_TITLE_BACKGROUND = COLOR_TITLE_BACKGROUND_GRADIENT =
3228 COLOR_TITLE_INACTIVE_FOREGROUND = COLOR_TITLE_INACTIVE_BACKGROUND = COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT =
3149 COLOR_INFO_BACKGROUND = COLOR_INFO_FOREGROUND = null; 3229 COLOR_INFO_BACKGROUND = COLOR_INFO_FOREGROUND = null;
3150 3230
3151 /* Dispose the event callback */ 3231 /* Dispose the event callback */
3152 OS.gdk_event_handler_set (null, null, null); 3232 OS.gdk_event_handler_set (null, null, null);
3153 3233
3164 fds = null; 3244 fds = null;
3165 3245
3166 /* Release references */ 3246 /* Release references */
3167 popups = null; 3247 popups = null;
3168 thread = null; 3248 thread = null;
3169 activeShell = null; 3249 lastWidget = activeShell = null;
3170 lastWidget = null; 3250 //flushData = null;
3171 indexTable = null; 3251 closures = null;
3172 widgetTable = null; 3252 indexTable = signalIds = treeSelection = null;
3253 widgetTable = modalShells = null;
3254 data = null;
3255 values = null;
3256 keys = null;
3257 windowManager = null;
3258 eventTable = filterTable = null;
3259 modalDialog = null;
3260 flushRect = null;
3261 exposeEvent = null;
3262 visibilityEvent = null;
3263 idleLock = null;
3173 } 3264 }
3174 3265
3175 /** 3266 /**
3176 * Removes the listener from the collection of listeners who will 3267 * Removes the listener from the collection of listeners who will
3177 * be notified when an event of the given type occurs anywhere in 3268 * be notified when an event of the given type occurs anywhere in
3217 } 3308 }
3218 return event; 3309 return event;
3219 } 3310 }
3220 3311
3221 void removeIdleProc () { 3312 void removeIdleProc () {
3222 synchronized(idleLock) { 3313 synchronized (idleLock) {
3223 if (idleHandle !is 0) OS.g_source_remove (idleHandle); 3314 if (idleHandle !is 0) OS.g_source_remove (idleHandle);
3224 idleNeeded = false; 3315 idleNeeded = false;
3225 idleHandle = 0; 3316 idleHandle = 0;
3226 } 3317 }
3227 } 3318 }
3453 dispatchEvents = wrappedValue.array; 3544 dispatchEvents = wrappedValue.array;
3454 if (value is null) putGdkEvents (); 3545 if (value is null) putGdkEvents ();
3455 return; 3546 return;
3456 } 3547 }
3457 } 3548 }
3458 3549 if (key.equals (SET_MODAL_DIALOG)) {
3459 if (key==/*eq*/ ADD_WIDGET_KEY) { 3550 setModalDialog (cast(Dialog) data);
3551 return;
3552 }
3553
3554 if (key.equals (ADD_WIDGET_KEY)) {
3460 auto wrap = cast(ArrayWrapperObject) value; 3555 auto wrap = cast(ArrayWrapperObject) value;
3461 if( wrap is null ) DWT.error(DWT.ERROR_INVALID_ARGUMENT, null, " []"); 3556 if( wrap is null ) DWT.error(DWT.ERROR_INVALID_ARGUMENT, null, " []");
3462 Object [] data = wrap.array; 3557 Object [] data = wrap.array;
3463 auto handle = (cast(LONG) data [0]).value; 3558 auto handle = (cast(LONG) data [0]).value;
3464 Widget widget = cast(Widget) data [1]; 3559 Widget widget = cast(Widget) data [1];
3562 CallbackData* cbdata = cast(CallbackData*)data; 3657 CallbackData* cbdata = cast(CallbackData*)data;
3563 return cbdata.display.setDirectionProc( widget, cast(int)cbdata.data ); 3658 return cbdata.display.setDirectionProc( widget, cast(int)cbdata.data );
3564 } 3659 }
3565 int /*long*/ setDirectionProc (GtkWidget* widget, int /*long*/ direction) { 3660 int /*long*/ setDirectionProc (GtkWidget* widget, int /*long*/ direction) {
3566 OS.gtk_widget_set_direction (widget, direction); 3661 OS.gtk_widget_set_direction (widget, direction);
3662 if (OS.GTK_IS_MENU_ITEM (widget)) {
3663 auto submenu = OS.gtk_menu_item_get_submenu (widget);
3664 if (submenu !is null) {
3665 OS.gtk_widget_set_direction (submenu, cast(int)/*64*/ direction);
3666 OS.gtk_container_forall (cast(GtkContainer*)submenu, cast(GtkCallback)&setDirectionProcFunc, cast(void*)direction);
3667 }
3668 }
3567 if (OS.GTK_IS_CONTAINER (cast(GTypeInstance*)widget)) { 3669 if (OS.GTK_IS_CONTAINER (cast(GTypeInstance*)widget)) {
3568 OS.gtk_container_forall (cast(GtkContainer*)widget, cast(GtkCallback)&setDirectionProcFunc, cast(void*)direction); 3670 OS.gtk_container_forall (cast(GtkContainer*)widget, cast(GtkCallback)&setDirectionProcFunc, cast(void*)direction);
3569 } 3671 }
3570 return 0; 3672 return 0;
3673 }
3674
3675 void setModalDialog (Dialog modalDailog) {
3676 this.modalDialog = modalDailog;
3677 Shell [] shells = getShells ();
3678 for (int i=0; i<shells.length; i++) shells [i].updateModal ();
3679 }
3680
3681 void setModalShell (Shell shell) {
3682 if (modalShells is null) modalShells = new Shell [4];
3683 int index = 0, length = modalShells.length;
3684 while (index < length) {
3685 if (modalShells [index] is shell) return;
3686 if (modalShells [index] is null) break;
3687 index++;
3688 }
3689 if (index is length) {
3690 Shell [] newModalShells = new Shell [length + 4];
3691 System.arraycopy (modalShells, 0, newModalShells, 0, length);
3692 modalShells = newModalShells;
3693 }
3694 modalShells [index] = shell;
3695 Shell [] shells = getShells ();
3696 for (int i=0; i<shells.length; i++) shells [i].updateModal ();
3571 } 3697 }
3572 3698
3573 /** 3699 /**
3574 * Sets the synchronizer used by the display to be 3700 * Sets the synchronizer used by the display to be
3575 * the argument, which can not be null. 3701 * the argument, which can not be null.
3586 * </ul> 3712 * </ul>
3587 */ 3713 */
3588 public void setSynchronizer (Synchronizer synchronizer) { 3714 public void setSynchronizer (Synchronizer synchronizer) {
3589 checkDevice (); 3715 checkDevice ();
3590 if (synchronizer is null) error (DWT.ERROR_NULL_ARGUMENT); 3716 if (synchronizer is null) error (DWT.ERROR_NULL_ARGUMENT);
3591 if (this.synchronizer !is null) { 3717 if (synchronizer is this.synchronizer) return;
3592 this.synchronizer.runAsyncMessages(true); 3718 Synchronizer oldSynchronizer;
3593 } 3719 synchronized (Device.classinfo) {
3594 this.synchronizer = synchronizer; 3720 oldSynchronizer = this.synchronizer;
3721 this.synchronizer = synchronizer;
3722 }
3723 if (oldSynchronizer !is null) {
3724 oldSynchronizer.runAsyncMessages(true);
3725 }
3595 } 3726 }
3596 3727
3597 void showIMWindow (Control control) { 3728 void showIMWindow (Control control) {
3598 imControl = control; 3729 imControl = control;
3599 if (preeditWindow is null) { 3730 if (preeditWindow is null) {
3963 * </ul> 4094 * </ul>
3964 * 4095 *
3965 * @see #asyncExec 4096 * @see #asyncExec
3966 */ 4097 */
3967 public void syncExec (Runnable runnable) { 4098 public void syncExec (Runnable runnable) {
3968 if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED); 4099 Synchronizer synchronizer;
3969 synchronized (idleLock) { 4100 synchronized (Device.classinfo) {
3970 if (idleNeeded && idleHandle is 0) { 4101 if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED);
3971 //NOTE: calling unlocked function in OS 4102 synchronizer = this.synchronizer;
4103 synchronized (idleLock) {
4104 if (idleNeeded && idleHandle is 0) {
4105 //NOTE: calling unlocked function in OS
3972 idleProcCallbackData.display = this; 4106 idleProcCallbackData.display = this;
3973 idleProcCallbackData.data = cast(void*)0; 4107 idleProcCallbackData.data = cast(void*)0;
3974 //PORTING_TODO: was _g_idle_add, calling directly 4108 //PORTING_TODO: was _g_idle_add, calling directly
3975 idleHandle = OS.g_idle_add (&idleProcFunc, &idleProcCallbackData); 4109 idleHandle = OS.g_idle_add (&idleProcFunc, &idleProcCallbackData);
4110 }
3976 } 4111 }
3977 } 4112 }
3978 synchronizer.syncExec (runnable); 4113 synchronizer.syncExec (runnable);
3979 } 4114 }
3980 4115
4019 * </ul> 4154 * </ul>
4020 * 4155 *
4021 * @see #sleep 4156 * @see #sleep
4022 */ 4157 */
4023 public void wake () { 4158 public void wake () {
4024 if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED); 4159 synchronized (Device.classinfo) {
4025 if (thread is Thread.getThis ()) return; 4160 if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED);
4026 wakeThread (); 4161 if (thread is Thread.getThis ()) return;
4162 wakeThread ();
4163 }
4027 } 4164 }
4028 4165
4029 void wakeThread () { 4166 void wakeThread () {
4030 OS.g_main_context_wakeup (null); 4167 OS.g_main_context_wakeup (null);
4031 wake_state = true; 4168 wake_state = true;