From: michael Date: Mon, 21 Jan 2002 18:07:48 +0000 (+0000) Subject: 2002-01-18 Michael Meeks X-Git-Tag: AT_SPI2_ATK_2_12_0~1427 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git;a=commitdiff_plain;h=f857d60677eff94e961c6c04f7e42b1591624412;hp=b91a3b15184b1b88e6f07da8ef21660da2b3001d 2002-01-18 Michael Meeks * test/test-simple.c (key_listener_cb): consume the key. (test_keylisteners): update. (main): wait for any pending unrefs on events. * registryd/deviceeventcontroller.c (spi_controller_update_key_grabs): only re-issue the grab on a key release. (spi_device_event_controller_forward_key_event): refresh the keygrabs before we notify the listeners, to reduce the X ungrab / re-grab race. (spi_controller_register_with_devices): remove XSelectInput - we do that with the gdk_window_ call. (_spi_controller_device_error_handler): return a value. s/GDK_DISPLAY/spi_get_display/ 2002-01-17 Michael Meeks * registryd/deviceeventcontroller.c (_deregister_keygrab): don't blow out the later assertion. * test/test-simple.c (test_keylisteners): do a more intelligent validation. 2002-01-14 Michael Meeks * atk-bridge/bridge.c (gnome_accessibility_module_init), (gnome_accessibility_module_shutdown): impl. (gtk_module_init): protect vs. double inits. (add_signal_listener): impl. (spi_atk_bridge_state_event_listener): kill (deregister_application): split out of (spi_atk_bridge_exit_func): here. git-svn-id: http://svn.gnome.org/svn/at-spi/trunk@228 e2bd861d-eb25-0410-b326-f6ed22b6b98c --- diff --git a/ChangeLog b/ChangeLog index 26623ae..f397960 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,41 @@ +2002-01-18 Michael Meeks + + * test/test-simple.c + (key_listener_cb): consume the key. + (test_keylisteners): update. + (main): wait for any pending unrefs on events. + + * registryd/deviceeventcontroller.c + (spi_controller_update_key_grabs): only re-issue the + grab on a key release. + (spi_device_event_controller_forward_key_event): + refresh the keygrabs before we notify the listeners, + to reduce the X ungrab / re-grab race. + (spi_controller_register_with_devices): remove + XSelectInput - we do that with the gdk_window_ call. + (_spi_controller_device_error_handler): return a value. + s/GDK_DISPLAY/spi_get_display/ + +2002-01-17 Michael Meeks + + * registryd/deviceeventcontroller.c + (_deregister_keygrab): don't blow out the later + assertion. + + * test/test-simple.c (test_keylisteners): do a + more intelligent validation. + +2002-01-14 Michael Meeks + + * atk-bridge/bridge.c + (gnome_accessibility_module_init), + (gnome_accessibility_module_shutdown): impl. + (gtk_module_init): protect vs. double inits. + (add_signal_listener): impl. + (spi_atk_bridge_state_event_listener): kill + (deregister_application): split out of + (spi_atk_bridge_exit_func): here. + 2002-01-18 Bill Haneman * test/simple-at.c: diff --git a/atk-bridge/bridge.c b/atk-bridge/bridge.c index 53c3d87..5c285b1 100644 --- a/atk-bridge/bridge.c +++ b/atk-bridge/bridge.c @@ -38,30 +38,45 @@ static CORBA_Environment ev; static Accessibility_Registry registry; static SpiApplication *this_app = NULL; -static gboolean spi_atk_bridge_idle_init (gpointer user_data); -static void spi_atk_bridge_focus_tracker (AtkObject *object); -static void spi_atk_bridge_exit_func (void); -static void spi_atk_register_event_listeners (void); +static void spi_atk_bridge_exit_func (void); +static void spi_atk_register_event_listeners (void); +static gboolean spi_atk_bridge_idle_init (gpointer user_data); +static void spi_atk_bridge_focus_tracker (AtkObject *object); static gboolean spi_atk_bridge_property_event_listener (GSignalInvocationHint *signal_hint, - guint n_param_values, - const GValue *param_values, - gpointer data); -static gboolean spi_atk_bridge_state_event_listener (GSignalInvocationHint *signal_hint, - guint n_param_values, - const GValue *param_values, - gpointer data); -static gboolean spi_atk_bridge_signal_listener (GSignalInvocationHint *signal_hint, - guint n_param_values, - const GValue *param_values, - gpointer data); -static gint spi_atk_bridge_key_listener (AtkKeyEventStruct *event, - gpointer data); + guint n_param_values, + const GValue *param_values, + gpointer data); +static gboolean spi_atk_bridge_signal_listener (GSignalInvocationHint *signal_hint, + guint n_param_values, + const GValue *param_values, + gpointer data); +static gint spi_atk_bridge_key_listener (AtkKeyEventStruct *event, + gpointer data); + +/* + * These exported symbols are hooked by gnome-program + * to provide automatic module initialization and shutdown. + */ +extern void gnome_accessibility_module_init (void); +extern void gnome_accessibility_module_shutdown (void); + +static int atk_bridge_initialized = FALSE; +static guint atk_bridge_focus_tracker_id = 0; +static guint atk_bridge_key_event_listener_id = 0; +static guint idle_init_id = 0; +static GArray *listener_ids = NULL; int gtk_module_init (gint *argc, gchar **argv[]) { CORBA_Environment ev; + if (atk_bridge_initialized) + { + return 0; + } + atk_bridge_initialized = TRUE; + if (!bonobo_init (argc, *argv)) { g_error ("Could not initialize Bonobo"); @@ -99,7 +114,7 @@ gtk_module_init (gint *argc, gchar **argv[]) g_atexit (spi_atk_bridge_exit_func); - g_idle_add (spi_atk_bridge_idle_init, NULL); + idle_init_id = g_idle_add (spi_atk_bridge_idle_init, NULL); return 0; } @@ -107,6 +122,8 @@ gtk_module_init (gint *argc, gchar **argv[]) static gboolean spi_atk_bridge_idle_init (gpointer user_data) { + idle_init_id = 0; + spi_atk_register_event_listeners (); fprintf (stderr, "Application registered & listening\n"); @@ -115,45 +132,75 @@ spi_atk_bridge_idle_init (gpointer user_data) } static void +add_signal_listener (const char *signal_name) +{ + guint id; + + id = atk_add_global_event_listener ( + spi_atk_bridge_signal_listener, signal_name); + + g_array_append_val (listener_ids, id); +} + +static void spi_atk_register_event_listeners (void) { /* * kludge to make sure the Atk interface types are registered, otherwise * the AtkText signal handlers below won't get registered */ + guint id; GObject *ao = g_object_new (ATK_TYPE_OBJECT, NULL); AtkObject *bo = atk_no_op_object_new (ao); /* Register for focus event notifications, and register app with central registry */ - atk_add_focus_tracker (spi_atk_bridge_focus_tracker); - atk_add_global_event_listener (spi_atk_bridge_property_event_listener, "Gtk:AtkObject:property-change"); - atk_add_global_event_listener (spi_atk_bridge_signal_listener, "Gtk:AtkObject:children-changed"); - atk_add_global_event_listener (spi_atk_bridge_signal_listener, "Gtk:AtkObject:visible-data-changed"); - atk_add_global_event_listener (spi_atk_bridge_signal_listener, "Gtk:AtkSelection:selection-changed"); - atk_add_global_event_listener (spi_atk_bridge_signal_listener, "Gtk:AtkText:text-selection-changed"); - atk_add_global_event_listener (spi_atk_bridge_signal_listener, "Gtk:AtkText:text-changed"); - atk_add_global_event_listener (spi_atk_bridge_signal_listener, "Gtk:AtkText:text-caret-moved"); - atk_add_global_event_listener (spi_atk_bridge_signal_listener, "Gtk:AtkTable:row-inserted"); - atk_add_global_event_listener (spi_atk_bridge_signal_listener, "Gtk:AtkTable:row-reordered"); - atk_add_global_event_listener (spi_atk_bridge_signal_listener, "Gtk:AtkTable:row-deleted"); - atk_add_global_event_listener (spi_atk_bridge_signal_listener, "Gtk:AtkTable:column-inserted"); - atk_add_global_event_listener (spi_atk_bridge_signal_listener, "Gtk:AtkTable:column-reordered"); - atk_add_global_event_listener (spi_atk_bridge_signal_listener, "Gtk:AtkTable:column-deleted"); - atk_add_global_event_listener (spi_atk_bridge_signal_listener, "Gtk:AtkTable:model-changed"); + listener_ids = g_array_sized_new (FALSE, TRUE, sizeof (guint), 16); + + atk_bridge_focus_tracker_id = atk_add_focus_tracker (spi_atk_bridge_focus_tracker); + + id = atk_add_global_event_listener (spi_atk_bridge_property_event_listener, + "Gtk:AtkObject:property-change"); + g_array_append_val (listener_ids, id); + + add_signal_listener ("Gtk:AtkObject:children-changed"); + add_signal_listener ("Gtk:AtkObject:visible-data-changed"); + add_signal_listener ("Gtk:AtkSelection:selection-changed"); + add_signal_listener ("Gtk:AtkText:text-selection-changed"); + add_signal_listener ("Gtk:AtkText:text-changed"); + add_signal_listener ("Gtk:AtkText:text-caret-moved"); + add_signal_listener ("Gtk:AtkTable:row-inserted"); + add_signal_listener ("Gtk:AtkTable:row-reordered"); + add_signal_listener ("Gtk:AtkTable:row-deleted"); + add_signal_listener ("Gtk:AtkTable:column-inserted"); + add_signal_listener ("Gtk:AtkTable:column-reordered"); + add_signal_listener ("Gtk:AtkTable:column-deleted"); + add_signal_listener ("Gtk:AtkTable:model-changed"); /* * May add the following listeners to implement preemptive key listening for GTK+ * * atk_add_global_event_listener (spi_atk_bridge_widgetkey_listener, "Gtk:GtkWidget:key-press-event"); * atk_add_global_event_listener (spi_atk_bridge_widgetkey_listener, "Gtk:GtkWidget:key-release-event"); */ - atk_add_key_event_listener (spi_atk_bridge_key_listener, NULL); + atk_bridge_key_event_listener_id = atk_add_key_event_listener ( + spi_atk_bridge_key_listener, NULL); g_object_unref (G_OBJECT (bo)); g_object_unref (ao); } static void +deregister_application (BonoboObject *app) +{ + Accessibility_Registry_deregisterApplication ( + registry, BONOBO_OBJREF (app), &ev); + + registry = bonobo_object_release_unref (registry, &ev); + + app = bonobo_object_unref (app); +} + +static void spi_atk_bridge_exit_func (void) { BonoboObject *app = (BonoboObject *) this_app; @@ -178,13 +225,8 @@ spi_atk_bridge_exit_func (void) g_assert (bonobo_activate ()); } - Accessibility_Registry_deregisterApplication ( - registry, BONOBO_OBJREF (app), &ev); + deregister_application (app); - bonobo_object_release_unref (registry, &ev); - - bonobo_object_unref (app); - fprintf (stderr, "bridge exit func complete.\n"); if (g_getenv ("AT_BRIDGE_SHUTDOWN")) @@ -193,6 +235,52 @@ spi_atk_bridge_exit_func (void) } } +void +gnome_accessibility_module_init (void) +{ + gtk_module_init (NULL, NULL); + + g_print("Atk Accessibilty bridge initialized\n"); +} + +void +gnome_accessibility_module_shutdown (void) +{ + BonoboObject *app = (BonoboObject *) this_app; + + if (!atk_bridge_initialized) + { + return; + } + atk_bridge_initialized = FALSE; + this_app = NULL; + + g_print("Atk Accessibilty bridge shutdown\n"); + + if (idle_init_id) + { + g_source_remove (idle_init_id); + idle_init_id = 0; + } + else + { + int i; + GArray *ids = listener_ids; + + listener_ids = NULL; + atk_remove_focus_tracker (atk_bridge_focus_tracker_id); + + for (i = 0; ids && i < ids->len; i++) + { + atk_remove_global_event_listener (g_array_index (ids, guint, i)); + } + + atk_remove_key_event_listener (atk_bridge_key_event_listener_id); + } + + deregister_application (app); +} + static void spi_atk_bridge_focus_tracker (AtkObject *object) { @@ -300,6 +388,7 @@ spi_atk_bridge_property_event_listener (GSignalInvocationHint *signal_hint, return TRUE; } +#if THIS_WILL_EVER_BE_USED static gboolean spi_atk_bridge_state_event_listener (GSignalInvocationHint *signal_hint, guint n_param_values, @@ -328,6 +417,7 @@ spi_atk_bridge_state_event_listener (GSignalInvocationHint *signal_hint, return TRUE; } +#endif static void spi_init_keystroke_from_atk_key_event (Accessibility_DeviceEvent *keystroke, @@ -442,10 +532,3 @@ spi_atk_bridge_signal_listener (GSignalInvocationHint *signal_hint, return TRUE; } - - - - - - - diff --git a/libspi/accessible.c b/libspi/accessible.c index dd791c1..ba2b4e1 100644 --- a/libspi/accessible.c +++ b/libspi/accessible.c @@ -376,9 +376,8 @@ static CORBA_char * impl_accessibility_accessible_get_role_name (PortableServer_Servant servant, CORBA_Environment *ev) { - AtkRole role; - Accessibility_Role retval; - AtkObject *object = get_atkobject_from_servant (servant); + AtkRole role; + AtkObject *object = get_atkobject_from_servant (servant); g_return_val_if_fail (object != NULL, 0); diff --git a/registryd/deviceeventcontroller.c b/registryd/deviceeventcontroller.c index 3f7731c..153fde6 100644 --- a/registryd/deviceeventcontroller.c +++ b/registryd/deviceeventcontroller.c @@ -89,12 +89,14 @@ static void spi_controller_register_device_listener (SpiDEController static void spi_device_event_controller_forward_key_event (SpiDEController *controller, const XEvent *event); +#define spi_get_display() GDK_DISPLAY() + /* Private methods */ static KeyCode keycode_for_keysym (long keysym) { - return XKeysymToKeycode (GDK_DISPLAY (), (KeySym) keysym); + return XKeysymToKeycode (spi_get_display (), (KeySym) keysym); } static DEControllerGrabMask * @@ -213,7 +215,10 @@ _deregister_keygrab (SpiDEController *controller, DEControllerGrabMask *cur_mask = l->data; cur_mask->ref_count--; - cur_mask->pending_remove = TRUE; + if (cur_mask->ref_count <= 0) + { + cur_mask->pending_remove = TRUE; + } } else { @@ -245,7 +250,7 @@ handle_keygrab (SpiDEController *controller, /* X Grabs require keycodes, not keysyms */ if (key_val >= 0) { - key_val = XKeysymToKeycode (GDK_DISPLAY (), (KeySym) key_val); + key_val = XKeysymToKeycode (spi_get_display (), (KeySym) key_val); } grab_mask.key_val = key_val; @@ -318,10 +323,11 @@ _spi_controller_device_error_handler (Display *display, XErrorEvent *error) if (error->error_code == BadAccess) { g_message ("Could not complete key grab: grab already in use.\n"); + return 0; } else { - (*x_default_error_handler) (display, error); + return (*x_default_error_handler) (display, error); } } @@ -338,10 +344,6 @@ spi_controller_register_with_devices (SpiDEController *controller) GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK); x_default_error_handler = XSetErrorHandler (_spi_controller_device_error_handler); - - XSelectInput (GDK_DISPLAY (), - DefaultRootWindow (GDK_DISPLAY ()), - KeyPressMask | KeyReleaseMask); } static gboolean @@ -595,6 +597,7 @@ spi_controller_update_key_grabs (SpiDEController *controller, next = l->next; re_issue_grab = recv && +/* (recv->type == Accessibility_KEY_RELEASED) && - (?) */ (recv->modifiers & grab_mask->mod_mask) && (grab_mask->key_val == keycode_for_keysym (recv->id)); @@ -618,7 +621,7 @@ spi_controller_update_key_grabs (SpiDEController *controller, #ifdef SPI_DEBUG fprintf (stderr, "ungrabbing, mask=%x\n", grab_mask->mod_mask); #endif - XUngrabKey (GDK_DISPLAY (), + XUngrabKey (spi_get_display (), grab_mask->key_val, grab_mask->mod_mask, gdk_x11_get_default_root_xwindow ()); @@ -631,7 +634,7 @@ spi_controller_update_key_grabs (SpiDEController *controller, #ifdef SPI_DEBUG fprintf (stderr, "grab with mask %x\n", grab_mask->mod_mask); #endif - XGrabKey (GDK_DISPLAY (), + XGrabKey (spi_get_display (), grab_mask->key_val, grab_mask->mod_mask, gdk_x11_get_default_root_xwindow (), @@ -673,7 +676,7 @@ spi_device_event_controller_object_finalize (GObject *object) fprintf(stderr, "spi_device_event_controller_object_finalize called\n"); #endif /* disconnect any special listeners, get rid of outstanding keygrabs */ - XUngrabKey (GDK_DISPLAY (), AnyKey, AnyModifier, DefaultRootWindow (GDK_DISPLAY ())); + XUngrabKey (spi_get_display (), AnyKey, AnyModifier, DefaultRootWindow (spi_get_display ())); spi_device_event_controller_parent_class->finalize (object); } @@ -819,17 +822,17 @@ impl_generate_keyboard_event (PortableServer_Servant servant, switch (synth_type) { case Accessibility_KEY_PRESS: - XTestFakeKeyEvent (GDK_DISPLAY (), (unsigned int) keycode, True, CurrentTime); + XTestFakeKeyEvent (spi_get_display (), (unsigned int) keycode, True, CurrentTime); break; case Accessibility_KEY_PRESSRELEASE: - XTestFakeKeyEvent (GDK_DISPLAY (), (unsigned int) keycode, True, CurrentTime); + XTestFakeKeyEvent (spi_get_display (), (unsigned int) keycode, True, CurrentTime); case Accessibility_KEY_RELEASE: - XTestFakeKeyEvent (GDK_DISPLAY (), (unsigned int) keycode, False, CurrentTime); + XTestFakeKeyEvent (spi_get_display (), (unsigned int) keycode, False, CurrentTime); break; case Accessibility_KEY_SYM: key_synth_code = keycode_for_keysym (keycode); - XTestFakeKeyEvent (GDK_DISPLAY (), (unsigned int) key_synth_code, True, CurrentTime); - XTestFakeKeyEvent (GDK_DISPLAY (), (unsigned int) key_synth_code, False, CurrentTime); + XTestFakeKeyEvent (spi_get_display (), (unsigned int) key_synth_code, True, CurrentTime); + XTestFakeKeyEvent (spi_get_display (), (unsigned int) key_synth_code, False, CurrentTime); break; case Accessibility_KEY_STRING: fprintf (stderr, "Not yet implemented\n"); @@ -934,6 +937,9 @@ spi_device_event_controller_forward_key_event (SpiDEController *controller, CORBA_exception_init (&ev); key_event = spi_keystroke_from_x_key_event ((XKeyEvent *) event); + + spi_controller_update_key_grabs (controller, &key_event); + /* relay to listeners, and decide whether to consume it or not */ is_consumed = spi_notify_keylisteners ( &controller->key_listeners, &key_event, CORBA_TRUE, &ev); @@ -942,14 +948,12 @@ spi_device_event_controller_forward_key_event (SpiDEController *controller, if (is_consumed) { - XAllowEvents (GDK_DISPLAY (), AsyncKeyboard, CurrentTime); + XAllowEvents (spi_get_display (), AsyncKeyboard, CurrentTime); } else { - XAllowEvents (GDK_DISPLAY (), ReplayKeyboard, CurrentTime); + XAllowEvents (spi_get_display (), ReplayKeyboard, CurrentTime); } - - spi_controller_update_key_grabs (controller, &key_event); } SpiDEController * diff --git a/test/test-simple.c b/test/test-simple.c index f2c86bb..3b33e60 100644 --- a/test/test-simple.c +++ b/test/test-simple.c @@ -651,7 +651,7 @@ key_listener_cb (const AccessibleKeystroke *stroke, *s = *stroke; - return FALSE; + return TRUE; } static void @@ -679,15 +679,19 @@ test_keylisteners (void) for (i = 0; i < 3; i++) { memset (&stroke, 0, sizeof (AccessibleKeystroke)); g_assert (SPI_generateKeyboardEvent ('=', NULL, SPI_KEY_SYM)); - while (stroke.type == 0) + while (!(stroke.type & SPI_KEY_PRESSED)) + g_main_iteration (TRUE); + fprintf (stderr, "p"); + while (!(stroke.type & SPI_KEY_RELEASED)) g_main_iteration (TRUE); + fprintf (stderr, "r "); } g_assert (SPI_deregisterAccessibleKeystrokeListener (key_listener, 0)); SPI_freeAccessibleKeySet (test_keyset); - /* FIXME: expand the validation here */ - g_assert (stroke.type == SPI_KEY_PRESSRELEASE); + g_assert (!strcmp (stroke.keystring, "=")); + fprintf (stderr, "\n"); AccessibleKeystrokeListener_unref (key_listener); } @@ -734,6 +738,11 @@ main (int argc, char **argv) test_window_destroy (win); + /* Wait for any pending events from the registry */ + g_usleep (500*1000); + for (i = 0; i < 100; i++) + linc_main_iteration (FALSE); + if ((leaked = SPI_exit ())) g_error ("Leaked %d SPI handles", leaked);