From 165eaa9c7436da733ac4de9c3b886b06a2d57498 Mon Sep 17 00:00:00 2001 From: Mike Gorse Date: Tue, 13 May 2008 16:36:37 -0400 Subject: [PATCH] First pass at an adaptation. This compiles and runs but is otherwise untested --- registryd/Makefile.am | 13 +- registryd/desktop.c | 145 +++--- registryd/desktop.h | 10 +- registryd/deviceeventcontroller.c | 895 ++++++++++++++++++++----------------- registryd/deviceeventcontroller.h | 10 +- registryd/registry-main.c | 36 +- registryd/registry.c | 910 ++++++-------------------------------- registryd/registry.h | 16 +- 8 files changed, 705 insertions(+), 1330 deletions(-) diff --git a/registryd/Makefile.am b/registryd/Makefile.am index 0495b5d..76a1555 100644 --- a/registryd/Makefile.am +++ b/registryd/Makefile.am @@ -1,7 +1,7 @@ -server_dot_in = Accessibility_Registry.server.in +#server_dot_in = Accessibility_Registry.server.in -$(server_dot_in): $(server_dot_in).in - sed -e "s|\@REGISTRYD_PATH\@|$(libexecdir)|" $< > $@ +#$(server_dot_in): $(server_dot_in).in +# sed -e "s|\@REGISTRYD_PATH\@|$(libexecdir)|" $< > $@ libexec_PROGRAMS = at-spi-registryd @@ -20,14 +20,15 @@ at_spi_registryd_SOURCES = \ registry-main.c \ registry.c \ registry.h \ + server-glue.h \ ucs2keysym.c LDADD = $(top_builddir)/libspi/libspi.la $(X_LIBS) $(XTST_LIBS) $(XEVIE_LIBS) $(REGISTRYD_LIBS) -serverinfodir = $(libdir)/bonobo/servers -serverinfo_DATA = Accessibility_Registry.server +#serverinfodir = $(libdir)/bonobo/servers +#serverinfo_DATA = Accessibility_Registry.server @INTLTOOL_SERVER_RULE@ EXTRA_DIST = Accessibility_Registry.server.in.in -CLEANFILES = $(serverinfo_DATA) $(server_dot_in) +#CLEANFILES = $(serverinfo_DATA) $(server_dot_in) diff --git a/registryd/desktop.c b/registryd/desktop.c index 59efaea..70138fb 100644 --- a/registryd/desktop.c +++ b/registryd/desktop.c @@ -25,12 +25,15 @@ #include #include -#include +#include #include "desktop.h" +#include "registry.h" #include #include #include +G_DEFINE_TYPE(SpiDesktop, spi_desktop, G_TYPE_OBJECT) + /* SpiDesktop signals */ enum { APPLICATION_ADDED, @@ -45,13 +48,13 @@ static guint spi_desktop_signals[LAST_SIGNAL]; typedef struct { SpiDesktop *desktop; - Accessibility_Application ref; + const char *path; } Application; static gboolean exiting = FALSE; /* A pointer to our parent object class */ -static SpiAccessibleClass *parent_class; +static GObjectClass *parent_class; #define SPI_TYPE_ATK_DESKTOP (spi_atk_desktop_get_type ()) #define SPI_ATK_DESKTOP(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_TYPE_ATK_DESKTOP, SpiAtkDesktop)) @@ -150,7 +153,6 @@ static void spi_desktop_init (SpiDesktop *desktop) { desktop->applications = NULL; - bonobo_object_set_immortal (BONOBO_OBJECT (desktop), TRUE); } static void @@ -161,54 +163,54 @@ spi_desktop_dispose (GObject *object) while (desktop->applications) { Application *app = desktop->applications->data; - g_assert (app->ref != CORBA_OBJECT_NIL); - spi_desktop_remove_application (desktop, app->ref); + g_assert (app != NULL); + spi_desktop_remove_application (desktop, app->path); } G_OBJECT_CLASS (parent_class)->dispose (object); } -static CORBA_long -impl_desktop_get_child_count (PortableServer_Servant servant, - CORBA_Environment *ev) +static dbus_bool_t +impl_desktop_get_child_count (const char *path, DBusMessageIter * iter, + void *user_data) { - SpiDesktop *desktop = SPI_DESKTOP (bonobo_object_from_servant (servant)); + SpiDesktop *desktop = SPI_REGISTRY(user_data)->desktop; if (desktop->applications) { - return g_list_length (desktop->applications); + return droute_return_v_int32(iter, g_list_length (desktop->applications)); } else { - return 0; + return droute_return_v_int32(iter, 0); } } -static Accessibility_Accessible -impl_desktop_get_child_at_index (PortableServer_Servant servant, - const CORBA_long index, - CORBA_Environment *ev) +static DBusMessage * +impl_desktop_get_child_at_index (DBusConnection *bus, DBusMessage *message, void *user_data) { - SpiDesktop *desktop = SPI_DESKTOP (bonobo_object_from_servant (servant)); - CORBA_Object retval; + SpiDesktop *desktop = SPI_REGISTRY(user_data)->desktop; + DBusError error; + dbus_int32_t index; Application *app; - + const char *path; + DBusMessage *reply; + + dbus_error_init (&error); + if (!dbus_message_get_args (message, &error, DBUS_TYPE_INT32, &index, DBUS_TYPE_INVALID)) + { + return spi_dbus_general_error (message); + } app = g_list_nth_data (desktop->applications, index); + path = (app? app->path: SPI_DBUS_PATH_NULL); - if (app) - { - retval = bonobo_object_dup_ref (app->ref, ev); - if (BONOBO_EX (ev)) - { - retval = CORBA_OBJECT_NIL; - } - } - else + reply = dbus_message_new_method_return (message); + if (reply) { - retval = CORBA_OBJECT_NIL; + dbus_message_append_args (reply, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID); } - return (Accessibility_Accessible) retval; + return reply; } static void @@ -221,12 +223,10 @@ static void spi_desktop_class_init (SpiDesktopClass *klass) { GObjectClass * object_class = (GObjectClass *) klass; - SpiAccessibleClass * spi_accessible_class = (SpiAccessibleClass *) klass; - POA_Accessibility_Accessible__epv *epv = &spi_accessible_class->epv; object_class->dispose = spi_desktop_dispose; - parent_class = g_type_class_ref (SPI_ACCESSIBLE_TYPE); + parent_class = g_type_class_ref (G_TYPE_OBJECT); spi_desktop_signals[APPLICATION_ADDED] = g_signal_new ("application_added", @@ -246,27 +246,13 @@ spi_desktop_class_init (SpiDesktopClass *klass) g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); - epv->_get_childCount = impl_desktop_get_child_count; - epv->getChildAtIndex = impl_desktop_get_child_at_index; g_atexit (spi_desktop_exiting); } -BONOBO_TYPE_FUNC_FULL (SpiDesktop, - Accessibility_Desktop, - PARENT_TYPE, - spi_desktop) - SpiDesktop * spi_desktop_new (void) { - SpiDesktop *desktop; - SpiAccessible *accessible; - - accessible = spi_accessible_construct (SPI_DESKTOP_TYPE, g_object_new (SPI_TYPE_ATK_DESKTOP, NULL)); - g_assert (SPI_IS_DESKTOP (accessible)); - desktop = SPI_DESKTOP (accessible); - - return desktop; + return g_object_new (SPI_DESKTOP_TYPE, NULL); } static void @@ -275,81 +261,82 @@ abnormal_application_termination (gpointer object, Application *app) g_return_if_fail (SPI_IS_DESKTOP (app->desktop)); if (!exiting) - spi_desktop_remove_application (app->desktop, app->ref); + spi_desktop_remove_application (app->desktop, app->path); } void spi_desktop_add_application (SpiDesktop *desktop, - const Accessibility_Application application) + const char *application) { - CORBA_Environment ev; Application *app; - Accessibility_Application ref; g_return_if_fail (SPI_IS_DESKTOP (desktop)); spi_desktop_remove_application (desktop, application); - CORBA_exception_init (&ev); - - ref = bonobo_object_dup_ref (application, &ev); - - if (!BONOBO_EX (&ev)) - { - app = g_new (Application, 1); - app->desktop = desktop; - app->ref = ref; + app = g_new (Application, 1); + app->desktop = desktop; + app->path = application; desktop->applications = g_list_append (desktop->applications, app); - ORBit_small_listen_for_broken ( - app->ref, G_CALLBACK (abnormal_application_termination), app); + // TODO: Listen for termination, and call abnormal_application_termination - g_signal_emit (G_OBJECT (desktop), - spi_desktop_signals[APPLICATION_ADDED], 0, - g_list_index (desktop->applications, app)); - } - - CORBA_exception_free (&ev); + g_signal_emit (G_OBJECT (desktop), + spi_desktop_signals[APPLICATION_ADDED], 0, + g_list_index (desktop->applications, app)); } void spi_desktop_remove_application (SpiDesktop *desktop, - const Accessibility_Application app_ref) + const char *path) { guint idx; GList *l; - CORBA_Environment ev; - g_return_if_fail (app_ref != CORBA_OBJECT_NIL); + g_return_if_fail (path != NULL); g_return_if_fail (SPI_IS_DESKTOP (desktop)); - CORBA_exception_init (&ev); - idx = 0; for (l = desktop->applications; l; l = l->next) { Application *app = (Application *) l->data; - if (CORBA_Object_is_equivalent (app->ref, app_ref, &ev)) + if (!strcmp(app->path, path)) { break; } idx++; } - CORBA_exception_free (&ev); - if (l) { Application *app = (Application *) l->data; desktop->applications = g_list_delete_link (desktop->applications, l); - ORBit_small_unlisten_for_broken (app->ref, G_CALLBACK (abnormal_application_termination)); - bonobo_object_release_unref (app->ref, NULL); + // TODO: unlisten for broken app, if appropriate g_free (app); g_signal_emit (G_OBJECT (desktop), spi_desktop_signals[APPLICATION_REMOVED], 0, idx); } } + +static DRouteMethod methods[] = +{ + { impl_desktop_get_child_at_index, "getChildAtIndex" }, + { NULL, NULL } +}; + +static DRouteProperty properties[] = +{ + { impl_desktop_get_child_count, NULL, "getChildCount" }, + { NULL, NULL, NULL } +}; + +void +spi_registry_initialize_desktop_interface (DRouteData * data) +{ + droute_add_interface (data, "org.freedesktop.atspi.Desktop", methods, + properties, NULL, NULL); +}; diff --git a/registryd/desktop.h b/registryd/desktop.h index 158dcbf..9c7df8d 100644 --- a/registryd/desktop.h +++ b/registryd/desktop.h @@ -35,14 +35,12 @@ G_BEGIN_DECLS #define SPI_IS_DESKTOP_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_DESKTOP_TYPE)) typedef struct { - SpiAccessible parent; + GObject parent; GList *applications; } SpiDesktop; typedef struct { - SpiAccessibleClass parent_class; - POA_Accessibility_Desktop__epv epv; - + GObjectClass parent_class; /*Signals */ void (*application_added) (SpiDesktop *desktop, guint index); @@ -53,9 +51,9 @@ typedef struct { GType spi_desktop_get_type (void); SpiDesktop *spi_desktop_new (void); void spi_desktop_add_application (SpiDesktop *desktop, - const Accessibility_Application application); + const char *app_path); void spi_desktop_remove_application (SpiDesktop *desktop, - const Accessibility_Application application); + const char *app_path); G_END_DECLS diff --git a/registryd/deviceeventcontroller.c b/registryd/deviceeventcontroller.c index ee43061..5e04c84 100644 --- a/registryd/deviceeventcontroller.c +++ b/registryd/deviceeventcontroller.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include @@ -55,6 +54,7 @@ #include "../libspi/spi-private.h" #include "deviceeventcontroller.h" +#include "libspi/keymasks.h" KeySym ucs2keysym (long ucs); long keysym2ucs(KeySym keysym); @@ -67,10 +67,9 @@ static SpiDEController *saved_controller; static void wait_for_release_event (XEvent *event, SpiDEController *controller); /* Our parent Gtk object type */ -#define PARENT_TYPE BONOBO_TYPE_OBJECT +#define PARENT_TYPE G_TYPE_OBJECT /* A pointer to our parent object class */ -static GObjectClass *spi_device_event_controller_parent_class; static int spi_error_code = 0; static GdkPoint last_mouse_pos_static = {0, 0}; static GdkPoint *last_mouse_pos = &last_mouse_pos_static; @@ -98,19 +97,20 @@ typedef struct { guint pending_remove : 1; Accessibility_ControllerEventMask mod_mask; - CORBA_unsigned_long key_val; /* KeyCode */ + dbus_uint32_t key_val; /* KeyCode */ } DEControllerGrabMask; typedef struct { - CORBA_Object object; + char *app_path; + char *path; SpiDeviceTypeCategory type; - Accessibility_EventTypeSeq *typeseq; + gulong types; } DEControllerListener; typedef struct { DEControllerListener listener; - Accessibility_KeySet *keys; + GSList *keys; Accessibility_ControllerEventMask mask; Accessibility_EventListenerMode *mode; } DEControllerKeyListener; @@ -136,21 +136,17 @@ static void spi_controller_register_with_devices (SpiDEController static gboolean spi_controller_update_key_grabs (SpiDEController *controller, Accessibility_DeviceEvent *recv); static gboolean spi_controller_register_device_listener (SpiDEController *controller, - DEControllerListener *l, - CORBA_Environment *ev); + DEControllerListener *l); static gboolean spi_device_event_controller_forward_key_event (SpiDEController *controller, const XEvent *event); -static void spi_deregister_controller_device_listener (SpiDEController *controller, - DEControllerListener *listener, - CORBA_Environment *ev); +static void spi_controller_deregister_device_listener (SpiDEController *controller, + DEControllerListener *listener); static void spi_deregister_controller_key_listener (SpiDEController *controller, - DEControllerKeyListener *key_listener, - CORBA_Environment *ev); + DEControllerKeyListener *key_listener); static gboolean spi_controller_notify_mouselisteners (SpiDEController *controller, - const Accessibility_DeviceEvent *event, - CORBA_Environment *ev); + const Accessibility_DeviceEvent *event); -static gboolean spi_eventtype_seq_contains_event (Accessibility_EventTypeSeq *type_seq, +static gboolean spi_eventtype_seq_contains_event (dbus_uint32_t types, const Accessibility_DeviceEvent *event); static gboolean spi_clear_error_state (void); static gboolean spi_dec_poll_mouse_moved (gpointer data); @@ -159,6 +155,8 @@ static gboolean spi_dec_poll_mouse_idle (gpointer data); #define spi_get_display() GDK_DISPLAY() +G_DEFINE_TYPE(SpiDEController, spi_device_event_controller, G_TYPE_OBJECT) + /* Private methods */ static unsigned int @@ -338,12 +336,19 @@ spi_dec_clear_unlatch_pending (SpiDEController *controller) priv->xkb_latch_mask = 0; } +static void emit(SpiDEController *controller, const char *name, int first_type, ...) +{ + va_list arg; + + va_start(arg, first_type); + spi_dbus_emit_valist(controller->registry->droute.bus, SPI_DBUS_PATH_DEC, SPI_DBUS_INTERFACE_DEC, name, first_type, arg); + va_end(arg); +} + static gboolean spi_dec_button_update_and_emit (SpiDEController *controller, guint mask_return) { - CORBA_Environment ev; - Accessibility_Event e; Accessibility_DeviceEvent mouse_e; gchar event_name[24]; gboolean is_consumed = FALSE; @@ -434,33 +439,20 @@ spi_dec_button_update_and_emit (SpiDEController *controller, Accessibility_BUTTON_RELEASED_EVENT; mouse_e.id = button_number; mouse_e.hw_code = button_number; - mouse_e.modifiers = (CORBA_unsigned_short) mouse_mask_state; + mouse_e.modifiers = (dbus_uint16_t) mouse_mask_state; mouse_e.timestamp = 0; mouse_e.event_string = ""; - mouse_e.is_text = CORBA_FALSE; + mouse_e.is_text = FALSE; is_consumed = spi_controller_notify_mouselisteners (controller, - &mouse_e, - &ev); - e.type = event_name; - e.source = BONOBO_OBJREF (controller->registry->desktop); - e.detail1 = last_mouse_pos->x; - e.detail2 = last_mouse_pos->y; - spi_init_any_nil (&e.any_data, - spi_accessible_new_return (atk_get_root (), FALSE, NULL), - Accessibility_ROLE_UNKNOWN, - ""); - CORBA_exception_init (&ev); + &mouse_e); if (!is_consumed) { - Accessibility_Registry_notifyEvent (BONOBO_OBJREF (controller->registry), - &e, - &ev); + dbus_uint32_t x = last_mouse_pos->x, y = last_mouse_pos->y; + emit(controller, event_name, DBUS_TYPE_UINT32, &x, DBUS_TYPE_UINT32, &y, DBUS_TYPE_INVALID); } else spi_dec_set_unlatch_pending (controller, mask_return); - - CORBA_free (e.any_data._value); } return TRUE; } @@ -475,9 +467,6 @@ static guint spi_dec_mouse_check (SpiDEController *controller, int *x, int *y, gboolean *moved) { - Accessibility_Event e; - Accessibility_EventDetails *details; - CORBA_Environment ev; int win_x_return,win_y_return; unsigned int mask_return; Window root_return, child_return; @@ -502,36 +491,14 @@ spi_dec_mouse_check (SpiDEController *controller, if (*x != last_mouse_pos->x || *y != last_mouse_pos->y) { - e.type = "mouse:abs"; - e.source = BONOBO_OBJREF (controller->registry->desktop); - e.detail1 = *x; - e.detail2 = *y; - spi_init_any_nil (&e.any_data, - spi_accessible_new_return (atk_get_root (), FALSE, NULL), - Accessibility_ROLE_UNKNOWN, - ""); - CORBA_exception_init (&ev); - Accessibility_Registry_notifyEvent (BONOBO_OBJREF (controller->registry), - &e, - &ev); - details = e.any_data._value; - CORBA_free (details); - e.type = "mouse:rel"; - e.source = BONOBO_OBJREF (controller->registry->desktop); - e.detail1 = *x - last_mouse_pos->x; - e.detail2 = *y - last_mouse_pos->y; - spi_init_any_nil (&e.any_data, - spi_accessible_new_return (atk_get_root (), FALSE, NULL), - Accessibility_ROLE_UNKNOWN, - ""); - CORBA_exception_init (&ev); + // TODO: combine these two signals? + dbus_uint32_t ix = *x, iy = *y; + emit(controller, "mouse_abs", DBUS_TYPE_UINT32, &ix, DBUS_TYPE_UINT32, &iy, DBUS_TYPE_INVALID); + ix -= last_mouse_pos->x; + iy -= last_mouse_pos->y; + emit(controller, "mouse_rel", DBUS_TYPE_UINT32, &ix, DBUS_TYPE_UINT32, &iy, DBUS_TYPE_INVALID); last_mouse_pos->x = *x; last_mouse_pos->y = *y; - Accessibility_Registry_notifyEvent (BONOBO_OBJREF (controller->registry), - &e, - &ev); - details = e.any_data._value; - CORBA_free (details); *moved = True; } else @@ -546,8 +513,7 @@ static void spi_dec_emit_modifier_event (SpiDEController *controller, guint prev_mask, guint current_mask) { - Accessibility_Event e; - CORBA_Environment ev; + dbus_uint32_t d1, d2; #ifdef SPI_XKB_DEBUG fprintf (stderr, "MODIFIER CHANGE EVENT! %x to %x\n", @@ -560,19 +526,9 @@ spi_dec_emit_modifier_event (SpiDEController *controller, guint prev_mask, if (current_mask & _numlock_physical_mask) current_mask |= SPI_KEYMASK_NUMLOCK; - e.type = "keyboard:modifiers"; - e.source = BONOBO_OBJREF (controller->registry->desktop); - e.detail1 = prev_mask & key_modifier_mask; - e.detail2 = current_mask & key_modifier_mask; - spi_init_any_nil (&e.any_data, - spi_accessible_new_return (atk_get_root (), FALSE, NULL), - Accessibility_ROLE_UNKNOWN, - ""); - CORBA_exception_init (&ev); - Accessibility_Registry_notifyEvent (BONOBO_OBJREF (controller->registry), - &e, - &ev); - CORBA_free (e.any_data._value); + d1 = prev_mask & key_modifier_mask; + d2 = current_mask & key_modifier_mask; + emit(controller, "keyboard_modifiers", DBUS_TYPE_UINT32, &d1, DBUS_TYPE_UINT32, &d2, DBUS_TYPE_INVALID); } static gboolean @@ -687,21 +643,25 @@ spi_dec_translate_mask (Accessibility_ControllerEventMask mask) } static DEControllerKeyListener * -spi_dec_key_listener_new (CORBA_Object l, - const Accessibility_KeySet *keys, +spi_dec_key_listener_new (const char *app_path, + const char *path, + GSList *keys, const Accessibility_ControllerEventMask mask, - const Accessibility_EventTypeSeq *typeseq, - const Accessibility_EventListenerMode *mode, - CORBA_Environment *ev) + const dbus_uint32_t types, + const Accessibility_EventListenerMode *mode) { DEControllerKeyListener *key_listener = g_new0 (DEControllerKeyListener, 1); - key_listener->listener.object = bonobo_object_dup_ref (l, ev); + key_listener->listener.app_path = g_strdup(app_path); + key_listener->listener.path = g_strdup(path); key_listener->listener.type = SPI_DEVICE_TYPE_KBD; - key_listener->keys = ORBit_copy_value (keys, TC_Accessibility_KeySet); + key_listener->keys = keys; key_listener->mask = spi_dec_translate_mask (mask); - key_listener->listener.typeseq = ORBit_copy_value (typeseq, TC_Accessibility_EventTypeSeq); + key_listener->listener.types = types; if (mode) - key_listener->mode = ORBit_copy_value (mode, TC_Accessibility_EventListenerMode); + { + key_listener->mode = (Accessibility_EventListenerMode *) g_malloc(sizeof(Accessibility_EventListenerMode)); + memcpy(key_listener->mode, mode, sizeof(*mode)); + } else key_listener->mode = NULL; @@ -710,82 +670,118 @@ spi_dec_key_listener_new (CORBA_Object l, (unsigned int) key_listener->mask, (int) (mode ? mode->global : 0), (void *) key_listener->keys, - (int) (key_listener->keys ? key_listener->keys->_length : 0)); + (int) (key_listener->keys ? g_slist_length(key_listener->keys) : 0)); #endif return key_listener; } static DEControllerListener * -spi_dec_listener_new (CORBA_Object l, - const Accessibility_EventTypeSeq *typeseq, - CORBA_Environment *ev) +spi_dec_listener_new (const char *app_path, + const char *path, + dbus_uint32_t types) { DEControllerListener *listener = g_new0 (DEControllerListener, 1); - listener->object = bonobo_object_dup_ref (l, ev); + listener->app_path = g_strdup(app_path); + listener->path = g_strdup(path); listener->type = SPI_DEVICE_TYPE_MOUSE; - listener->typeseq = ORBit_copy_value (typeseq, TC_Accessibility_EventTypeSeq); + listener->types = types; return listener; } static DEControllerListener * -spi_listener_clone (DEControllerListener *listener, CORBA_Environment *ev) +spi_listener_clone (DEControllerListener *listener) { DEControllerListener *clone = g_new0 (DEControllerListener, 1); - clone->object = - CORBA_Object_duplicate (listener->object, ev); + clone->app_path = g_strdup (listener->app_path); + clone->path = g_strdup (listener->path); clone->type = listener->type; - clone->typeseq = ORBit_copy_value (listener->typeseq, TC_Accessibility_EventTypeSeq); + clone->types = listener->types; return clone; } +static GSList *keylist_clone (GSList *s) +{ + GSList *d = NULL; + GSList *l; + + for (l = s; l; l = g_slist_next(l)) + { + Accessibility_KeyDefinition *kd = (Accessibility_KeyDefinition *)g_malloc(sizeof(Accessibility_KeyDefinition)); + if (kd) + { + Accessibility_KeyDefinition *kds = (Accessibility_KeyDefinition *)l->data; + kd->keycode = kds->keycode; + kd->keysym = kds->keysym; + kd->keystring = g_strdup(kds->keystring); + d = g_slist_append(d, kd); + } + } + return d; +} + static DEControllerKeyListener * -spi_key_listener_clone (DEControllerKeyListener *key_listener, CORBA_Environment *ev) +spi_key_listener_clone (DEControllerKeyListener *key_listener) { DEControllerKeyListener *clone = g_new0 (DEControllerKeyListener, 1); - clone->listener.object = - CORBA_Object_duplicate (key_listener->listener.object, ev); + clone->listener.app_path = g_strdup (key_listener->listener.app_path); + clone->listener.path = g_strdup (key_listener->listener.path); clone->listener.type = SPI_DEVICE_TYPE_KBD; - clone->keys = ORBit_copy_value (key_listener->keys, TC_Accessibility_KeySet); + clone->keys = keylist_clone (key_listener->keys); clone->mask = key_listener->mask; - clone->listener.typeseq = ORBit_copy_value (key_listener->listener.typeseq, TC_Accessibility_EventTypeSeq); + clone->listener.types = key_listener->listener.types; if (key_listener->mode) - clone->mode = ORBit_copy_value (key_listener->mode, TC_Accessibility_EventListenerMode); + { + clone->mode = (Accessibility_EventListenerMode *)g_malloc(sizeof(Accessibility_EventListenerMode)); + if (clone->mode) memcpy(clone->mode, key_listener->mode, sizeof(Accessibility_EventListenerMode)); + } else clone->mode = NULL; return clone; } +static void keylist_free(GSList *keys) +{ + GSList *l; + + for (l = keys; l; l = g_slist_next(l)) + { + Accessibility_KeyDefinition *kd = (Accessibility_KeyDefinition *)l->data; + g_free(kd->keystring); + g_free(kd); + } + g_slist_free (keys); +} + static void -spi_key_listener_data_free (DEControllerKeyListener *key_listener, CORBA_Environment *ev) +spi_key_listener_data_free (DEControllerKeyListener *key_listener) { - CORBA_free (key_listener->listener.typeseq); - CORBA_free (key_listener->keys); + keylist_free(key_listener->keys); + if (key_listener->mode) g_free(key_listener->mode); g_free (key_listener); } static void -spi_key_listener_clone_free (DEControllerKeyListener *clone, CORBA_Environment *ev) +spi_key_listener_clone_free (DEControllerKeyListener *clone) { - CORBA_Object_release (clone->listener.object, ev); - spi_key_listener_data_free (clone, ev); + spi_key_listener_data_free (clone); } static void -spi_listener_clone_free (DEControllerListener *clone, CORBA_Environment *ev) +spi_listener_clone_free (DEControllerListener *clone) { - CORBA_Object_release (clone->object, ev); - CORBA_free (clone->typeseq); + g_free (clone->path); + g_free (clone->app_path); g_free (clone); } static void -spi_dec_listener_free (DEControllerListener *listener, - CORBA_Environment *ev) +spi_dec_listener_free (DEControllerListener *listener) { - bonobo_object_release_unref (listener->object, ev); + g_free (listener->app_path); + g_free (listener->path); if (listener->type == SPI_DEVICE_TYPE_KBD) - spi_key_listener_data_free ((DEControllerKeyListener *) listener, ev); + spi_key_listener_data_free ((DEControllerKeyListener *) listener); } static void @@ -848,7 +844,7 @@ handle_keygrab (SpiDEController *controller, DEControllerGrabMask grab_mask = { 0 }; grab_mask.mod_mask = key_listener->mask; - if (key_listener->keys->_length == 0) /* special case means AnyKey/AllKeys */ + if (g_slist_length (key_listener->keys) == 0) /* special case means AnyKey/AllKeys */ { grab_mask.key_val = AnyKey; #ifdef SPI_DEBUG @@ -858,16 +854,16 @@ handle_keygrab (SpiDEController *controller, } else { - int i; + GSList *l; - for (i = 0; i < key_listener->keys->_length; ++i) + for (l = key_listener->keys; l; l = g_slist_next(l)) { - Accessibility_KeyDefinition keydef = key_listener->keys->_buffer[i]; - long int key_val = keydef.keysym; + Accessibility_KeyDefinition *keydef = l->data; + long int key_val = keydef->keysym; /* X Grabs require keycodes, not keysyms */ - if (keydef.keystring && keydef.keystring[0]) + if (keydef->keystring && keydef->keystring[0]) { - key_val = XStringToKeysym(keydef.keystring); + key_val = XStringToKeysym(keydef->keystring); } if (key_val > 0) { @@ -875,7 +871,7 @@ handle_keygrab (SpiDEController *controller, } else { - key_val = keydef.keycode; + key_val = keydef->keycode; } grab_mask.key_val = key_val; process_cb (controller, &grab_mask); @@ -905,8 +901,7 @@ spi_controller_deregister_global_keygrabs (SpiDEController *controller, static gboolean spi_controller_register_device_listener (SpiDEController *controller, - DEControllerListener *listener, - CORBA_Environment *ev) + DEControllerListener *listener) { DEControllerKeyListener *key_listener; @@ -933,10 +928,33 @@ spi_controller_register_device_listener (SpiDEController *controller, return FALSE; } +static gboolean Accessibility_DeviceEventListener_notifyEvent(SpiRegistry *registry, DEControllerListener *listener, const Accessibility_DeviceEvent *key_event) +{ + DBusMessage *message = dbus_message_new_method_call(listener->app_path, listener->path, "org.freedesktop.atspi.Registry", "notifyEvent"); + DBusError error; + dbus_bool_t consumed = FALSE; + + dbus_error_init(&error); + if (spi_dbus_marshall_deviceEvent(message, key_event)) + { + // TODO: Evaluate performance: perhaps rework this whole architecture + // to avoid blocking calls + DBusMessage *reply = dbus_connection_send_with_reply_and_block(registry->droute.bus, message, 1000, &error); + if (reply) + { + DBusError error; + dbus_error_init(&error); + dbus_message_get_args(reply, &error, DBUS_TYPE_BOOLEAN, &consumed, DBUS_TYPE_INVALID); + dbus_message_unref(reply); + } + } + dbus_message_unref(message); + return consumed; +} + static gboolean spi_controller_notify_mouselisteners (SpiDEController *controller, - const Accessibility_DeviceEvent *event, - CORBA_Environment *ev) + const Accessibility_DeviceEvent *event) { GList *l; GSList *notify = NULL, *l2; @@ -954,19 +972,14 @@ spi_controller_notify_mouselisteners (SpiDEController *controlle { DEControllerListener *listener = l->data; - if (spi_eventtype_seq_contains_event (listener->typeseq, event)) + if (spi_eventtype_seq_contains_event (listener->types, event)) { - Accessibility_DeviceEventListener ls = listener->object; - - if (ls != CORBA_OBJECT_NIL) - { - /* we clone (don't dup) the listener, to avoid refcount inc. */ - notify = g_slist_prepend (notify, - spi_listener_clone (listener, ev)); + /* we clone (don't dup) the listener, to avoid refcount inc. */ + notify = g_slist_prepend (notify, + spi_listener_clone (listener)); #ifdef SPI_KEYEVENT_DEBUG - found = TRUE; + found = TRUE; #endif - } } } @@ -981,26 +994,16 @@ spi_controller_notify_mouselisteners (SpiDEController *controlle for (l2 = notify; l2 && !is_consumed; l2 = l2->next) { DEControllerListener *listener = l2->data; - Accessibility_DeviceEventListener ls = listener->object; - CORBA_exception_init (ev); - is_consumed = Accessibility_DeviceEventListener_notifyEvent (ls, event, ev); - if (BONOBO_EX (ev)) - { - is_consumed = FALSE; - DBG (2, g_warning ("error notifying listener, removing it\n")); - spi_deregister_controller_device_listener (controller, listener, - ev); - CORBA_exception_free (ev); - } + is_consumed = Accessibility_DeviceEventListener_notifyEvent (controller->registry, listener, event); - spi_listener_clone_free ((DEControllerListener *) l2->data, ev); + spi_listener_clone_free ((DEControllerListener *) l2->data); } for (; l2; l2 = l2->next) { DEControllerListener *listener = l2->data; - spi_listener_clone_free (listener, ev); + spi_listener_clone_free (listener); /* clone doesn't have its own ref, so don't use spi_device_listener_free */ } @@ -1016,13 +1019,12 @@ static void spi_device_event_controller_forward_mouse_event (SpiDEController *controller, XEvent *xevent) { - Accessibility_Event e; Accessibility_DeviceEvent mouse_e; - CORBA_Environment ev; gchar event_name[24]; gboolean is_consumed = FALSE; gboolean xkb_mod_unlatch_occurred; XButtonEvent *xbutton_event = (XButtonEvent *) xevent; + dbus_uint32_t ix, iy; int button = xbutton_event->button; @@ -1056,7 +1058,7 @@ spi_device_event_controller_forward_mouse_event (SpiDEController *controller, (xevent->type == ButtonPress) ? "Press" : "Release", mouse_button_state); #endif - snprintf (event_name, 22, "mouse:button:%d%c", button, + snprintf (event_name, 22, "mouse:button_%d%c", button, (xevent->type == ButtonPress) ? 'p' : 'r'); /* TODO: FIXME distinguish between physical and logical buttons */ @@ -1065,10 +1067,10 @@ spi_device_event_controller_forward_mouse_event (SpiDEController *controller, Accessibility_BUTTON_RELEASED_EVENT; mouse_e.id = button; mouse_e.hw_code = button; - mouse_e.modifiers = (CORBA_unsigned_short) xbutton_event->state; - mouse_e.timestamp = (CORBA_unsigned_long) xbutton_event->time; + mouse_e.modifiers = (dbus_uint16_t) xbutton_event->state; + mouse_e.timestamp = (dbus_uint32_t) xbutton_event->time; mouse_e.event_string = ""; - mouse_e.is_text = CORBA_FALSE; + mouse_e.is_text = FALSE; if ((mouse_button_state & mouse_button_mask) != (mouse_mask_state & mouse_button_mask)) { @@ -1078,21 +1080,10 @@ spi_device_event_controller_forward_mouse_event (SpiDEController *controller, mouse_mask_state, mouse_button_state); mouse_mask_state = mouse_button_state; is_consumed = - spi_controller_notify_mouselisteners (controller, &mouse_e, &ev); - e.type = CORBA_string_dup (event_name); - e.source = BONOBO_OBJREF (controller->registry->desktop); - e.detail1 = last_mouse_pos->x; - e.detail2 = last_mouse_pos->y; - spi_init_any_nil (&e.any_data, - spi_accessible_new_return (atk_get_root (), FALSE, NULL), - Accessibility_ROLE_UNKNOWN, - ""); - CORBA_exception_init (&ev); - - Accessibility_Registry_notifyEvent (BONOBO_OBJREF (controller->registry), - &e, - &ev); - CORBA_free (e.any_data._value); + spi_controller_notify_mouselisteners (controller, &mouse_e); + ix = last_mouse_pos->x; + iy = last_mouse_pos->y; + emit(controller, event_name, DBUS_TYPE_UINT32, &ix, DBUS_TYPE_UINT32, &iy, DBUS_TYPE_INVALID); } xkb_mod_unlatch_occurred = (xevent->type == ButtonPress || @@ -1334,11 +1325,12 @@ spi_controller_register_with_devices (SpiDEController *controller) } static gboolean -spi_key_set_contains_key (Accessibility_KeySet *key_set, +spi_key_set_contains_key (GSList *key_set, const Accessibility_DeviceEvent *key_event) { gint i; gint len; + GSList *l; if (!key_set) { @@ -1346,35 +1338,38 @@ spi_key_set_contains_key (Accessibility_KeySet *key_set, return TRUE; } - len = key_set->_length; + len = g_slist_length (key_set); if (len == 0) /* special case, means "all keys/any key" */ { +#ifdef SPI_DEBUG g_print ("anykey\n"); +#endif return TRUE; } - for (i = 0; i < len; ++i) + for (l = key_set,i = 0; l; l = g_slist_next(l),i++) { + Accessibility_KeyDefinition *kd = l->data; #ifdef SPI_KEYEVENT_DEBUG g_print ("key_set[%d] event = %d, code = %d; key_event %d, code %d, string %s\n", i, - (int)key_set->_buffer[i].keysym, - (int) key_set->_buffer[i].keycode, + (int) kd->keysym, + (int) kd->keycode, (int) key_event->id, (int) key_event->hw_code, key_event->event_string); #endif - if (key_set->_buffer[i].keysym == (CORBA_long) key_event->id) + if (kd->keysym == (dbus_uint32_t) key_event->id) { return TRUE; } - if (key_set->_buffer[i].keycode == (CORBA_long) key_event->hw_code) + if (kd->keycode == (dbus_uint32_t) key_event->hw_code) { return TRUE; } if (key_event->event_string && key_event->event_string[0] && - !strcmp (key_set->_buffer[i].keystring, key_event->event_string)) + !strcmp (kd->keystring, key_event->event_string)) { return TRUE; } @@ -1384,49 +1379,25 @@ spi_key_set_contains_key (Accessibility_KeySet *key_set, } static gboolean -spi_eventtype_seq_contains_event (Accessibility_EventTypeSeq *type_seq, +spi_eventtype_seq_contains_event (dbus_uint32_t types, const Accessibility_DeviceEvent *event) { - gint i; - gint len; - - - if (!type_seq) + if (types == 0) /* special case, means "all events/any event" */ { - g_print ("null type seq!"); return TRUE; } - len = type_seq->_length; - - if (len == 0) /* special case, means "all events/any event" */ - { - return TRUE; - } - - for (i = 0; i < len; ++i) - { -#ifdef SPI_DEBUG - g_print ("type_seq[%d] = %d; event type = %d\n", i, - (int) type_seq->_buffer[i], (int) event->type); -#endif - if (type_seq->_buffer[i] == (CORBA_long) event->type) - { - return TRUE; - } - } - - return FALSE; + return (types & (1 << event->type)); } static gboolean spi_key_event_matches_listener (const Accessibility_DeviceEvent *key_event, DEControllerKeyListener *listener, - CORBA_boolean is_system_global) + dbus_bool_t is_system_global) { - if (((key_event->modifiers & 0xFF) == (CORBA_unsigned_short) (listener->mask & 0xFF)) && + if (((key_event->modifiers & 0xFF) == (dbus_uint16_t) (listener->mask & 0xFF)) && spi_key_set_contains_key (listener->keys, key_event) && - spi_eventtype_seq_contains_event (listener->listener.typeseq, key_event) && + spi_eventtype_seq_contains_event (listener->listener.types, key_event) && (is_system_global == listener->mode->global)) { return TRUE; @@ -1440,8 +1411,7 @@ spi_key_event_matches_listener (const Accessibility_DeviceEvent *key_event, static gboolean spi_controller_notify_keylisteners (SpiDEController *controller, Accessibility_DeviceEvent *key_event, - CORBA_boolean is_system_global, - CORBA_Environment *ev) + dbus_bool_t is_system_global) { GList *l; GSList *notify = NULL, *l2; @@ -1463,14 +1433,9 @@ spi_controller_notify_keylisteners (SpiDEController *controller, if (spi_key_event_matches_listener (key_event, key_listener, is_system_global)) { - Accessibility_DeviceEventListener ls = key_listener->listener.object; - - if (ls != CORBA_OBJECT_NIL) - { - /* we clone (don't dup) the listener, to avoid refcount inc. */ - notify = g_slist_prepend (notify, - spi_key_listener_clone (key_listener, ev)); - } + /* we clone (don't dup) the listener, to avoid refcount inc. */ + notify = g_slist_prepend (notify, + spi_key_listener_clone (key_listener)); } } @@ -1485,26 +1450,17 @@ spi_controller_notify_keylisteners (SpiDEController *controller, for (l2 = notify; l2 && !is_consumed; l2 = l2->next) { DEControllerKeyListener *key_listener = l2->data; - Accessibility_DeviceEventListener ls = key_listener->listener.object; - is_consumed = Accessibility_DeviceEventListener_notifyEvent (ls, key_event, ev) && + is_consumed = Accessibility_DeviceEventListener_notifyEvent (controller->registry, &key_listener->listener, key_event) && key_listener->mode->preemptive; - if (BONOBO_EX (ev)) - { - is_consumed = FALSE; - spi_deregister_controller_key_listener (controller, key_listener, - ev); - CORBA_exception_free (ev); - } - - spi_key_listener_clone_free (key_listener, ev); + spi_key_listener_clone_free (key_listener); } for (; l2; l2 = l2->next) { DEControllerKeyListener *key_listener = l2->data; - spi_key_listener_clone_free (key_listener, ev); + spi_key_listener_clone_free (key_listener); /* clone doesn't have its own ref, so don't use spi_dec_listener_free */ } @@ -1534,8 +1490,8 @@ spi_keystroke_from_x_key_event (XKeyEvent *x_key_event) int nbytes; nbytes = XLookupString (x_key_event, cbuf, cbuf_bytes, &keysym, NULL); - key_event.id = (CORBA_long)(keysym); - key_event.hw_code = (CORBA_short) x_key_event->keycode; + key_event.id = (dbus_int32_t)(keysym); + key_event.hw_code = (dbus_int16_t) x_key_event->keycode; if (((XEvent *) x_key_event)->type == KeyPress) { key_event.type = Accessibility_KEY_PRESSED_EVENT; @@ -1544,105 +1500,105 @@ spi_keystroke_from_x_key_event (XKeyEvent *x_key_event) { key_event.type = Accessibility_KEY_RELEASED_EVENT; } - key_event.modifiers = (CORBA_unsigned_short)(x_key_event->state); - key_event.is_text = CORBA_FALSE; + key_event.modifiers = (dbus_uint16_t)(x_key_event->state); + key_event.is_text = FALSE; switch (keysym) { case ' ': - key_event.event_string = CORBA_string_dup ("space"); + key_event.event_string = g_strdup ("space"); break; case XK_Tab: - key_event.event_string = CORBA_string_dup ("Tab"); + key_event.event_string = g_strdup ("Tab"); break; case XK_BackSpace: - key_event.event_string = CORBA_string_dup ("Backspace"); + key_event.event_string = g_strdup ("Backspace"); break; case XK_Return: - key_event.event_string = CORBA_string_dup ("Return"); + key_event.event_string = g_strdup ("Return"); break; case XK_Home: - key_event.event_string = CORBA_string_dup ("Home"); + key_event.event_string = g_strdup ("Home"); break; case XK_Page_Down: - key_event.event_string = CORBA_string_dup ("Page_Down"); + key_event.event_string = g_strdup ("Page_Down"); break; case XK_Page_Up: - key_event.event_string = CORBA_string_dup ("Page_Up"); + key_event.event_string = g_strdup ("Page_Up"); break; case XK_F1: - key_event.event_string = CORBA_string_dup ("F1"); + key_event.event_string = g_strdup ("F1"); break; case XK_F2: - key_event.event_string = CORBA_string_dup ("F2"); + key_event.event_string = g_strdup ("F2"); break; case XK_F3: - key_event.event_string = CORBA_string_dup ("F3"); + key_event.event_string = g_strdup ("F3"); break; case XK_F4: - key_event.event_string = CORBA_string_dup ("F4"); + key_event.event_string = g_strdup ("F4"); break; case XK_F5: - key_event.event_string = CORBA_string_dup ("F5"); + key_event.event_string = g_strdup ("F5"); break; case XK_F6: - key_event.event_string = CORBA_string_dup ("F6"); + key_event.event_string = g_strdup ("F6"); break; case XK_F7: - key_event.event_string = CORBA_string_dup ("F7"); + key_event.event_string = g_strdup ("F7"); break; case XK_F8: - key_event.event_string = CORBA_string_dup ("F8"); + key_event.event_string = g_strdup ("F8"); break; case XK_F9: - key_event.event_string = CORBA_string_dup ("F9"); + key_event.event_string = g_strdup ("F9"); break; case XK_F10: - key_event.event_string = CORBA_string_dup ("F10"); + key_event.event_string = g_strdup ("F10"); break; case XK_F11: - key_event.event_string = CORBA_string_dup ("F11"); + key_event.event_string = g_strdup ("F11"); break; case XK_F12: - key_event.event_string = CORBA_string_dup ("F12"); + key_event.event_string = g_strdup ("F12"); break; case XK_End: - key_event.event_string = CORBA_string_dup ("End"); + key_event.event_string = g_strdup ("End"); break; case XK_Escape: - key_event.event_string = CORBA_string_dup ("Escape"); + key_event.event_string = g_strdup ("Escape"); break; case XK_Up: - key_event.event_string = CORBA_string_dup ("Up"); + key_event.event_string = g_strdup ("Up"); break; case XK_Down: - key_event.event_string = CORBA_string_dup ("Down"); + key_event.event_string = g_strdup ("Down"); break; case XK_Left: - key_event.event_string = CORBA_string_dup ("Left"); + key_event.event_string = g_strdup ("Left"); break; case XK_Right: - key_event.event_string = CORBA_string_dup ("Right"); + key_event.event_string = g_strdup ("Right"); break; default: if (nbytes > 0) { gunichar c; cbuf[nbytes] = '\0'; /* OK since length is cbuf_bytes+1 */ - key_event.event_string = CORBA_string_dup (cbuf); + key_event.event_string = g_strdup (cbuf); c = keysym2ucs (keysym); if (c > 0 && !g_unichar_iscntrl (c)) { - key_event.is_text = CORBA_TRUE; + key_event.is_text = TRUE; /* incorrect for some composed chars? */ } } else { - key_event.event_string = CORBA_string_dup (""); + key_event.event_string = g_strdup (""); } } - key_event.timestamp = (CORBA_unsigned_long) x_key_event->time; + key_event.timestamp = (dbus_uint32_t) x_key_event->time; #ifdef SPI_KEYEVENT_DEBUG { char *pressed_str = "pressed"; @@ -1662,7 +1618,7 @@ spi_keystroke_from_x_key_event (XKeyEvent *x_key_event) (int) x_key_event->state, key_event.event_string, key_event.event_string[0], - (key_event.is_text == CORBA_TRUE) ? "(text)" : "(not text)"); + (key_event.is_text == TRUE) ? "(text)" : "(not text)"); } #endif #ifdef SPI_DEBUG @@ -1783,7 +1739,7 @@ spi_device_event_controller_object_finalize (GObject *object) SpiDEController *controller; DEControllerPrivateData *private; controller = SPI_DEVICE_EVENT_CONTROLLER (object); - + GObjectClass *parent_class = G_OBJECT_CLASS(spi_device_event_controller_parent_class); #ifdef SPI_DEBUG fprintf(stderr, "spi_device_event_controller_object_finalize called\n"); #endif @@ -1804,56 +1760,104 @@ spi_device_event_controller_object_finalize (GObject *object) if (private->xkb_desc) XkbFreeKeyboard (private->xkb_desc, 0, True); g_free (private); - spi_device_event_controller_parent_class->finalize (object); + parent_class->finalize (object); } /* - * CORBA Accessibility::DEController::registerKeystrokeListener + * DBus Accessibility::DEController::registerKeystrokeListener * method implementation */ -static CORBA_boolean -impl_register_keystroke_listener (PortableServer_Servant servant, - const Accessibility_DeviceEventListener l, - const Accessibility_KeySet *keys, - const Accessibility_ControllerEventMask mask, - const Accessibility_EventTypeSeq *type, - const Accessibility_EventListenerMode *mode, - CORBA_Environment *ev) -{ - SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER ( - bonobo_object_from_servant (servant)); +static DBusMessage * +impl_register_keystroke_listener (DBusConnection *bus, + DBusMessage *message, + void *user_data) +{ + SpiDEController *controller = SPI_REGISTRY(user_data)->de_controller; DEControllerKeyListener *dec_listener; + DBusMessageIter iter, iter_array; + const char *path; + GSList *keys = NULL; + dbus_int32_t mask, type; + Accessibility_EventListenerMode *mode; + dbus_bool_t ret; + DBusMessage *reply; + char *keystring; + + dbus_message_iter_init(message, &iter); + // TODO: verify type signature + dbus_message_iter_get_basic(&iter, &path); + dbus_message_iter_next(&iter); + dbus_message_iter_recurse(&iter, &iter_array); + while (dbus_message_iter_get_arg_type(&iter_array) != DBUS_TYPE_INVALID) + { + Accessibility_KeyDefinition *kd = (Accessibility_KeyDefinition *)g_malloc(sizeof(Accessibility_KeyDefinition)); + if (!spi_dbus_message_iter_get_struct(&iter_array, DBUS_TYPE_INT32, &kd->keycode, DBUS_TYPE_INT32, &kd->keysym, DBUS_TYPE_STRING, &keystring, DBUS_TYPE_INVALID)) + { + break; + } + kd->keystring = g_strdup (keystring); + keys = g_slist_append(keys, kd); + } + dbus_message_iter_next(&iter); + dbus_message_iter_get_basic(&iter, &mask); + dbus_message_iter_next(&iter); + dbus_message_iter_get_basic(&iter, &type); + dbus_message_iter_next(&iter); + mode = (Accessibility_EventListenerMode *)g_malloc(sizeof(Accessibility_EventListenerMode)); + if (mode) + { + spi_dbus_message_iter_get_struct(&iter, DBUS_TYPE_BOOLEAN, &mode->synchronous, DBUS_TYPE_BOOLEAN, &mode->preemptive, DBUS_TYPE_BOOLEAN, &mode->global, DBUS_TYPE_INVALID); + } #ifdef SPI_DEBUG - fprintf (stderr, "registering keystroke listener %p with maskVal %lu\n", - (void *) l, (unsigned long) mask); + fprintf (stderr, "registering keystroke listener %s:%s with maskVal %lu\n", + dbus_message_get_sender(message), path, (unsigned long) mask); #endif - dec_listener = spi_dec_key_listener_new (l, keys, mask, type, mode, ev); - return spi_controller_register_device_listener ( - controller, (DEControllerListener *) dec_listener, ev); + dec_listener = spi_dec_key_listener_new (dbus_message_get_sender(message), path, keys, mask, type, mode); + ret = spi_controller_register_device_listener ( + controller, (DEControllerListener *) dec_listener); + reply = dbus_message_new_method_return (message); + if (reply) + { + dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret, DBUS_TYPE_INVALID); + } + return reply; } - /* - * CORBA Accessibility::DEController::registerDeviceEventListener + * DBus Accessibility::DEController::registerDeviceEventListener * method implementation */ -static CORBA_boolean -impl_register_device_listener (PortableServer_Servant servant, - const Accessibility_DeviceEventListener l, - const Accessibility_EventTypeSeq *event_types, - CORBA_Environment *ev) -{ - SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER ( - bonobo_object_from_servant (servant)); +static DBusMessage * +impl_register_device_listener (DBusConnection *bus, + DBusMessage *message, + void *user_data) +{ + SpiDEController *controller = SPI_REGISTRY(user_data)->de_controller; DEControllerListener *dec_listener; - - dec_listener = spi_dec_listener_new (l, event_types, ev); - return spi_controller_register_device_listener ( - controller, (DEControllerListener *) dec_listener, ev); + DBusError error; + const char *path; + dbus_int32_t event_types; + dbus_bool_t ret; + DBusMessage *reply; + + dbus_error_init(&error); + if (!dbus_message_get_args(message, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_UINT32, &event_types, DBUS_TYPE_INVALID)) + { + return spi_dbus_general_error (message); + } + dec_listener = spi_dec_listener_new (dbus_message_get_sender(message), path, event_types); + ret = spi_controller_register_device_listener ( + controller, (DEControllerListener *) dec_listener); + reply = dbus_message_new_method_return (message); + if (reply) + { + dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret, DBUS_TYPE_INVALID); + } + return reply; } typedef struct { - CORBA_Environment *ev; + DBusConnection *bus; DEControllerListener *listener; } RemoveListenerClosure; @@ -1864,11 +1868,11 @@ remove_listener_cb (GList * const *list, DEControllerListener *listener = (*list)->data; RemoveListenerClosure *ctx = user_data; - if (CORBA_Object_is_equivalent (ctx->listener->object, - listener->object, ctx->ev)) + if (!strcmp(ctx->listener->app_path, listener->app_path) && + !strcmp(ctx->listener->path, listener->path)) { spi_re_entrant_list_delete_link (list); - spi_dec_listener_free (listener, ctx->ev); + spi_dec_listener_free (listener); } return SPI_RE_ENTRANT_CONTINUE; @@ -1881,27 +1885,26 @@ copy_key_listener_cb (GList * const *list, DEControllerKeyListener *key_listener = (*list)->data; RemoveListenerClosure *ctx = user_data; - if (CORBA_Object_is_equivalent (ctx->listener->object, - key_listener->listener.object, ctx->ev)) + if (!strcmp(ctx->listener->app_path, key_listener->listener.app_path) && + !strcmp(ctx->listener->path, key_listener->listener.path)) { /* TODO: FIXME aggregate keys in case the listener is registered twice */ DEControllerKeyListener *ctx_key_listener = (DEControllerKeyListener *) ctx->listener; - CORBA_free (ctx_key_listener->keys); - ctx_key_listener->keys = ORBit_copy_value (key_listener->keys, TC_Accessibility_KeySet); + keylist_free (ctx_key_listener->keys); + ctx_key_listener->keys = keylist_clone(key_listener->keys); } return SPI_RE_ENTRANT_CONTINUE; } static void -spi_deregister_controller_device_listener (SpiDEController *controller, - DEControllerListener *listener, - CORBA_Environment *ev) +spi_controller_deregister_device_listener (SpiDEController *controller, + DEControllerListener *listener) { RemoveListenerClosure ctx; - ctx.ev = ev; + ctx.bus = controller->registry->droute.bus; ctx.listener = listener; spi_re_entrant_list_foreach (&controller->mouse_listeners, @@ -1910,16 +1913,15 @@ spi_deregister_controller_device_listener (SpiDEController *controlle static void spi_deregister_controller_key_listener (SpiDEController *controller, - DEControllerKeyListener *key_listener, - CORBA_Environment *ev) + DEControllerKeyListener *key_listener) { RemoveListenerClosure ctx; - ctx.ev = ev; + ctx.bus = controller->registry->droute.bus; ctx.listener = (DEControllerListener *) key_listener; /* special case, copy keyset from existing controller list entry */ - if (key_listener->keys->_length == 0) + if (g_slist_length(key_listener->keys) == 0) { spi_re_entrant_list_foreach (&controller->key_listeners, copy_key_listener_cb, &ctx); @@ -1933,53 +1935,83 @@ spi_deregister_controller_key_listener (SpiDEController *controller, } /* - * CORBA Accessibility::DEController::deregisterKeystrokeListener + * DBus Accessibility::DEController::deregisterKeystrokeListener * method implementation */ -static void -impl_deregister_keystroke_listener (PortableServer_Servant servant, - const Accessibility_DeviceEventListener l, - const Accessibility_KeySet *keys, - const Accessibility_ControllerEventMask mask, - const Accessibility_EventTypeSeq *type, - CORBA_Environment *ev) -{ - DEControllerKeyListener *key_listener; - SpiDEController *controller; - - controller = SPI_DEVICE_EVENT_CONTROLLER (bonobo_object (servant)); - - key_listener = spi_dec_key_listener_new (l, keys, mask, type, NULL, ev); +static DBusMessage * +impl_deregister_keystroke_listener (DBusConnection *bus, + DBusMessage *message, + void *user_data) +{ + SpiDEController *controller = SPI_REGISTRY(user_data)->de_controller; + DEControllerKeyListener *key_listener; + DBusMessageIter iter, iter_array; + const char *path; + GSList *keys = NULL; + dbus_int32_t mask, type; + DBusMessage *reply; + + dbus_message_iter_init(message, &iter); + // TODO: verify type signature + dbus_message_iter_get_basic(&iter, &path); + dbus_message_iter_next(&iter); + dbus_message_iter_recurse(&iter, &iter_array); + while (dbus_message_iter_get_arg_type(&iter_array) != DBUS_TYPE_INVALID) + { + Accessibility_KeyDefinition *kd = (Accessibility_KeyDefinition *)g_malloc(sizeof(Accessibility_KeyDefinition)); + char *keystring; + if (!spi_dbus_message_iter_get_struct(&iter_array, DBUS_TYPE_INT32, &kd->keycode, DBUS_TYPE_INT32, &kd->keysym, DBUS_TYPE_STRING, &keystring, DBUS_TYPE_INVALID)) + { + break; + } + kd->keystring = g_strdup (keystring); + keys = g_slist_append(keys, kd); + } + dbus_message_iter_next(&iter); + dbus_message_iter_get_basic(&iter, &mask); + dbus_message_iter_next(&iter); + dbus_message_iter_get_basic(&iter, &type); + dbus_message_iter_next(&iter); + key_listener = spi_dec_key_listener_new (dbus_message_get_sender(message), path, keys, mask, type, NULL); #ifdef SPI_DEREGISTER_DEBUG fprintf (stderr, "deregistering keystroke listener %p with maskVal %lu\n", (void *) l, (unsigned long) mask->value); #endif - spi_deregister_controller_key_listener (controller, key_listener, ev); + spi_deregister_controller_key_listener (controller, key_listener); - spi_dec_listener_free ((DEControllerListener *) key_listener, ev); + spi_dec_listener_free ((DEControllerListener *) key_listener); + reply = dbus_message_new_method_return (message); + return reply; } /* - * CORBA Accessibility::DEController::deregisterDeviceEventListener + * DBus Accessibility::DEController::deregisterDeviceEventListener * method implementation */ -static void -impl_deregister_device_listener (PortableServer_Servant servant, - const Accessibility_DeviceEventListener l, - const Accessibility_EventTypeSeq *event_types, - CORBA_Environment *ev) -{ - SpiDEController *controller; - DEControllerListener *listener = - spi_dec_listener_new (l, event_types, ev); - - controller = SPI_DEVICE_EVENT_CONTROLLER (bonobo_object (servant)); - - spi_deregister_controller_device_listener (controller, listener, ev); - - spi_dec_listener_free (listener, ev); +static DBusMessage * +impl_deregister_device_listener (DBusConnection *bus, + DBusMessage *message, + void *user_data) +{ + SpiDEController *controller = SPI_REGISTRY(user_data)->de_controller; + DEControllerListener *listener; + DBusError error; + const char *path; + dbus_int32_t event_types; + DBusMessage *reply; + + dbus_error_init(&error); + if (!dbus_message_get_args(message, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_UINT32, &event_types, DBUS_TYPE_INVALID)) + { + return spi_dbus_general_error (message); + } + listener = spi_dec_listener_new (dbus_message_get_sender(message), path, event_types); + spi_controller_deregister_device_listener ( + controller, listener); + reply = dbus_message_new_method_return (message); + return reply; } static unsigned int dec_xkb_get_slowkeys_delay (SpiDEController *controller) @@ -2202,7 +2234,7 @@ dec_synth_keysym (SpiDEController *controller, KeySym keysym) static gboolean -dec_synth_keystring (SpiDEController *controller, const CORBA_char *keystring) +dec_synth_keystring (SpiDEController *controller, const char *keystring) { /* probably we need to create and inject an XIM handler eventually. */ /* for now, try to match the string to existing @@ -2266,21 +2298,26 @@ dec_synth_keystring (SpiDEController *controller, const CORBA_char *keystring) /* - * CORBA Accessibility::DEController::registerKeystrokeListener + * DBus Accessibility::DEController::registerKeystrokeListener * method implementation */ -static void -impl_generate_keyboard_event (PortableServer_Servant servant, - const CORBA_long keycode, - const CORBA_char *keystring, - const Accessibility_KeySynthType synth_type, - CORBA_Environment *ev) -{ - SpiDEController *controller = - SPI_DEVICE_EVENT_CONTROLLER (bonobo_object (servant)); +static DBusMessage * impl_generate_keyboard_event (DBusConnection *bus, DBusMessage *message, void *user_data) +{ + SpiDEController *controller = SPI_REGISTRY(user_data)->de_controller; + DBusError error; + dbus_int32_t keycode; + char *keystring; + dbus_uint32_t synth_type; gint err; KeySym keysym; DEControllerPrivateData *priv; + DBusMessage *reply; + + dbus_error_init(&error); + if (!dbus_message_get_args(message, &error, DBUS_TYPE_INT32, &keycode, DBUS_TYPE_STRING, &keystring, DBUS_TYPE_UINT32, &synth_type, DBUS_TYPE_INVALID)) + { + return spi_dbus_general_error (message); + } #ifdef SPI_DEBUG fprintf (stderr, "synthesizing keystroke %ld, type %d\n", @@ -2343,19 +2380,27 @@ impl_generate_keyboard_event (PortableServer_Servant servant, { spi_dec_clear_unlatch_pending (controller); } + reply = dbus_message_new_method_return (message); + return reply; } /* Accessibility::DEController::generateMouseEvent */ -static void -impl_generate_mouse_event (PortableServer_Servant servant, - const CORBA_long x, - const CORBA_long y, - const CORBA_char *eventName, - CORBA_Environment *ev) +static DBusMessage * impl_generate_mouse_event (DBusConnection *bus, DBusMessage *message, void *user_data) { + DBusError error; + dbus_int32_t x; + dbus_int32_t y; + char *eventName; + DBusMessage *reply; int button = 0; - gboolean error = FALSE; + gboolean err = FALSE; Display *display = spi_get_display (); + + if (!dbus_message_get_args(message, &error, DBUS_TYPE_INT32, &x, DBUS_TYPE_INT32, &y, DBUS_TYPE_STRING, &eventName, DBUS_TYPE_INVALID)) + { + return spi_dbus_general_error (message); + } + #ifdef SPI_DEBUG fprintf (stderr, "generating mouse %s event at %ld, %ld\n", eventName, (long int) x, (long int) y); @@ -2382,9 +2427,9 @@ impl_generate_mouse_event (PortableServer_Servant servant, button = 5; break; default: - error = TRUE; + err = TRUE; } - if (!error) + if (!err) { if (x != -1 && y != -1) { @@ -2410,59 +2455,68 @@ impl_generate_mouse_event (PortableServer_Servant servant, x, y, 0); break; } + reply = dbus_message_new_method_return (message); + return reply; } /* Accessibility::DEController::notifyListenersSync */ -static CORBA_boolean -impl_notify_listeners_sync (PortableServer_Servant servant, - const Accessibility_DeviceEvent *event, - CORBA_Environment *ev) +static DBusMessage * +impl_notify_listeners_sync (DBusConnection *bus, DBusMessage *message, void *user_data) { - SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER ( - bonobo_object_from_servant (servant)); + SpiDEController *controller = SPI_REGISTRY(user_data)->de_controller; + Accessibility_DeviceEvent event; + dbus_bool_t ret; + DBusMessage *reply; + + if (!spi_dbus_demarshall_deviceEvent(message, &event)) + { + return spi_dbus_general_error (message); + } #ifdef SPI_DEBUG g_print ("notifylistening listeners synchronously: controller %p, event id %d\n", - controller, (int) event->id); + controller, (int) event.id); #endif - return spi_controller_notify_keylisteners (controller, + ret = spi_controller_notify_keylisteners (controller, (Accessibility_DeviceEvent *) - event, CORBA_FALSE, ev) ? - CORBA_TRUE : CORBA_FALSE; + &event, FALSE) ? + TRUE : FALSE; + reply = dbus_message_new_method_return (message); + if (reply) + { + dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret, DBUS_TYPE_INVALID); + } + return reply; } -/* Accessibility::DEController::notifyListenersAsync */ -static void -impl_notify_listeners_async (PortableServer_Servant servant, - const Accessibility_DeviceEvent *event, - CORBA_Environment *ev) +static DBusMessage * +impl_notify_listeners_async (DBusConnection *bus, DBusMessage *message, void *user_data) { - SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER ( - bonobo_object_from_servant (servant)); + SpiDEController *controller = SPI_REGISTRY(user_data)->de_controller; + Accessibility_DeviceEvent event; + DBusMessage *reply; + + if (!spi_dbus_demarshall_deviceEvent(message, &event)) + { + return spi_dbus_general_error (message); + } #ifdef SPI_DEBUG - fprintf (stderr, "notifying listeners asynchronously\n"); + g_print ("notifylistening listeners asynchronously: controller %p, event id %d\n", + controller, (int) event.id); #endif spi_controller_notify_keylisteners (controller, (Accessibility_DeviceEvent *) - event, CORBA_FALSE, ev); + &event, FALSE); + reply = dbus_message_new_method_return (message); + return reply; } static void spi_device_event_controller_class_init (SpiDEControllerClass *klass) { GObjectClass * object_class = (GObjectClass *) klass; - POA_Accessibility_DeviceEventController__epv *epv = &klass->epv; spi_device_event_controller_parent_class = g_type_class_peek_parent (klass); object_class->finalize = spi_device_event_controller_object_finalize; - - epv->registerKeystrokeListener = impl_register_keystroke_listener; - epv->deregisterKeystrokeListener = impl_deregister_keystroke_listener; - epv->registerDeviceEventListener = impl_register_device_listener; - epv->deregisterDeviceEventListener = impl_deregister_device_listener; - epv->generateKeyboardEvent = impl_generate_keyboard_event; - epv->generateMouseEvent = impl_generate_mouse_event; - epv->notifyListenersSync = impl_notify_listeners_sync; - epv->notifyListenersAsync = impl_notify_listeners_async; if (!spi_dec_private_quark) spi_dec_private_quark = g_quark_from_static_string ("spi-dec-private"); @@ -2547,22 +2601,19 @@ static gboolean spi_device_event_controller_forward_key_event (SpiDEController *controller, const XEvent *event) { - CORBA_Environment ev; Accessibility_DeviceEvent key_event; gboolean ret; g_assert (event->type == KeyPress || event->type == KeyRelease); - CORBA_exception_init (&ev); - key_event = spi_keystroke_from_x_key_event ((XKeyEvent *) event); if (controller->xevie_display == NULL) spi_controller_update_key_grabs (controller, &key_event); /* relay to listeners, and decide whether to consume it or not */ - ret = spi_controller_notify_keylisteners (controller, &key_event, CORBA_TRUE, &ev); - CORBA_free(key_event.event_string); + ret = spi_controller_notify_keylisteners (controller, &key_event, TRUE); + g_free(key_event.event_string); return ret; } @@ -2572,8 +2623,7 @@ spi_device_event_controller_new (SpiRegistry *registry) SpiDEController *retval = g_object_new ( SPI_DEVICE_EVENT_CONTROLLER_TYPE, NULL); - retval->registry = SPI_REGISTRY (bonobo_object_ref ( - BONOBO_OBJECT (registry))); + retval->registry = g_object_ref (registry); spi_dec_init_mouse_listener (registry); /* TODO: kill mouse listener on finalize */ @@ -2597,7 +2647,6 @@ check_release (gpointer data) gboolean released; Accessibility_DeviceEvent *event = (Accessibility_DeviceEvent *)data; KeyCode code = event->hw_code; - CORBA_Environment ev; released = is_key_released (code); @@ -2605,8 +2654,7 @@ check_release (gpointer data) { check_release_handler = 0; event->type = Accessibility_KEY_RELEASED_EVENT; - ev._major = CORBA_NO_EXCEPTION; - spi_controller_notify_keylisteners (saved_controller, event, CORBA_TRUE, &ev); + spi_controller_notify_keylisteners (saved_controller, event, TRUE); } return (released == 0); } @@ -2619,7 +2667,22 @@ static void wait_for_release_event (XEvent *event, check_release_handler = g_timeout_add (CHECK_RELEASE_DELAY, check_release, &pressed_event); } -BONOBO_TYPE_FUNC_FULL (SpiDEController, - Accessibility_DeviceEventController, - PARENT_TYPE, - spi_device_event_controller) +static DRouteMethod methods[] = +{ + { impl_register_keystroke_listener, "registerKeystrokeListener" }, + { impl_register_device_listener, "registerDeviceListener" }, + { impl_deregister_keystroke_listener, "deregisterKeystrokeListener" }, + { impl_deregister_device_listener, "deregisterDeviceListener" }, + { impl_generate_keyboard_event, "generateKeyboardEvent" }, + { impl_generate_mouse_event, "generateMouseEvent" }, + { impl_notify_listeners_sync, "notifyListenersSync" }, + { impl_notify_listeners_async, "notifyListenersAsync" }, + { NULL, NULL } +}; + +void +spi_registry_initialize_dec_interface (DRouteData * data) +{ + droute_add_interface (data, "org.freedesktop.atspi.DeviceEventController", methods, + NULL, NULL, NULL); +}; diff --git a/registryd/deviceeventcontroller.h b/registryd/deviceeventcontroller.h index bb04352..1fd81dd 100644 --- a/registryd/deviceeventcontroller.h +++ b/registryd/deviceeventcontroller.h @@ -24,9 +24,9 @@ #ifndef SPI_DEVICE_EVENT_CONTROLLER_H_ #define SPI_DEVICE_EVENT_CONTROLLER_H_ -#include +#include +#include #include -#include typedef struct _SpiDEController SpiDEController; @@ -42,7 +42,7 @@ G_BEGIN_DECLS #define SPI_DEVICE_EVENT_CONTROLLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPI_DEVICE_EVENT_CONTROLLER_TYPE, SpiDEControllerClass)) struct _SpiDEController { - BonoboObject parent; + GObject parent; SpiRegistry *registry; GList *key_listeners; @@ -52,9 +52,7 @@ struct _SpiDEController { }; typedef struct { - BonoboObjectClass parent_class; - - POA_Accessibility_DeviceEventController__epv epv; + GObjectClass parent_class; } SpiDEControllerClass; GType spi_device_event_controller_get_type (void); diff --git a/registryd/registry-main.c b/registryd/registry-main.c index 08a2db3..246270c 100644 --- a/registryd/registry-main.c +++ b/registryd/registry-main.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include "registry.h" @@ -44,11 +43,10 @@ main (int argc, char **argv) const char *display_name; char *cp, *dp; SpiRegistry *registry; + DBusError error; + GMainLoop *mainloop; - if (!bonobo_init (&argc, argv)) - { - g_error ("Could not initialize oaf / Bonobo"); - } + g_type_init(); obj_id = "OAFIID:Accessibility_Registry:1.0"; @@ -63,12 +61,11 @@ main (int argc, char **argv) if (cp && dp && (cp > dp)) *cp = '\0'; } - ret = bonobo_activation_register_active_server ( - obj_id, - bonobo_object_corba_objref (bonobo_object (registry)), - NULL); + dbus_error_init (&error); + mainloop = g_main_loop_new (NULL, FALSE); + ret= dbus_bus_request_name(registry->droute.bus, SPI_DBUS_NAME_REGISTRY, 0, &error); - if (ret != Bonobo_ACTIVATION_REG_SUCCESS) + if (!ret) { #ifdef AT_SPI_DEBUG fprintf (stderr, "SpiRegistry Message: SpiRegistry daemon was already running.\n"); @@ -80,7 +77,7 @@ main (int argc, char **argv) fprintf (stderr, "SpiRegistry Message: SpiRegistry daemon is running.\n"); #endif registry_set_ior (registry); - bonobo_main (); + g_main_loop_run (mainloop); } return 0; @@ -88,15 +85,10 @@ main (int argc, char **argv) static void registry_set_ior (SpiRegistry *registry){ - CORBA_Environment ev; Atom AT_SPI_IOR = XInternAtom (spi_get_display (), "AT_SPI_IOR", FALSE); char *iorstring = NULL; - CORBA_exception_init (&ev); - - iorstring = CORBA_ORB_object_to_string (bonobo_activation_orb_get (), - bonobo_object_corba_objref (bonobo_object (registry)), - &ev); + iorstring = SPI_DBUS_NAME_REGISTRY; XChangeProperty (spi_get_display(), XDefaultRootWindow (spi_get_display ()), @@ -104,14 +96,4 @@ registry_set_ior (SpiRegistry *registry){ PropModeReplace, (unsigned char *) iorstring, iorstring ? strlen (iorstring) : 0); - - if (ev._major != CORBA_NO_EXCEPTION) - { - g_error ("Error setting IOR %s", - CORBA_exception_id (&ev)); - CORBA_exception_free (&ev); - } - - CORBA_exception_free (&ev); - } diff --git a/registryd/registry.c b/registryd/registry.c index 6119cdf..9455e1f 100644 --- a/registryd/registry.c +++ b/registryd/registry.c @@ -32,20 +32,13 @@ # include #endif -#include #include "../libspi/spi-private.h" #include "registry.h" +#include "dbus/dbus-glib-lowlevel.h" /* Our parent GObject type */ -#define PARENT_TYPE SPI_LISTENER_TYPE +#define PARENT_TYPE G_OBJECT_TYPE -/* A pointer to our parent object class */ -static SpiListenerClass *spi_registry_parent_class; - -static GQuark _deactivate_quark = 0; -static GQuark _activate_quark = 0; -static GQuark _state_quark = 0; -static GQuark _state_changed_focused_quark = 0; int _dbg = 0; @@ -68,11 +61,7 @@ typedef struct { GQuark detail; /* from string segment[3] (not concatenated) */ } EventTypeStruct; -typedef struct { - Accessibility_EventListener listener; - GQuark event_type_quark; - EventTypeCategory event_type_cat; -} SpiListenerStruct; +G_DEFINE_TYPE(SpiRegistry, spi_registry, G_TYPE_OBJECT) static void spi_registry_set_debug (const char *debug_flag_string) @@ -81,50 +70,23 @@ spi_registry_set_debug (const char *debug_flag_string) _dbg = (int) g_ascii_strtod (debug_flag_string, NULL); } -static SpiListenerStruct * -spi_listener_struct_new (Accessibility_EventListener listener, CORBA_Environment *ev) +static void emit(SpiRegistry *registry, const char *name, int first_type, ...) { - SpiListenerStruct *retval = g_malloc (sizeof (SpiListenerStruct)); - retval->listener = bonobo_object_dup_ref (listener, ev); - return retval; -} - + va_list arg; -static void -spi_listener_struct_free (SpiListenerStruct *ls, CORBA_Environment *ev) -{ - bonobo_object_release_unref (ls->listener, ev); - g_free (ls); + va_start(arg, first_type); + spi_dbus_emit_valist(registry->droute.bus, SPI_DBUS_PATH_REGISTRY, SPI_DBUS_INTERFACE_REGISTRY, name, first_type, arg); + va_end(arg); } static void desktop_add_application (SpiDesktop *desktop, guint index, gpointer data) { - BonoboObject *registry = BONOBO_OBJECT (data); - Accessibility_Event e; - CORBA_Environment ev; - Accessibility_Accessible a; + SpiRegistry *registry = SPI_REGISTRY (data); + const char *name = g_list_nth_data(desktop->applications, index); - CORBA_exception_init (&ev); - e.type = "object:children-changed:add"; - e.source = BONOBO_OBJREF (desktop); - e.detail1 = index; - e.detail2 = 0; - a = Accessibility_Accessible_getChildAtIndex (BONOBO_OBJREF (desktop), - index, &ev); - /* FIXME - spi_init_any_object (&e.any_data, a); - */ - spi_init_any_nil (&e.any_data, - e.source, - Accessibility_ROLE_DESKTOP_FRAME, - ""); - - Accessibility_Registry_notifyEvent (BONOBO_OBJREF (registry), - &e, &ev); - bonobo_object_release_unref (a, &ev); - CORBA_exception_free (&ev); + emit(registry, "ApplicationAdd", DBUS_TYPE_UINT32, &index, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID); } @@ -133,31 +95,10 @@ static void desktop_remove_application (SpiDesktop *desktop, guint index, gpointer data) { - BonoboObject *registry = BONOBO_OBJECT (data); - Accessibility_Event e; - /* Accessibility_Accessible a; FIXME */ - CORBA_Environment ev; + SpiRegistry *registry = SPI_REGISTRY (data); + const char *name = g_list_nth_data(desktop->applications, index); - CORBA_exception_init (&ev); - - e.type = "object:children-changed:remove"; - e.source = BONOBO_OBJREF (desktop); - e.detail1 = index; - e.detail2 = 0; - /* FIXME - a = Accessibility_Accessible_getChildAtIndex (BONOBO_OBJREF (desktop), - index, &ev); - spi_init_any_object (&e.any_data, a); - */ - spi_init_any_nil (&e.any_data, - e.source, - Accessibility_ROLE_DESKTOP_FRAME, - ""); - /* Accessibility_Accessible_unref (a, &ev); */ - Accessibility_Registry_notifyEvent (BONOBO_OBJREF (registry), - &e, &ev); - Accessibility_Desktop_unref (e.source, &ev); - CORBA_exception_free (&ev); + emit(registry, "ApplicationRemove", DBUS_TYPE_UINT32, &index, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID); } @@ -170,14 +111,6 @@ spi_registry_object_finalize (GObject *object) G_OBJECT_CLASS (spi_registry_parent_class)->finalize (object); } -static long -_get_unique_id (void) -{ - static long id = 0; - - return ++id; -} - /** * registerApplication: * @application: a reference to the requesting @Application @@ -186,160 +119,22 @@ _get_unique_id (void) * Register a new application with the accessibility broker. * **/ -static void -impl_accessibility_registry_register_application (PortableServer_Servant servant, - const Accessibility_Application application, - CORBA_Environment * ev) +static DBusMessage * +impl_accessibility_registry_register_application (DBusConnection *bus, DBusMessage *message, void *user_data) { - SpiRegistry *registry = SPI_REGISTRY (bonobo_object_from_servant (servant)); + SpiRegistry *registry = SPI_REGISTRY (user_data); + const char *application = dbus_message_get_sender (message); #ifdef SPI_DEBUG - fprintf (stderr, "registering app %p\n", application); + fprintf (stderr, "registering app %s\n", application); #endif spi_desktop_add_application (registry->desktop, application); - Accessibility_Application__set_id (application, _get_unique_id (), ev); - /* * TODO: change the implementation below to a WM-aware one; * e.g. don't add all apps to the SpiDesktop */ -} - -#ifdef USE_A_HASH_IN_FUTURE -static gint -compare_corba_objects (gconstpointer p1, gconstpointer p2) -{ - CORBA_Environment ev; - gint retval; - -#ifdef SPI_DEBUG - fprintf (stderr, "comparing %p to %p\n", - p1, p2); -#endif - - retval = !CORBA_Object_is_equivalent ((CORBA_Object) p1, (CORBA_Object) p2, &ev); - return retval; -} -#endif - -static void -register_with_toolkits (SpiRegistry *spi_registry_bonobo_object, EventTypeStruct *etype, CORBA_Environment *ev) -{ - gint n_desktops; - gint n_apps; - gint i, j; - Accessibility_Desktop desktop; - Accessibility_Application app; - Accessibility_Registry registry; - registry = BONOBO_OBJREF (spi_registry_bonobo_object); - - /* for each app in each desktop, call ...Application_registerToolkitEventListener */ - - n_desktops = Accessibility_Registry_getDesktopCount (registry, ev); - - for (i=0; ievent_name), - ev); - } - } -} - -#ifdef USE_A_HASH_IN_FUTURE - -static gint -compare_listener_quarks (gconstpointer p1, gconstpointer p2) -{ - return (((SpiListenerStruct *)p2)->event_type_quark != - ((SpiListenerStruct *)p1)->event_type_quark); -} - -static gint -compare_listener_corbaref (gconstpointer p1, gconstpointer p2) -{ - return compare_corba_objects (((SpiListenerStruct *)p2)->listener, - ((SpiListenerStruct *)p1)->listener); -} -#endif - -static void -parse_event_type (EventTypeStruct *etype, const char *event_name) -{ - gchar **split_string; - gchar *s; - - split_string = g_strsplit (event_name, ":", 4); - etype->event_name = event_name; - - if (!g_ascii_strncasecmp (event_name, "focus:", 6)) - { - etype->type_cat = ETYPE_FOCUS; - } - else if (!g_ascii_strncasecmp (event_name, "mouse:", 6)) - { - etype->type_cat = ETYPE_MOUSE; - } - else if (!g_ascii_strncasecmp (event_name, "object:", 7)) - { - etype->type_cat = ETYPE_OBJECT; - } - else if (!g_ascii_strncasecmp (event_name, "document:", 9)) - { - etype->type_cat = ETYPE_OBJECT; - } - else if (!g_ascii_strncasecmp (event_name, "window:", 7)) - { - etype->type_cat = ETYPE_WINDOW; - } - else if (!g_ascii_strncasecmp (event_name, "keyboard:", 9)) - { - etype->type_cat = ETYPE_KEYBOARD; - } - else - { - etype->type_cat = ETYPE_TOOLKIT; - } - - if (split_string[1]) - { - etype->major = g_quark_from_string (split_string[1]); - if (split_string[2]) - { - etype->minor = g_quark_from_string (s = g_strconcat (split_string[1], split_string[2], NULL)); - g_free (s); - if (split_string[3]) - { - etype->detail = g_quark_from_string (split_string[3]); - } - else - { - etype->detail = g_quark_from_static_string (""); - } - } - else - { - etype->minor = etype->major; - etype->detail = g_quark_from_static_string (""); /*etype->major;*/ - } - } - else - { - etype->major = g_quark_from_static_string (""); - etype->minor = etype->major; - etype->detail = etype->major; - } - - g_strfreev (split_string); + return dbus_message_new_method_return (message); } /** @@ -351,172 +146,20 @@ parse_event_type (EventTypeStruct *etype, const char *event_name) * De-register an application previously registered with the broker. * **/ -static void -impl_accessibility_registry_deregister_application (PortableServer_Servant servant, - const Accessibility_Application application, - CORBA_Environment * ev) +static DBusMessage * +impl_accessibility_registry_deregister_application (DBusConnection *bus, DBusMessage *message, void *user_data) { - SpiRegistry *registry = SPI_REGISTRY (bonobo_object_from_servant (servant)); + SpiRegistry *registry = SPI_REGISTRY (user_data); + const char *application = dbus_message_get_sender (message); spi_desktop_remove_application (registry->desktop, application); #ifdef SPI_DEBUG - fprintf (stderr, "de-registered app %p\n", application); + fprintf (stderr, "de-registered app %s\n", application); #endif + return dbus_message_new_method_return (message); } -static GList ** -get_listener_list (SpiRegistry *registry, - EventTypeCategory cat) -{ - GList **ret; - - switch (cat) - { - case ETYPE_OBJECT: - case ETYPE_PROPERTY: - case ETYPE_FOCUS: - case ETYPE_KEYBOARD: - ret = ®istry->object_listeners; - break; - case ETYPE_WINDOW: - ret = ®istry->window_listeners; - break; - case ETYPE_MOUSE: - case ETYPE_TOOLKIT: - ret = ®istry->toolkit_listeners; - break; - default: - ret = NULL; - break; - } - return ret; -} - -/* - * CORBA Accessibility::Registry::registerGlobalEventListener method implementation - */ -static void -impl_accessibility_registry_register_global_event_listener ( - PortableServer_Servant servant, - Accessibility_EventListener listener, - const CORBA_char *event_name, - CORBA_Environment *ev) -{ - SpiRegistry *registry = SPI_REGISTRY (bonobo_object_from_servant (servant)); - SpiListenerStruct *ls = spi_listener_struct_new (listener, ev); - EventTypeStruct etype; - GList **list; - -#ifdef SPI_LISTENER_DEBUG - fprintf (stderr, "registering for events of type %s\n", event_name); -#endif - - /* parse, check major event type and add listener accordingly */ - parse_event_type (&etype, event_name); - ls->event_type_quark = etype.minor; - ls->event_type_cat = etype.type_cat; - - list = get_listener_list (registry, etype.type_cat); - - if (list) - { - *list = g_list_prepend (*list, ls); - - if (etype.type_cat == ETYPE_TOOLKIT) - { - register_with_toolkits (registry, &etype, ev); - } - } - else - { - spi_listener_struct_free (ls, ev); - } -} - -typedef struct { - gboolean remove_all; - Accessibility_EventListener listener; - EventTypeStruct etype; -} RemoveListenerClosure; - -static SpiReEntrantContinue -remove_listener_cb (GList * const *list, gpointer user_data) -{ - SpiListenerStruct *ls = (SpiListenerStruct *) (*list)->data; - CORBA_Environment ev; - RemoveListenerClosure *cl = user_data; - - CORBA_exception_init (&ev); - - if (cl->remove_all || (((cl->etype.minor == ls->event_type_quark) || - (cl->etype.major == ls->event_type_quark)) && - cl->etype.type_cat == ls->event_type_cat ) ) - { - if (CORBA_Object_is_equivalent (ls->listener, cl->listener, &ev)) - { - spi_re_entrant_list_delete_link (list); - spi_listener_struct_free (ls, &ev); - } - } - - CORBA_exception_free (&ev); - - return SPI_RE_ENTRANT_CONTINUE; -} - -/* - * CORBA Accessibility::Registry::deregisterGlobalEventListenerAll method implementation - */ -static void -impl_accessibility_registry_deregister_global_event_listener_all ( - PortableServer_Servant servant, - Accessibility_EventListener listener, - CORBA_Environment *ev) -{ - int i; - GList **lists[3]; - SpiRegistry *registry = SPI_REGISTRY (bonobo_object_from_servant (servant)); - RemoveListenerClosure cl = { 0, }; - - lists[0] = ®istry->object_listeners; - lists[1] = ®istry->window_listeners; - lists[2] = ®istry->toolkit_listeners; - - cl.remove_all = TRUE; - cl.listener = listener; - - for (i = 0; i < sizeof (lists) / sizeof (lists[0]); i++) - { - spi_re_entrant_list_foreach (lists [i], remove_listener_cb, &cl); - } -} - - -/* - * CORBA Accessibility::Registry::deregisterGlobalEventListener method implementation - */ -static void -impl_accessibility_registry_deregister_global_event_listener ( - PortableServer_Servant servant, - Accessibility_EventListener listener, - const CORBA_char *event_name, - CORBA_Environment *ev) -{ - SpiRegistry *registry; - RemoveListenerClosure cl = { 0, }; - - registry = SPI_REGISTRY (bonobo_object_from_servant (servant)); - - cl.remove_all = FALSE; - parse_event_type (&cl.etype, (char *) event_name); - cl.listener = listener; - - spi_re_entrant_list_foreach (get_listener_list (registry, cl.etype.type_cat), - remove_listener_cb, &cl); -} - - /** * getDesktopCount: * return values: a short integer indicating the current number of @@ -525,17 +168,21 @@ impl_accessibility_registry_deregister_global_event_listener ( * Get the current number of desktops. * **/ -static short -impl_accessibility_registry_get_desktop_count (PortableServer_Servant servant, - CORBA_Environment * ev) +static DBusMessage * +impl_accessibility_registry_get_desktop_count (DBusConnection *bus, DBusMessage *message, void *user_data) { + dbus_int16_t n_desktops = 1; + DBusMessage *reply; + /* TODO: implement support for multiple virtual desktops */ - CORBA_short n_desktops; - n_desktops = (CORBA_short) 1; - return n_desktops; + reply = dbus_message_new_method_return (message); + if (reply) + { + dbus_message_append_args (reply, DBUS_TYPE_INT16, &n_desktops, DBUS_TYPE_INVALID); + } + return reply; } - /** * getDesktop: * @n: the index of the requested @Desktop. @@ -544,23 +191,27 @@ impl_accessibility_registry_get_desktop_count (PortableServer_Servant servant, * Get the nth accessible desktop. * **/ -static Accessibility_Desktop -impl_accessibility_registry_get_desktop (PortableServer_Servant servant, - const CORBA_short n, - CORBA_Environment * ev) +static DBusMessage * +impl_accessibility_registry_get_desktop (DBusConnection *bus, DBusMessage *message, void *user_data) { - SpiRegistry *registry = SPI_REGISTRY (bonobo_object_from_servant (servant)); + DBusError error; + dbus_int16_t n; + const char *path; + DBusMessage *reply; /* TODO: implement support for multiple virtual desktops */ - if (n == 0) - { - return (Accessibility_Desktop) - bonobo_object_dup_ref (BONOBO_OBJREF (registry->desktop), ev); - } - else - { - return (Accessibility_Desktop) CORBA_OBJECT_NIL; - } + dbus_error_init (&error); + if (!dbus_message_get_args (message, &error, DBUS_TYPE_INT16, &n, DBUS_TYPE_INVALID)) + { + return spi_dbus_general_error (message); + } + path = (n == 0? SPI_DBUS_PATH_DESKTOP: "/"); + reply = dbus_message_new_method_return (message); + if (reply) + { + dbus_message_append_args (reply, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID); + } + return reply; } @@ -572,391 +223,63 @@ impl_accessibility_registry_get_desktop (PortableServer_Servant servant, * Get a list of accessible desktops. * **/ -static Accessibility_DesktopSeq * -impl_accessibility_registry_get_desktop_list (PortableServer_Servant servant, - CORBA_Environment * ev) +static DBusMessage * +impl_accessibility_registry_get_desktop_list (DBusConnection *bus, DBusMessage *message, void *user_data) { - SpiRegistry *registry = SPI_REGISTRY (bonobo_object_from_servant (servant)); - Accessibility_DesktopSeq *desktops; + DBusMessage *reply; + DBusMessageIter iter, iter_array; + const char *path = SPI_DBUS_PATH_DESKTOP; - desktops = Accessibility_DesktopSeq__alloc (); - desktops->_length = desktops->_maximum = 1; - desktops->_buffer = Accessibility_DesktopSeq_allocbuf (desktops->_length); - desktops->_buffer [0] = bonobo_object_dup_ref (BONOBO_OBJREF (registry->desktop), ev); - - return desktops; -} - - -static Accessibility_DeviceEventController -impl_accessibility_registry_get_device_event_controller (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - SpiRegistry *registry = SPI_REGISTRY (bonobo_object_from_servant (servant)); - - if (!registry->de_controller) - { - registry->de_controller = spi_device_event_controller_new (registry); - } - - return bonobo_object_dup_ref (BONOBO_OBJREF (registry->de_controller), ev); -} - -typedef struct { - CORBA_Environment *ev; - Bonobo_Unknown source; - EventTypeStruct etype; - Accessibility_Event *e_out; -} NotifyContext; - -static SpiReEntrantContinue -notify_listeners_cb (GList * const *list, gpointer user_data) -{ - SpiListenerStruct *ls; - NotifyContext *ctx = user_data; - - ls = (*list)->data; - -#ifdef SPI_LISTENER_DEBUG - fprintf (stderr, "event quarks: %lx %lx %lx\n", ls->event_type_quark, ctx->etype.major, ctx->etype.minor); - fprintf (stderr, "event name: %s\n", ctx->etype.event_name); -#endif - if ((ls->event_type_quark == ctx->etype.major) || - (ls->event_type_quark == ctx->etype.minor)) - { -#ifdef SPI_DEBUG - CORBA_string s; - fprintf (stderr, "notifying listener %d\n", 0); -/* g_list_index (list, l->data)); */ - s = Accessibility_Accessible__get_name (ctx->source, ctx->ev); - fprintf (stderr, "event source name %s\n", s); - CORBA_free (s); - if (BONOBO_EX (ctx->ev)) - { - CORBA_exception_free (ctx->ev); - return SPI_RE_ENTRANT_CONTINUE; - } -#endif - - ctx->e_out->source = ctx->source; - - if ((*list) && (*list)->data == ls) - { - Accessibility_EventListener_notifyEvent ( - (Accessibility_EventListener) ls->listener, ctx->e_out, ctx->ev); - if (ctx->ev->_major != CORBA_NO_EXCEPTION) - { - DBG (1, g_warning ("Accessibility app error: exception during " - "event notification: %s\n", - CORBA_exception_id (ctx->ev))); - CORBA_exception_free (ctx->ev); - /* FIXME: check that this item is removed from the list - * on system exception by a 'broken' listener */ - } - } - } - - return SPI_RE_ENTRANT_CONTINUE; -} - -static void -registry_emit_event (SpiRegistry *registry, NotifyContext *ctx) -{ - GList **list = get_listener_list (registry, ctx->etype.type_cat); - - if (list && *list) - { - - spi_re_entrant_list_foreach (list, notify_listeners_cb, ctx); - } -} - -static NotifyContext* -registry_clone_notify_context (NotifyContext *ctx) -{ - NotifyContext *new_ctx = g_new0 (NotifyContext, 1); - - new_ctx->ev = NULL; - new_ctx->source = bonobo_object_dup_ref (ctx->source, NULL); - new_ctx->etype.event_name = CORBA_string_dup (ctx->etype.event_name); - new_ctx->etype.type_cat = ctx->etype.type_cat; - new_ctx->etype.major = ctx->etype.major; - new_ctx->etype.minor = ctx->etype.minor; - new_ctx->etype.detail = ctx->etype.detail; - new_ctx->e_out = ORBit_copy_value (ctx->e_out, TC_Accessibility_Event); - return new_ctx; -} - -static void -registry_flush_event_queue (SpiRegistry *registry, - gboolean discard, - CORBA_Environment *ev) -{ - NotifyContext *q_ctx; - while (!g_queue_is_empty (registry->deferred_event_queue)) { - q_ctx = g_queue_pop_tail (registry->deferred_event_queue); -#ifdef SPI_QUEUE_DEBUG - fprintf (stderr, "%s! %s [n=%d] %p\n", (discard ? "discard" : "pop"), - q_ctx->etype.event_name, - (int) registry->deferred_event_queue->length, q_ctx); -#endif - if (!discard) { - q_ctx->ev = ev; - registry_emit_event (registry, q_ctx); - } - if (discard && - (q_ctx->etype.type_cat == ETYPE_OBJECT) && - (q_ctx->etype.major == _state_quark) && - (q_ctx->etype.minor == _state_changed_focused_quark)) { - registry->focus_object = q_ctx->source; -#ifdef SPI_QUEUE_DEBUG - fprintf (stderr, "discard!: set focus_object %p\n", registry->focus_object); -#endif - } - else { - bonobo_object_release_unref (q_ctx->source, NULL); - } - CORBA_free ((void *)q_ctx->etype.event_name); - CORBA_free (q_ctx->e_out); - g_free (q_ctx); - } - registry->is_queueing = FALSE; -} - -static gboolean -registry_timeout_flush_queue (gpointer data) -{ - SpiRegistry *registry = data; - CORBA_Environment ev; -#ifdef SPI_QUEUE_DEBUG - fprintf (stderr, "timeout! flushing queue...\n"); -#endif - CORBA_exception_init (&ev); - registry->queue_handler_id = 0; - registry_flush_event_queue (registry, FALSE, &ev); - return FALSE; -} - -static gboolean -registry_discard_on_event (SpiRegistry *registry, NotifyContext *ctx) -{ - gboolean retval = FALSE; - NotifyContext *q_ctx = g_queue_peek_tail (registry->deferred_event_queue); - if ((q_ctx != NULL) && - (ctx->etype.type_cat == ETYPE_WINDOW) && - (ctx->etype.major == _activate_quark)) { - if (CORBA_Object_is_equivalent (ctx->source, q_ctx->source, NULL)) { - retval = TRUE; - } - } - return retval; -} - -static gboolean -registry_reset_on_event (SpiRegistry *registry, NotifyContext *ctx) -{ - return (ctx->etype.type_cat == ETYPE_WINDOW) ? TRUE : FALSE; + reply = dbus_message_new_method_return (message); + if (!reply) return NULL; + dbus_message_iter_init_append(reply, &iter); + if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "o", &iter_array)) goto oom; + dbus_message_iter_append_basic(&iter_array, DBUS_TYPE_STRING, &path); + if (!dbus_message_iter_close_container (&iter, &iter_array)) goto oom; + return reply; +oom: + // TODO: handle out-of-memory + return reply; } -#ifdef SPI_QUEUE_DEBUG -#include -#endif -static void -registry_start_queue (SpiRegistry *registry) +static DBusMessage * +impl_accessibility_registry_get_device_event_controller (DBusConnection *bus, DBusMessage *message, void *user_data) { -#ifdef SPI_QUEUE_DEBUG - struct timeval tp; - gettimeofday (&tp, NULL); - fprintf (stderr, "start queueing at %i.%.6i\n", tp.tv_sec, tp.tv_usec); -#endif - if (registry->queue_handler_id != 0) - g_source_remove (registry->queue_handler_id); - - if (registry->focus_object) - { -#ifdef SPI_QUEUE_DEBUG - fprintf (stderr, "registry_start_queue: release focus_object %p\n", registry->focus_object); -#endif - bonobo_object_release_unref (registry->focus_object, NULL); - registry->focus_object = NULL; - } - registry->queue_handler_id = g_timeout_add_full (G_PRIORITY_HIGH_IDLE, - registry->exit_notify_timeout, - registry_timeout_flush_queue, registry, - NULL); - registry->is_queueing = TRUE; -} + DBusMessage *reply; + const char *path = SPI_DBUS_PATH_DEC; -static gboolean -registry_discard_event (SpiRegistry *registry, NotifyContext *ctx) -{ - gboolean ret = FALSE; - - if (ctx->etype.type_cat == ETYPE_FOCUS) - { - if (registry->focus_object) - { - if (CORBA_Object_is_equivalent (registry->focus_object, ctx->source, NULL)) - { - ret = TRUE; - } -#ifdef SPI_QUEUE_DEBUG - fprintf (stderr, "registry_discard_event: release focus_object %p\n", registry->focus_object); -#endif - bonobo_object_release_unref (registry->focus_object, NULL); - registry->focus_object = NULL; - } - } - return ret; -} - -static gboolean -registry_defer_on_event (SpiRegistry *registry, NotifyContext *ctx) -{ - gboolean defer = FALSE; - if ((ctx->etype.type_cat == ETYPE_WINDOW) && - (ctx->etype.major == _deactivate_quark)) { - defer = TRUE; - registry_start_queue (registry); - } - /* defer all object:state-change events after a window:deactivate */ - else if ((ctx->etype.type_cat == ETYPE_FOCUS) || - ((ctx->etype.type_cat == ETYPE_OBJECT) && - (ctx->etype.major == _state_quark))) { - defer = TRUE; + reply = dbus_message_new_method_return (message); + if (reply) + { + dbus_message_append_args (reply, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID); } - return defer; + return reply; } -static gboolean -registry_queue_event (SpiRegistry *registry, NotifyContext *ctx) -{ -#ifdef SPI_QUEUE_DEBUG - if (ctx->etype.type_cat != ETYPE_MOUSE) - fprintf (stderr, "push! %s %p\n", ctx->etype.event_name, ctx); -#endif - if (registry->is_queueing) - { - NotifyContext *q_ctx = registry_clone_notify_context (ctx); - - g_queue_push_head (registry->deferred_event_queue, q_ctx); - - return FALSE; - } - else - { - return TRUE; - } -} - -/** - * Dispose of event in one of several ways: - * 1) discard; - * 2) initiate queuing and push onto queue (below) - * 3) push on existing queue to either pop on timeout or on subsequent event - * 4) pass-through immediately - * 5) pass-through, discarding queued events - * 6) emit queued events and then pass through - **/ -static gboolean -registry_filter_event (SpiRegistry *registry, NotifyContext *ctx, - CORBA_Environment *ev) -{ - g_assert (ctx != NULL); - - if (registry_discard_event (registry, ctx)) - return FALSE; - - if (registry_defer_on_event (registry, ctx)) { /* #2, #3 */ - if (registry->is_queueing) { - return registry_queue_event (registry, ctx); - } - else { /* #4a */ - return TRUE; - } - } - else if (registry_reset_on_event (registry, ctx)) { /* #5, #6 */ - gboolean discard = registry_discard_on_event (registry, ctx); -#ifdef SPI_QUEUE_DEBUG - fprintf (stderr, "event %s caused reset, discard=%d\n", - ctx->etype.event_name, (int) discard); - { - struct timeval tp; - gettimeofday (&tp, NULL); - fprintf (stderr, "event at %i.%.6i\n", tp.tv_sec, tp.tv_usec); - } -#endif - registry_flush_event_queue (registry, discard, ev); - return (discard ? FALSE : TRUE); - } - else { /* #4b */ - return TRUE; - } -} - -static void -impl_registry_notify_event (PortableServer_Servant servant, - const Accessibility_Event *e, - CORBA_Environment *ev) -{ - SpiRegistry *registry; - NotifyContext ctx; - static int level = 0; - - level++; - registry = SPI_REGISTRY (bonobo_object_from_servant (servant)); - - parse_event_type (&ctx.etype, e->type); - - ctx.ev = ev; - ctx.e_out = (Accessibility_Event *)e; - ctx.source = e->source; - -#ifdef SPI_QUEUE_DEBUG - if (ctx.etype.type_cat != ETYPE_MOUSE) - fprintf (stderr, "filter! %s level: %d\n", ctx.etype.event_name, level); -#endif - if (registry_filter_event (registry, &ctx, ev)) { -#ifdef SPI_QUEUE_DEBUG - if (ctx.etype.type_cat != ETYPE_MOUSE) - fprintf (stderr, "emit! %s level: %d\n", ctx.etype.event_name, level); -#endif - registry_emit_event (registry, &ctx); - } - level--; -} static void spi_registry_class_init (SpiRegistryClass *klass) { GObjectClass * object_class = (GObjectClass *) klass; - POA_Accessibility_Registry__epv *epv = &klass->epv; - spi_registry_parent_class = g_type_class_ref (SPI_LISTENER_TYPE); + spi_registry_parent_class = g_type_class_ref (G_TYPE_OBJECT); object_class->finalize = spi_registry_object_finalize; - - klass->parent_class.epv.notifyEvent = impl_registry_notify_event; - - epv->registerApplication = impl_accessibility_registry_register_application; - epv->deregisterApplication = impl_accessibility_registry_deregister_application; - epv->registerGlobalEventListener = impl_accessibility_registry_register_global_event_listener; - epv->deregisterGlobalEventListener = impl_accessibility_registry_deregister_global_event_listener; - epv->deregisterGlobalEventListenerAll = impl_accessibility_registry_deregister_global_event_listener_all; - epv->getDeviceEventController = impl_accessibility_registry_get_device_event_controller; - epv->getDesktopCount = impl_accessibility_registry_get_desktop_count; - epv->getDesktop = impl_accessibility_registry_get_desktop; - epv->getDesktopList = impl_accessibility_registry_get_desktop_list; - _deactivate_quark = g_quark_from_static_string ("deactivate"); - _activate_quark = g_quark_from_static_string ("activate"); - _state_quark = g_quark_from_static_string ("state-changed"); - _state_changed_focused_quark = g_quark_from_static_string ("state-changedfocused"); } +static DBusObjectPathVTable droute_vtable = +{ + NULL, + &droute_message, + NULL, NULL, NULL, NULL +}; + static void spi_registry_init (SpiRegistry *registry) { + DBusError error; + spi_registry_set_debug (g_getenv ("AT_SPI_DEBUG")); /* * TODO: FIXME, this module makes the foolish assumptions that @@ -965,20 +288,27 @@ spi_registry_init (SpiRegistry *registry) */ gdk_init (NULL, NULL); - registry->object_listeners = NULL; - registry->window_listeners = NULL; - registry->toolkit_listeners = NULL; - registry->deferred_event_queue = g_queue_new (); registry->exit_notify_timeout = 200; registry->queue_handler_id = 0; - /* - * The focus_object is set when a state-change:focused event is discarded - * after a window:deactivate event is received because a window:activate - * event has been received for the same window within the timeout period. - * The focus object is used to suppress a focus event for that object. - * It is released when a window:deactivate event is received. - */ - registry->focus_object = NULL; + + dbus_error_init (&error); + registry->droute.bus = dbus_bus_get(DBUS_BUS_SESSION, &error); + if (!registry->droute.bus) + { + g_warning("Couldn't connect to dbus: %s\n", error.message); + return; + } + spi_registry_initialize_registry_interface (®istry->droute); + spi_registry_initialize_desktop_interface (®istry->droute); + spi_registry_initialize_dec_interface (®istry->droute); + // todo: initialize accessible and component interfaces, for desktop? + if (!dbus_connection_try_register_fallback (registry->droute.bus, "/org/freedesktop/atspi", &droute_vtable, ®istry->droute, &error)) + { + g_warning("Couldn't register droute.\n"); + } + dbus_connection_setup_with_g_main(registry->droute.bus, g_main_context_default()); + + // TODO: decide whether focus_object is still relevant registry->desktop = spi_desktop_new (); /* Register callback notification for application addition and removal */ g_signal_connect (G_OBJECT (registry->desktop), @@ -994,15 +324,27 @@ spi_registry_init (SpiRegistry *registry) registry->de_controller = spi_device_event_controller_new (registry); } -BONOBO_TYPE_FUNC_FULL (SpiRegistry, - Accessibility_Registry, - PARENT_TYPE, - spi_registry) - SpiRegistry * spi_registry_new (void) { SpiRegistry *retval = g_object_new (SPI_REGISTRY_TYPE, NULL); - bonobo_object_set_immortal (BONOBO_OBJECT (retval), TRUE); return retval; } + +static DRouteMethod methods[] = +{ + { impl_accessibility_registry_register_application , "registerApplication" }, + { impl_accessibility_registry_deregister_application, "deregisterApplication" }, + { impl_accessibility_registry_get_desktop_count, "getDesktopCount" }, + { impl_accessibility_registry_get_desktop, "getDesktop" }, + { impl_accessibility_registry_get_desktop_list, "getDesktopList" }, + { impl_accessibility_registry_get_device_event_controller, "getDeviceEventController" }, + { NULL, NULL } +}; + +void +spi_registry_initialize_registry_interface (DRouteData * data) +{ + droute_add_interface (data, "org.freedesktop.atspi.Registry", methods, + NULL, NULL, NULL); +}; diff --git a/registryd/registry.h b/registryd/registry.h index 679adeb..ead4fcb 100644 --- a/registryd/registry.h +++ b/registryd/registry.h @@ -25,7 +25,6 @@ #define SPI_REGISTRY_H_ #include -#include typedef struct _SpiRegistry SpiRegistry; @@ -41,7 +40,7 @@ G_BEGIN_DECLS #define SPI_IS_REGISTRY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_REGISTRY_TYPE)) struct _SpiRegistry { - SpiListener parent; + GObject parent; GList *object_listeners; GList *window_listeners; @@ -50,20 +49,25 @@ struct _SpiRegistry { gboolean is_queueing; guint exit_notify_timeout; guint queue_handler_id; - Bonobo_Unknown focus_object; + char *focus_object_bus; + char *focus_object_path; SpiDEController *de_controller; SpiDesktop *desktop; + DRouteData droute; }; typedef struct { - SpiListenerClass parent_class; - - POA_Accessibility_Registry__epv epv; + GObjectClass parent_class; } SpiRegistryClass; GType spi_registry_get_type (void); SpiRegistry *spi_registry_new (void); +void spi_registry_emit(SpiRegistry *registry, const char *name, int first_arg_type, ...); + +void spi_registry_initialize_registry_interface (DRouteData * data); +void spi_registry_initialize_dec_interface (DRouteData * data); +void spi_registry_initialize_desktop_interface (DRouteData * data); G_END_DECLS #endif /* SPI_REGISTRY_H_ */ -- 2.7.4