diff dwt/widgets/Widget.d @ 66:bb2217c09e61

Fixed signal blocking/unblocking: The right closure is chosen by the user_data value. In the D port the CallbackData struct is used to encapsulate also an instance pointer to the Display. When selecting the closure, the pointer of the CallbackData must be given instead of the integer constant. To make porting easier, value getter are created. They are called 'ud'+NAME.
author Frank Benoit <benoit@tionex.de>
date Sun, 13 Jan 2008 23:50:55 +0100
parents 6537a52fde85
children 15b21862b0ac
line wrap: on
line diff
--- a/dwt/widgets/Widget.d	Sat Jan 12 15:38:16 2008 +0100
+++ b/dwt/widgets/Widget.d	Sun Jan 13 23:50:55 2008 +0100
@@ -27,6 +27,11 @@
 import tango.stdc.string;
 import tango.core.Thread;
 
+//version=LOG;
+version(LOG){
+    import tango.io.Stdout;
+}
+
 /**
  * This class is the abstract superclass of all user interface objects.
  * Widgets are created, disposed and issue notification to listeners
@@ -172,6 +177,73 @@
     static const int MONTH_CHANGED = 61;
     static const int LAST_SIGNAL = 62;
 
+    template UD_Getter( char[] name ){
+        const char[] UD_Getter = "void* ud"~name~"(){ return getDisplay().getWindowProcUserData( "~name~"); }\n";
+    }
+
+    mixin ( UD_Getter!( "ACTIVATE" ));
+    mixin ( UD_Getter!( "BUTTON_PRESS_EVENT" ));
+    mixin ( UD_Getter!( "BUTTON_PRESS_EVENT_INVERSE" ));
+    mixin ( UD_Getter!( "BUTTON_RELEASE_EVENT" ));
+    mixin ( UD_Getter!( "BUTTON_RELEASE_EVENT_INVERSE" ));
+    mixin ( UD_Getter!( "CHANGED" ));
+    mixin ( UD_Getter!( "CHANGE_VALUE" ));
+    mixin ( UD_Getter!( "CLICKED" ));
+    mixin ( UD_Getter!( "COMMIT" ));
+    mixin ( UD_Getter!( "CONFIGURE_EVENT" ));
+    mixin ( UD_Getter!( "DELETE_EVENT" ));
+    mixin ( UD_Getter!( "DELETE_RANGE" ));
+    mixin ( UD_Getter!( "DELETE_TEXT" ));
+    mixin ( UD_Getter!( "ENTER_NOTIFY_EVENT" ));
+    mixin ( UD_Getter!( "EVENT" ));
+    mixin ( UD_Getter!( "EVENT_AFTER" ));
+    mixin ( UD_Getter!( "EXPAND_COLLAPSE_CURSOR_ROW" ));
+    mixin ( UD_Getter!( "EXPOSE_EVENT" ));
+    mixin ( UD_Getter!( "EXPOSE_EVENT_INVERSE" ));
+    mixin ( UD_Getter!( "FOCUS" ));
+    mixin ( UD_Getter!( "FOCUS_IN_EVENT" ));
+    mixin ( UD_Getter!( "FOCUS_OUT_EVENT" ));
+    mixin ( UD_Getter!( "GRAB_FOCUS" ));
+    mixin ( UD_Getter!( "HIDE" ));
+    mixin ( UD_Getter!( "INPUT" ));
+    mixin ( UD_Getter!( "INSERT_TEXT" ));
+    mixin ( UD_Getter!( "KEY_PRESS_EVENT" ));
+    mixin ( UD_Getter!( "KEY_RELEASE_EVENT" ));
+    mixin ( UD_Getter!( "LEAVE_NOTIFY_EVENT" ));
+    mixin ( UD_Getter!( "MAP" ));
+    mixin ( UD_Getter!( "MAP_EVENT" ));
+    mixin ( UD_Getter!( "MNEMONIC_ACTIVATE" ));
+    mixin ( UD_Getter!( "MOTION_NOTIFY_EVENT" ));
+    mixin ( UD_Getter!( "MOTION_NOTIFY_EVENT_INVERSE" ));
+    mixin ( UD_Getter!( "MOVE_FOCUS" ));
+    mixin ( UD_Getter!( "OUTPUT" ));
+    mixin ( UD_Getter!( "POPUP_MENU" ));
+    mixin ( UD_Getter!( "PREEDIT_CHANGED" ));
+    mixin ( UD_Getter!( "REALIZE" ));
+    mixin ( UD_Getter!( "ROW_ACTIVATED" ));
+    mixin ( UD_Getter!( "SCROLL_CHILD" ));
+    mixin ( UD_Getter!( "SCROLL_EVENT" ));
+    mixin ( UD_Getter!( "SELECT" ));
+    mixin ( UD_Getter!( "SHOW" ));
+    mixin ( UD_Getter!( "SHOW_HELP" ));
+    mixin ( UD_Getter!( "SIZE_ALLOCATE" ));
+    mixin ( UD_Getter!( "STYLE_SET" ));
+    mixin ( UD_Getter!( "SWITCH_PAGE" ));
+    mixin ( UD_Getter!( "TEST_COLLAPSE_ROW" ));
+    mixin ( UD_Getter!( "TEST_EXPAND_ROW" ));
+    mixin ( UD_Getter!( "TEXT_BUFFER_INSERT_TEXT" ));
+    mixin ( UD_Getter!( "TOGGLED" ));
+    mixin ( UD_Getter!( "UNMAP" ));
+    mixin ( UD_Getter!( "UNMAP_EVENT" ));
+    mixin ( UD_Getter!( "UNREALIZE" ));
+    mixin ( UD_Getter!( "VALUE_CHANGED" ));
+    mixin ( UD_Getter!( "VISIBILITY_NOTIFY_EVENT" ));
+    mixin ( UD_Getter!( "WINDOW_STATE_EVENT" ));
+    mixin ( UD_Getter!( "ACTIVATE_INVERSE" ));
+    mixin ( UD_Getter!( "DAY_SELECTED" ));
+    mixin ( UD_Getter!( "MONTH_CHANGED" ));
+    mixin ( UD_Getter!( "LAST_SIGNAL" ));
+
 /**
  * Prevents uninitialized instances from being created outside the package.
  */
@@ -921,9 +993,9 @@
 
 bool mnemonicHit (GtkWidget* mnemonicHandle, char key) {
     if (!mnemonicMatch (mnemonicHandle, key)) return false;
-    OS.g_signal_handlers_block_matched ( cast(void*)mnemonicHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, cast(void*)MNEMONIC_ACTIVATE);
+    OS.g_signal_handlers_block_matched ( cast(void*)mnemonicHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udMNEMONIC_ACTIVATE);
     bool result = cast(bool)OS.gtk_widget_mnemonic_activate (cast(GtkWidget*)mnemonicHandle, false);
-    OS.g_signal_handlers_unblock_matched (cast(void*)mnemonicHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, cast(void*)MNEMONIC_ACTIVATE);
+    OS.g_signal_handlers_unblock_matched (cast(void*)mnemonicHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udMNEMONIC_ACTIVATE);
     return result;
 }
 
@@ -1163,8 +1235,7 @@
     if (keyEvent is null) {
         ptr = OS.gtk_get_current_event ();
         if (ptr !is null) {
-            keyEvent = new GdkEventKey ();
-            memmove (keyEvent, ptr, GdkEventKey.sizeof);
+            keyEvent = cast(GdkEventKey*)ptr;
             switch (cast(int)keyEvent.type) {
                 case OS.GDK_KEY_PRESS:
                 case OS.GDK_KEY_RELEASE:
@@ -1447,31 +1518,76 @@
 }
 
 int /*long*/ windowProc (GtkWidget* handle, int /*long*/ user_data) {
+    void trace( char[] str ){
+        version(LOG) Stderr.formatln( "Widget windowProc {}", str ).flush;
+    }
+
     switch (cast(int)/*64*/user_data) {
-        case ACTIVATE: return gtk_activate (handle);
-        case CHANGED: return gtk_changed (handle);
-        case CLICKED: return gtk_clicked (handle);
-        case DAY_SELECTED: return gtk_day_selected (handle);
-        case HIDE: return gtk_hide (handle);
-        case GRAB_FOCUS: return gtk_grab_focus (handle);
-        case MAP: return gtk_map (handle);
-        case MONTH_CHANGED: return gtk_month_changed (handle);
-        case OUTPUT: return gtk_output (handle);
-        case POPUP_MENU: return gtk_popup_menu (handle);
-        case PREEDIT_CHANGED: return gtk_preedit_changed (cast(GtkIMContext*)handle);
-        case REALIZE: return gtk_realize (handle);
-        case SELECT: return gtk_select (cast(int)handle);
-        case SHOW: return gtk_show (handle);
-        case VALUE_CHANGED: return gtk_value_changed (cast(int)handle);
-        case UNMAP: return gtk_unmap (handle);
-        case UNREALIZE: return gtk_unrealize (handle);
-        default: return 0;
+        case ACTIVATE:
+            trace( "ACTIVATE" );
+            return gtk_activate (handle);
+        case CHANGED:
+            trace( "CHANGED" );
+            return gtk_changed (handle);
+        case CLICKED:
+            trace( "CLICKED" );
+            return gtk_clicked (handle);
+        case DAY_SELECTED:
+            trace( "DAY_SELECTED" );
+            return gtk_day_selected (handle);
+        case HIDE:
+            trace( "HIDE" );
+            return gtk_hide (handle);
+        case GRAB_FOCUS:
+            trace( "GRAB_FOCUS" );
+            return gtk_grab_focus (handle);
+        case MAP:
+            trace( "MAP" );
+            return gtk_map (handle);
+        case MONTH_CHANGED:
+            trace( "MONTH_CHANGED" );
+            return gtk_month_changed (handle);
+        case OUTPUT:
+            trace( "OUTPUT" );
+            return gtk_output (handle);
+        case POPUP_MENU:
+            trace( "POPUP_MENU" );
+            return gtk_popup_menu (handle);
+        case PREEDIT_CHANGED:
+            trace( "PREEDIT_CHANGED" );
+            return gtk_preedit_changed (cast(GtkIMContext*)handle);
+        case REALIZE:
+            trace( "REALIZE" );
+            return gtk_realize (handle);
+        case SELECT:
+            trace( "SELECT" );
+            return gtk_select (cast(int)handle);
+        case SHOW:
+            trace( "SHOW" );
+            return gtk_show (handle);
+        case VALUE_CHANGED:
+            trace( "VALUE_CHANGED" );
+            return gtk_value_changed (cast(int)handle);
+        case UNMAP:
+            trace( "UNMAP" );
+            return gtk_unmap (handle);
+        case UNREALIZE:
+            trace( "UNREALIZE" );
+            return gtk_unrealize (handle);
+        default:
+            trace( "default" );
+            return 0;
     }
 }
 
 int /*long*/ windowProc (GtkWidget* handle, int /*long*/ arg0, int /*long*/ user_data) {
+    void trace( char[] str ){
+        version(LOG) Stderr.formatln( "Widget windowProc1 {}", str ).flush;
+    }
+
     switch (cast(int)/*64*/user_data) {
         case EXPOSE_EVENT_INVERSE: {
+            trace( "EXPOSE_EVENT_INVERSE" );
             GdkEventExpose* gdkEvent = cast(GdkEventExpose*) arg0;
             auto paintWindow = paintWindow();
             auto window = gdkEvent.window;
@@ -1481,60 +1597,153 @@
         case BUTTON_PRESS_EVENT_INVERSE:
         case BUTTON_RELEASE_EVENT_INVERSE:
         case MOTION_NOTIFY_EVENT_INVERSE: {
+            trace( "BUTTON_PRESS_EVENT_INVERSE BUTTON_RELEASE_EVENT_INVERSE MOTION_NOTIFY_EVENT_INVERSE" );
             return 1;
         }
-        case BUTTON_PRESS_EVENT: return gtk_button_press_event (handle, cast(GdkEventButton*)arg0);
-        case BUTTON_RELEASE_EVENT: return gtk_button_release_event (handle, cast(GdkEventButton*)arg0);
-        case COMMIT: return gtk_commit (cast(GtkIMContext*)handle, cast(char*)arg0);
-        case CONFIGURE_EVENT: return gtk_configure_event (handle, arg0);
-        case DELETE_EVENT: return gtk_delete_event (handle, arg0);
-        case ENTER_NOTIFY_EVENT: return gtk_enter_notify_event (handle, cast(GdkEventCrossing*)arg0);
-        case EVENT: return gtk_event (handle, cast(GdkEvent*)arg0);
-        case EVENT_AFTER: return gtk_event_after (handle, cast(GdkEvent*)arg0);
-        case EXPOSE_EVENT: return gtk_expose_event (handle, cast(GdkEventExpose*)arg0);
-        case FOCUS: return gtk_focus (handle, arg0);
-        case FOCUS_IN_EVENT: return gtk_focus_in_event (handle, cast(GdkEventFocus*)arg0);
-        case FOCUS_OUT_EVENT: return gtk_focus_out_event (handle, cast(GdkEventFocus*)arg0);
-        case KEY_PRESS_EVENT: return gtk_key_press_event (handle, cast(GdkEventKey*)arg0);
-        case KEY_RELEASE_EVENT: return gtk_key_release_event (handle, cast(GdkEventKey*)arg0);
-        case INPUT: return gtk_input (handle, arg0);
-        case LEAVE_NOTIFY_EVENT: return gtk_leave_notify_event (handle, cast(GdkEventCrossing*)arg0);
-        case MAP_EVENT: return gtk_map_event (handle, arg0);
-        case MNEMONIC_ACTIVATE: return gtk_mnemonic_activate (handle, arg0);
-        case MOTION_NOTIFY_EVENT: return gtk_motion_notify_event (handle, cast(GdkEventMotion*)arg0);
-        case MOVE_FOCUS: return gtk_move_focus (handle, arg0);
-        case SCROLL_EVENT:  return gtk_scroll_event (handle, cast(GdkEventScroll*)arg0);
-        case SHOW_HELP: return gtk_show_help (handle, arg0);
-        case SIZE_ALLOCATE: return gtk_size_allocate (handle, arg0);
-        case STYLE_SET: return gtk_style_set (handle, arg0);
-        case TOGGLED: return gtk_toggled (cast(int)handle, arg0);
-        case UNMAP_EVENT: return gtk_unmap_event (handle, arg0);
-        case VISIBILITY_NOTIFY_EVENT: return gtk_visibility_notify_event (handle, cast(GdkEventVisibility*)arg0);
-        case WINDOW_STATE_EVENT: return gtk_window_state_event (handle, cast(GdkEventWindowState*)arg0);
-        default: return 0;
+        case BUTTON_PRESS_EVENT:
+            trace( "BUTTON_PRESS_EVENT" );
+            return gtk_button_press_event (handle, cast(GdkEventButton*)arg0);
+        case BUTTON_RELEASE_EVENT:
+            trace( "BUTTON_RELEASE_EVENT" );
+            return gtk_button_release_event (handle, cast(GdkEventButton*)arg0);
+        case COMMIT:
+            trace( "COMMIT" );
+            return gtk_commit (cast(GtkIMContext*)handle, cast(char*)arg0);
+        case CONFIGURE_EVENT:
+            trace( "CONFIGURE_EVENT" );
+            return gtk_configure_event (handle, arg0);
+        case DELETE_EVENT:
+            trace( "DELETE_EVENT" );
+            return gtk_delete_event (handle, arg0);
+        case ENTER_NOTIFY_EVENT:
+            trace( "ENTER_NOTIFY_EVENT" );
+            return gtk_enter_notify_event (handle, cast(GdkEventCrossing*)arg0);
+        case EVENT:
+            trace( "EVENT" );
+            return gtk_event (handle, cast(GdkEvent*)arg0);
+        case EVENT_AFTER:
+            trace( "EVENT_AFTER" );
+            return gtk_event_after (handle, cast(GdkEvent*)arg0);
+        case EXPOSE_EVENT:
+            trace( "EXPOSE_EVENT" );
+            return gtk_expose_event (handle, cast(GdkEventExpose*)arg0);
+        case FOCUS:
+            trace( "FOCUS" );
+            return gtk_focus (handle, arg0);
+        case FOCUS_IN_EVENT:
+            trace( "FOCUS_IN_EVENT" );
+            return gtk_focus_in_event (handle, cast(GdkEventFocus*)arg0);
+        case FOCUS_OUT_EVENT:
+            trace( "FOCUS_OUT_EVENT" );
+            return gtk_focus_out_event (handle, cast(GdkEventFocus*)arg0);
+        case KEY_PRESS_EVENT:
+            trace( "KEY_PRESS_EVENT" );
+            return gtk_key_press_event (handle, cast(GdkEventKey*)arg0);
+        case KEY_RELEASE_EVENT:
+            trace( "KEY_RELEASE_EVENT" );
+            return gtk_key_release_event (handle, cast(GdkEventKey*)arg0);
+        case INPUT:
+            trace( "INPUT" );
+            return gtk_input (handle, arg0);
+        case LEAVE_NOTIFY_EVENT:
+            trace( "LEAVE_NOTIFY_EVENT" );
+            return gtk_leave_notify_event (handle, cast(GdkEventCrossing*)arg0);
+        case MAP_EVENT:
+            trace( "MAP_EVENT" );
+            return gtk_map_event (handle, arg0);
+        case MNEMONIC_ACTIVATE:
+            trace( "MNEMONIC_ACTIVATE" );
+            return gtk_mnemonic_activate (handle, arg0);
+        case MOTION_NOTIFY_EVENT:
+            trace( "MOTION_NOTIFY_EVENT" );
+            return gtk_motion_notify_event (handle, cast(GdkEventMotion*)arg0);
+        case MOVE_FOCUS:
+            trace( "MOVE_FOCUS" );
+            return gtk_move_focus (handle, arg0);
+        case SCROLL_EVENT:
+            trace( "SCROLL_EVENT" );
+            return gtk_scroll_event (handle, cast(GdkEventScroll*)arg0);
+        case SHOW_HELP:
+            trace( "SHOW_HELP" );
+            return gtk_show_help (handle, arg0);
+        case SIZE_ALLOCATE:
+            trace( "SIZE_ALLOCATE" );
+            return gtk_size_allocate (handle, arg0);
+        case STYLE_SET:
+            trace( "STYLE_SET" );
+            return gtk_style_set (handle, arg0);
+        case TOGGLED:
+            trace( "TOGGLED" );
+            return gtk_toggled (cast(int)handle, arg0);
+        case UNMAP_EVENT:
+            trace( "UNMAP_EVENT" );
+            return gtk_unmap_event (handle, arg0);
+        case VISIBILITY_NOTIFY_EVENT:
+            trace( "VISIBILITY_NOTIFY_EVENT" );
+            return gtk_visibility_notify_event (handle, cast(GdkEventVisibility*)arg0);
+        case WINDOW_STATE_EVENT:
+            trace( "WINDOW_STATE_EVENT" );
+            return gtk_window_state_event (handle, cast(GdkEventWindowState*)arg0);
+        default:
+            trace( "default" );
+            return 0;
     }
 }
 
 int /*long*/ windowProc (GtkWidget* handle, int /*long*/ arg0, int /*long*/ arg1, int /*long*/ user_data) {
+    void trace( char[] str ){
+        version(LOG) Stderr.formatln( "Widget windowProc2 {}", str ).flush;
+    }
+
     switch (cast(int)/*64*/user_data) {
-        case DELETE_RANGE: return gtk_delete_range (handle, arg0, arg1);
-        case DELETE_TEXT: return gtk_delete_text (handle, arg0, arg1);
-        case ROW_ACTIVATED: return gtk_row_activated (cast(int)handle, arg0, arg1);
-        case SCROLL_CHILD: return gtk_scroll_child (handle, arg0, arg1);
-        case SWITCH_PAGE: return gtk_switch_page (handle, arg0, arg1);
-        case TEST_COLLAPSE_ROW: return gtk_test_collapse_row (cast(int)handle, arg0, arg1);
-        case TEST_EXPAND_ROW: return gtk_test_expand_row(cast(int)handle, arg0, arg1);
-        default: return 0;
+        case DELETE_RANGE:
+            trace( "DELETE_RANGE" );
+            return gtk_delete_range (handle, arg0, arg1);
+        case DELETE_TEXT:
+            trace( "DELETE_TEXT" );
+            return gtk_delete_text (handle, arg0, arg1);
+        case ROW_ACTIVATED:
+            trace( "ROW_ACTIVATED" );
+            return gtk_row_activated (cast(int)handle, arg0, arg1);
+        case SCROLL_CHILD:
+            trace( "SCROLL_CHILD" );
+            return gtk_scroll_child (handle, arg0, arg1);
+        case SWITCH_PAGE:
+            trace( "SWITCH_PAGE" );
+            return gtk_switch_page (handle, arg0, arg1);
+        case TEST_COLLAPSE_ROW:
+            trace( "TEST_COLLAPSE_ROW" );
+            return gtk_test_collapse_row (cast(int)handle, arg0, arg1);
+        case TEST_EXPAND_ROW:
+            trace( "TEST_EXPAND_ROW" );
+            return gtk_test_expand_row(cast(int)handle, arg0, arg1);
+        default:
+            trace( "default" );
+            return 0;
     }
 }
 
 int /*long*/ windowProc (GtkWidget* handle, int /*long*/ arg0, int /*long*/ arg1, int /*long*/ arg2, int /*long*/ user_data) {
+    void trace( char[] str ){
+        version(LOG) Stderr.formatln( "Widget windowProc3 {}", str ).flush;
+    }
+
     switch (cast(int)/*64*/user_data) {
-        case CHANGE_VALUE: return gtk_change_value (handle, arg0, arg1, arg2);
-        case EXPAND_COLLAPSE_CURSOR_ROW: return gtk_expand_collapse_cursor_row (handle, arg0, arg1, arg2);
-        case INSERT_TEXT: return gtk_insert_text (cast(GtkEditable*)handle, cast(char*)arg0, arg1, arg2);
-        case TEXT_BUFFER_INSERT_TEXT: return gtk_text_buffer_insert_text (cast(GtkTextBuffer*)handle, cast(GtkTextIter*)arg0, cast(char*)arg1, arg2);
-        default: return 0;
+        case CHANGE_VALUE:
+            trace( "CHANGE_VALUE" );
+            return gtk_change_value (handle, arg0, arg1, arg2);
+        case EXPAND_COLLAPSE_CURSOR_ROW:
+            trace( "EXPAND_COLLAPSE_CURSOR_ROW" );
+            return gtk_expand_collapse_cursor_row (handle, arg0, arg1, arg2);
+        case INSERT_TEXT:
+            trace( "INSERT_TEXT" );
+            return gtk_insert_text (cast(GtkEditable*)handle, cast(char*)arg0, arg1, arg2);
+        case TEXT_BUFFER_INSERT_TEXT:
+            trace( "TEXT_BUFFER_INSERT_TEXT" );
+            return gtk_text_buffer_insert_text (cast(GtkTextBuffer*)handle, cast(GtkTextIter*)arg0, cast(char*)arg1, arg2);
+        default:
+            trace( "default" );
+            return 0;
     }
 }