From: Mark Doffman Date: Sat, 11 Oct 2008 14:51:00 +0000 (+0100) Subject: 2008-10-11 Mark Doffman X-Git-Tag: AT_SPI2_CORE_0_1_3~128 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=497722b006e292663865c2e830373badb0622f58;p=platform%2Fupstream%2Fat-spi2-core.git 2008-10-11 Mark Doffman * registryd/* Add an icomplete NON WORKING implementation of application registration as specified in xml/org.freedesktop.atspi.Registry.xml xml/org.freedesktop.atspi.Tree.xml --- diff --git a/registryd/Makefile.am b/registryd/Makefile.am index 85f6fb2..9fecd7d 100644 --- a/registryd/Makefile.am +++ b/registryd/Makefile.am @@ -17,13 +17,10 @@ at_spi_registryd_LDADD = $(DBUS_GLIB_LIBS) \ $(top_builddir)/spi-common/libspicommon.la at_spi_registryd_SOURCES = \ - desktop.c \ - desktop.h \ - deviceeventcontroller.c \ - deviceeventcontroller.h \ registry-main.c \ registry.c \ registry.h \ - reentrant-list.c \ - reentrant-list.h \ ucs2keysym.c + +# deviceeventcontroller.c +# deviceeventcontroller.h diff --git a/registryd/desktop.c b/registryd/desktop.c deleted file mode 100644 index 2b08d02..0000000 --- a/registryd/desktop.c +++ /dev/null @@ -1,393 +0,0 @@ -/* - * AT-SPI - Assistive Technology Service Provider Interface - * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap) - * - * Copyright 2001, 2002 Sun Microsystems Inc., - * Copyright 2001, 2002 Ximian, Inc., Ximian Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* desktop.c: implements SpiDesktop.idl */ - -#include -#include -#include -#include -#include -#include - -#include - -#include "desktop.h" -#include "registry.h" - -G_DEFINE_TYPE(SpiDesktop, spi_desktop, G_TYPE_OBJECT) - -/* SpiDesktop signals */ -enum { - APPLICATION_ADDED, - APPLICATION_REMOVED, -LAST_SIGNAL -}; -static guint spi_desktop_signals[LAST_SIGNAL]; - - -/* Our parent Gtk object type */ -#define PARENT_TYPE SPI_ACCESSIBLE_TYPE - -static gboolean exiting = FALSE; - -/* A pointer to our parent object 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)) -#define SPI_IS_ATK_DESKTOP(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SPI_TYPE_ATK_DESKTOP)) - -typedef struct { - AtkObject parent; - - GdkScreen *screen; -} SpiAtkDesktop; - -typedef struct { - AtkObjectClass parent; -} SpiAtkDesktopClass; - -static void spi_atk_desktop_init (SpiAtkDesktop *desktop); -static void atk_component_interface_init (AtkComponentIface *iface); -static void spi_atk_desktop_get_extents (AtkComponent *component, - gint *x, - gint *y, - gint *width, - gint *height, - AtkCoordType coord_type); - -static GType -spi_atk_desktop_get_type (void) -{ - static GType type = 0; - - if (!type) - { - static const GTypeInfo typeInfo = - { - sizeof (SpiAtkDesktopClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) NULL, - (GClassFinalizeFunc) NULL, - NULL, - sizeof (SpiAtkDesktop), - 0, - (GInstanceInitFunc) spi_atk_desktop_init, - } ; - static const GInterfaceInfo atk_component_info = - { - (GInterfaceInitFunc) atk_component_interface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - - type = g_type_register_static (ATK_TYPE_OBJECT, - "SpiAtkDesktop", &typeInfo, 0); - g_type_add_interface_static (type, ATK_TYPE_COMPONENT, - &atk_component_info); - } - return type; -} - -static void -spi_atk_desktop_init (SpiAtkDesktop *desktop) -{ - GdkDisplay *display; - - atk_object_set_name (ATK_OBJECT (desktop), "main"); - display = gdk_x11_lookup_xdisplay (GDK_DISPLAY ()); - desktop->screen = gdk_display_get_default_screen (display); -} - -static void -atk_component_interface_init (AtkComponentIface *iface) -{ - g_return_if_fail (iface != NULL); - - iface->get_extents = spi_atk_desktop_get_extents; -} - -static void -spi_atk_desktop_get_extents (AtkComponent *component, - gint *x, - gint *y, - gint *width, - gint *height, - AtkCoordType coord_type) -{ - SpiAtkDesktop *desktop; - - g_return_if_fail (SPI_IS_ATK_DESKTOP (component)); - desktop = SPI_ATK_DESKTOP (component); - *x = 0; - *y = 0; - *width = gdk_screen_get_width (desktop->screen); - *height = gdk_screen_get_height (desktop->screen); -} - -static void -spi_desktop_init (SpiDesktop *desktop) -{ - desktop->applications = NULL; -} - -static void -spi_desktop_dispose (GObject *object) -{ - SpiDesktop *desktop = (SpiDesktop *) object; - - while (desktop->applications) - { - SpiDesktopApplication *app = desktop->applications->data; - g_assert (app != NULL); - spi_desktop_remove_application (desktop, app->bus_name); - } - - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static dbus_bool_t -impl_desktop_get_child_count (const char *path, DBusMessageIter * iter, - void *user_data) -{ - SpiDesktop *desktop = SPI_REGISTRY(user_data)->desktop; - - if (desktop->applications) - { - return droute_return_v_int32(iter, g_list_length (desktop->applications)); - } - else - { - return droute_return_v_int32(iter, 0); - } -} - -static DBusMessage * -impl_desktop_get_child_at_index (DBusConnection *bus, DBusMessage *message, void *user_data) -{ - SpiDesktop *desktop = SPI_REGISTRY(user_data)->desktop; - DBusError error; - dbus_int32_t index; - SpiDesktopApplication *app; - const char *bus_name; - 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); - bus_name = (app? app->bus_name: ""); - - reply = dbus_message_new_method_return (message); - if (reply) - { - dbus_message_append_args (reply, DBUS_TYPE_STRING, &bus_name, DBUS_TYPE_INVALID); - } - - return reply; -} - -static DBusMessage * -impl_desktop_get_children (DBusConnection *bus, DBusMessage *message, void *user_data) -{ - SpiDesktop *desktop = SPI_REGISTRY(user_data)->desktop; - DBusError error; - gint count; - gint i; - SpiDesktopApplication *app; - DBusMessage *reply; - DBusMessageIter iter, iter_array; - - 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, "s", &iter_array)) - { - goto oom; - } - count = g_list_length (desktop->applications); - for (i = 0; i < count; i++) - { - app = g_list_nth_data (desktop->applications, i); - if (!app) - { - g_warning ("Null app\n"); - continue; - } - dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_STRING, &app->bus_name); - } - if (!dbus_message_iter_close_container (&iter, &iter_array)) - { - goto oom; - } - return reply; -oom: - // TODO: Handle out of memory - return reply; -} - -static dbus_bool_t -impl_get_name (const char *path, DBusMessageIter * iter, void *user_data) -{ - if (strcmp (path, SPI_DBUS_PATH_DESKTOP) != 0) - return FALSE; - // TODO: call atk_object_get_name - return droute_return_v_string (iter, "main"); -} - -static void -spi_desktop_exiting (void) -{ - exiting = TRUE; -} - -static void -spi_desktop_class_init (SpiDesktopClass *klass) -{ - GObjectClass * object_class = (GObjectClass *) klass; - - object_class->dispose = spi_desktop_dispose; - - parent_class = g_type_class_ref (G_TYPE_OBJECT); - - spi_desktop_signals[APPLICATION_ADDED] = - g_signal_new ("application_added", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (SpiDesktopClass, application_added), - NULL, NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, - 1, G_TYPE_UINT); - spi_desktop_signals[APPLICATION_REMOVED] = - g_signal_new ("application_removed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (SpiDesktopClass, application_removed), - NULL, NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, - 1, G_TYPE_UINT); - g_atexit (spi_desktop_exiting); -} - -SpiDesktop * -spi_desktop_new (void) -{ - return g_object_new (SPI_DESKTOP_TYPE, NULL); -} - -static void -abnormal_application_termination (gpointer object, SpiDesktopApplication *app) -{ - g_return_if_fail (SPI_IS_DESKTOP (app->desktop)); - - if (!exiting) - spi_desktop_remove_application (app->desktop, app->bus_name); -} - -void -spi_desktop_add_application (SpiDesktop *desktop, - const char *application) -{ - SpiDesktopApplication *app; - - g_return_if_fail (SPI_IS_DESKTOP (desktop)); - - app = g_new (SpiDesktopApplication, 1); - app->desktop = desktop; - app->bus_name = g_strdup (application); - - desktop->applications = g_list_append (desktop->applications, 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)); -} - -void -spi_desktop_remove_application (SpiDesktop *desktop, - const char *bus_name) -{ - guint idx; - GList *l; - SpiDesktopApplication *app; - - g_return_if_fail ( bus_name != NULL); - g_return_if_fail (SPI_IS_DESKTOP (desktop)); - - idx = 0; - for (l = desktop->applications; l; l = l->next) - { - app = (SpiDesktopApplication *) l->data; - - if (!strcmp(app->bus_name, bus_name)) - { - break; - } - idx++; - } - - if (!l) return; - - g_signal_emit (G_OBJECT (desktop), spi_desktop_signals[APPLICATION_REMOVED], 0, idx); - - desktop->applications = g_list_delete_link (desktop->applications, l); - - g_free (app->bus_name); - g_free (app); -} - -static DRouteMethod methods_desktop[] = -{ - { impl_desktop_get_child_at_index, "getChildAtIndex" }, - { impl_desktop_get_children, "getChildren" }, - { NULL, NULL } -}; - -static DRouteProperty properties_desktop[] = -{ - { impl_desktop_get_child_count, NULL, "getChildCount" }, - { NULL, NULL, NULL } -}; - -static DRouteProperty properties_accessible[] = -{ - { impl_get_name, "getName" }, - { NULL, NULL } -}; - -void -spi_registry_initialize_desktop_interface (DRouteData * data) -{ - droute_add_interface (data, SPI_DBUS_INTERFACE_DESKTOP, methods_desktop, - properties_desktop, NULL, NULL); - droute_add_interface (data, SPI_DBUS_INTERFACE_ACCESSIBLE, NULL, - properties_accessible, NULL, NULL); -}; diff --git a/registryd/desktop.h b/registryd/desktop.h deleted file mode 100644 index 3a0e401..0000000 --- a/registryd/desktop.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * AT-SPI - Assistive Technology Service Provider Interface - * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap) - * - * Copyright 2001, 2002 Sun Microsystems Inc., - * Copyright 2001, 2002 Ximian, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef SPI_DESKTOP_H_ -#define SPI_DESKTOP_H_ - -#include - -G_BEGIN_DECLS - -#define SPI_DESKTOP_TYPE (spi_desktop_get_type ()) -#define SPI_DESKTOP(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_DESKTOP_TYPE, SpiDesktop)) -#define SPI_DESKTOP_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), SPI_DESKTOP_TYPE, SpiDesktopClass)) -#define SPI_IS_DESKTOP(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SPI_DESKTOP_TYPE)) -#define SPI_IS_DESKTOP_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_DESKTOP_TYPE)) - -typedef struct { - GObject parent; - GList *applications; -} SpiDesktop; - -typedef struct { - GObjectClass parent_class; - /*Signals */ - void (*application_added) (SpiDesktop *desktop, - guint index); - void (*application_removed) (SpiDesktop *desktop, - guint index); -} SpiDesktopClass; - -GType spi_desktop_get_type (void); -SpiDesktop *spi_desktop_new (void); -void spi_desktop_add_application (SpiDesktop *desktop, - const char *bus_name); -void spi_desktop_remove_application (SpiDesktop *desktop, - const char *bus_name); - -typedef struct { - SpiDesktop *desktop; - const char *bus_name; -} SpiDesktopApplication; - -G_END_DECLS - -#endif /* SPI_DESKTOP_H_ */ diff --git a/registryd/deviceeventcontroller.c b/registryd/deviceeventcontroller.c index 8ca6699..4b0ba0d 100644 --- a/registryd/deviceeventcontroller.c +++ b/registryd/deviceeventcontroller.c @@ -2714,9 +2714,17 @@ static DRouteMethod methods[] = { NULL, NULL } }; -void +static void spi_registry_initialize_dec_interface (DRouteData * data) { droute_add_interface (data, SPI_DBUS_INTERFACE_DEC, methods, NULL, NULL, NULL); }; + +SpiDEController * +spi_registry_dec_new (DRouteData *droute) +{ + SpiDEController *dec = g_object_new (SPI_DEVICE_EVENT_CONTROLLER_TYPE, 1); + spi_registry_initialize_dec_interface (&droute); + return dec; +} diff --git a/registryd/deviceeventcontroller.h b/registryd/deviceeventcontroller.h index df8288b..fad9be7 100644 --- a/registryd/deviceeventcontroller.h +++ b/registryd/deviceeventcontroller.h @@ -59,6 +59,8 @@ SpiDEController *spi_device_event_controller_new (SpiRegistry *registry); void spi_remove_device_listeners (SpiDEController *controller, const char *bus_name); +void spi_registry_initialize_dec_interface (DRouteData * data); + G_END_DECLS #endif /* DEVICEEVENTCONTROLLER_H_ */ diff --git a/registryd/reentrant-list.c b/registryd/reentrant-list.c deleted file mode 100644 index 6e9911e..0000000 --- a/registryd/reentrant-list.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * AT-SPI - Assistive Technology Service Provider Interface - * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap) - * - * Copyright 2001, 2002 Sun Microsystems Inc., - * Copyright 2001, 2002 Ximian, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include -#include - -#include "reentrant-list.h" - -typedef struct { - GList **list; - GList *iterator; -} Iteration; - -static GSList *working_list = NULL; /* of Iteration */ - -/* - * deletes an element from the list - in a re-entrant - * safe fashion; advances the element pointer to the next - * element. - */ -void -spi_re_entrant_list_delete_link (GList * const *element_ptr) -{ - GSList *l; - GList *next; - GList *element; - gboolean first_item; - - g_return_if_fail (element_ptr != NULL); - - element = *element_ptr; - g_return_if_fail (element != NULL); - - next = element->next; - first_item = (element->prev == NULL); - - g_list_remove_link (NULL, element); - - for (l = working_list; l; l = l->next) - { - Iteration *i = l->data; - - if (i->iterator == element) - { - i->iterator = next; - } - - if (first_item && *(i->list) == element) - { - *(i->list) = next; - } - } - - g_list_free_1 (element); -} - -void -spi_re_entrant_list_foreach (GList **list, - SpiReEntrantFn func, - gpointer user_data) -{ - Iteration i; - - if (!list || !*list) - { - return; - } - - i.list = list; - i.iterator = *list; - - working_list = g_slist_prepend (working_list, &i); - - while (i.iterator) { - GList *l = i.iterator; - - func (&i.iterator, user_data); - - if (i.iterator == l) - i.iterator = i.iterator->next; - } - - working_list = g_slist_remove (working_list, &i); -} diff --git a/registryd/reentrant-list.h b/registryd/reentrant-list.h deleted file mode 100644 index 88e37e4..0000000 --- a/registryd/reentrant-list.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * AT-SPI - Assistive Technology Service Provider Interface - * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap) - * - * Copyright 2001, 2002 Sun Microsystems Inc., - * Copyright 2001, 2002 Ximian, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef REENTRANT_LIST_H_ -#define REENTRANT_LIST_H_ - -#include - -G_BEGIN_DECLS - -typedef enum { - SPI_RE_ENTRANT_CONTINUE = 0, - SPI_RE_ENTRANT_TERMINATE -} SpiReEntrantContinue; - -typedef SpiReEntrantContinue (*SpiReEntrantFn) (GList * const *list, - gpointer user_data); - -void spi_re_entrant_list_delete_link (GList * const *element_ptr); -void spi_re_entrant_list_foreach (GList **list, - SpiReEntrantFn func, - gpointer user_data); - -G_END_DECLS - -#endif /* REENTRANT_LIST_H_ */ diff --git a/registryd/registry-main.c b/registryd/registry-main.c index 84e97be..dd42775 100644 --- a/registryd/registry-main.c +++ b/registryd/registry-main.c @@ -32,7 +32,7 @@ static gchar *dbus_name = NULL; -static GOptionEntry optentries[] = +static GOptionEntry optentries[] = { {"dbus-name", 0, 0, G_OPTION_ARG_STRING, &dbus_name, "Well-known name to register with D-Bus", NULL}, {NULL} @@ -42,7 +42,11 @@ int main (int argc, char **argv) { SpiRegistry *registry; + /*SpiDEController *dec;*/ + GMainLoop *mainloop; + DBusConnection *bus; + GOptionContext *opt; GError *err = NULL; @@ -61,13 +65,17 @@ main (int argc, char **argv) if (dbus_name == NULL) dbus_name = SPI_DBUS_NAME_REGISTRY; - registry = spi_registry_new (); + dbus_error_init (&error); + bus = dbus_bus_get(DBUS_BUS_SESSION, &error); + if (!bus) + { + g_warning("Couldn't connect to dbus: %s\n", error.message); + } mainloop = g_main_loop_new (NULL, FALSE); + dbus_connection_setup_with_g_main(bus, g_main_context_default()); - dbus_error_init (&error); - ret = dbus_bus_request_name(registry->droute.bus, dbus_name, DBUS_NAME_FLAG_DO_NOT_QUEUE, &error); - + ret = dbus_bus_request_name(bus, dbus_name, DBUS_NAME_FLAG_DO_NOT_QUEUE, &error); if (ret == DBUS_REQUEST_NAME_REPLY_EXISTS) { g_error("Could not obtain D-Bus name - %s\n", dbus_name); @@ -75,8 +83,11 @@ main (int argc, char **argv) else { g_print ("SpiRegistry daemon is running with well-known name - %s\n", dbus_name); - g_main_loop_run (mainloop); } + /*dec = spi_registry_dec_new (bus);*/ + registry = spi_registry_new (bus); + + g_main_loop_run (mainloop); return 0; } diff --git a/registryd/registry.c b/registryd/registry.c index 596e725..3423f92 100644 --- a/registryd/registry.c +++ b/registryd/registry.c @@ -2,6 +2,7 @@ * AT-SPI - Assistive Technology Service Provider Interface * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap) * + * Copyright 2008, Codethink Ltd. * Copyright 2001, 2002 Sun Microsystems Inc., * Copyright 2001, 2002 Ximian, Inc. * @@ -21,358 +22,218 @@ * Boston, MA 02111-1307, USA. */ -/* registry.c: the main accessibility service registry implementation */ - -#undef SPI_LISTENER_DEBUG -#undef SPI_DEBUG -#undef SPI_QUEUE_DEBUG - #include -#ifdef SPI_DEBUG -# include -#endif - #include +#include #include "registry.h" -#include "dbus/dbus-glib-lowlevel.h" - -/* Our parent GObject type */ -#define PARENT_TYPE G_OBJECT_TYPE - -int _dbg = 0; - -typedef enum { - ETYPE_FOCUS, - ETYPE_OBJECT, - ETYPE_PROPERTY, - ETYPE_WINDOW, - ETYPE_TOOLKIT, - ETYPE_KEYBOARD, - ETYPE_MOUSE, - ETYPE_LAST_DEFINED -} EventTypeCategory; - -typedef struct { - const char *event_name; - EventTypeCategory type_cat; - GQuark major; /* from string segment[1] */ - GQuark minor; /* from string segment[1]+segment[2] */ - GQuark detail; /* from string segment[3] (not concatenated) */ -} EventTypeStruct; + +/*---------------------------------------------------------------------------*/ G_DEFINE_TYPE(SpiRegistry, spi_registry, G_TYPE_OBJECT) static void -spi_registry_set_debug (const char *debug_flag_string) -{ - if (debug_flag_string) - _dbg = (int) g_ascii_strtod (debug_flag_string, NULL); -} - -static void emit(SpiRegistry *registry, const char *name, int first_type, ...) +spi_registry_class_init (SpiRegistryClass *klass) { - va_list arg; + GObjectClass * object_class = (GObjectClass *) klass; - va_start(arg, first_type); - spi_dbus_emit_valist(registry->droute.bus, SPI_DBUS_PATH_DESKTOP, SPI_DBUS_INTERFACE_REGISTRY, name, first_type, arg); - va_end(arg); + spi_registry_parent_class = g_type_class_ref (G_TYPE_OBJECT); } static void -desktop_add_application (SpiDesktop *desktop, - guint index, gpointer data) +spi_registry_init (SpiRegistry *registry) { - SpiRegistry *registry = SPI_REGISTRY (data); - const SpiDesktopApplication *app = g_list_nth_data(desktop->applications, index); - - emit(registry, "applicationAdd", DBUS_TYPE_UINT32, &index, DBUS_TYPE_STRING, &app->bus_name, DBUS_TYPE_INVALID); + registry->apps = g_sequence_new (g_free); } +/*---------------------------------------------------------------------------*/ - -static void -desktop_remove_application (SpiDesktop *desktop, - guint index, gpointer data) +static void emit(SpiRegistry *reg, const char *itf, const char *name, int ftype, ...) { - SpiRegistry *registry = SPI_REGISTRY (data); - SpiDesktopApplication *app = g_list_nth_data(desktop->applications, index); - - spi_dbus_remove_disconnect_match (registry->droute.bus, app->bus_name); - emit(registry, "applicationRemove", DBUS_TYPE_UINT32, &index, DBUS_TYPE_STRING, &app->bus_name, DBUS_TYPE_INVALID); + va_list arg; + + va_start(arg, ftype); + spi_dbus_emit_valist(reg->bus, SPI_DBUS_PATH_DEC, itf, name, ftype, arg); + va_end(arg); } +/*---------------------------------------------------------------------------*/ static void -spi_registry_object_finalize (GObject *object) +add_bus_name_cb (gpointer item, gpointer data) { - DBG (1, g_warning ("spi_registry_object_finalize called\n")); - g_object_unref (SPI_REGISTRY (object)->de_controller); + DBusMessageIter *iter_array = (DBusMessageIter *) data; - G_OBJECT_CLASS (spi_registry_parent_class)->finalize (object); + dbus_message_iter_append_basic (iter_array, DBUS_TYPE_STRING, (gchar *) item); } -/** - * registerApplication: - * @application: a reference to the requesting @Application - * return values: void - * - * Register a new application with the accessibility broker. - * - **/ static DBusMessage * -impl_accessibility_registry_register_application (DBusConnection *bus, DBusMessage *message, void *user_data) +impl_getApplications (DBusConnection *bus, DBusMessage *message, void *user_data) { - SpiRegistry *registry = SPI_REGISTRY (user_data); - const char *application = dbus_message_get_sender (message); - -#ifdef SPI_DEBUG - fprintf (stderr, "registering app %s\n", application); -#endif - spi_desktop_add_application (registry->desktop, application); + DBusMessage *reply; + DBusMessageIter iter, iter_array; + SpiRegistry *reg = SPI_REGISTRY (user_data); - spi_dbus_add_disconnect_match (registry->droute.bus, application); + reply = dbus_message_new_method_return (message); - /* - * TODO: change the implementation below to a WM-aware one; - * e.g. don't add all apps to the SpiDesktop - */ - return dbus_message_new_method_return (message); + dbus_message_iter_init_append (reply, &iter); + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &iter_array); + g_sequence_foreach (reg->apps, add_bus_name_cb, &iter_array); + dbus_message_iter_close_container(&iter, &iter_array); + return reply; } -/** - * deregisterApplication: - * @application: a reference to the @Application - * to be deregistered. - * return values: void - * - * De-register an application previously registered with the broker. - * - **/ -static DBusMessage * -impl_accessibility_registry_deregister_application (DBusConnection *bus, DBusMessage *message, void *user_data) -{ - 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 %s\n", application); -#endif - return dbus_message_new_method_return (message); +static DBusHandlerResult +message_handler (DBusConnection *bus, DBusMessage *message, void *user_data) +{ + DBusMessage *reply = NULL; + + if (dbus_message_is_method_call (message, SPI_DBUS_INTERFACE_REGISTRY, "getApplications")) + { + reply = impl_getApplications (bus, message, user_data); + if (reply) + { + dbus_connection_send (bus, reply, NULL); + dbus_message_unref (reply); + } + return DBUS_HANDLER_RESULT_HANDLED; + } + else + { + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } } -/** - * getDesktopCount: - * return values: a short integer indicating the current number of - * @Desktops. - * - * Get the current number of desktops. - * - **/ -static DBusMessage * -impl_accessibility_registry_get_desktop_count (DBusConnection *bus, DBusMessage *message, void *user_data) +/*---------------------------------------------------------------------------*/ + +static gint +data_str_cmp (gpointer a, gpointer b, gpointer data) { - dbus_int16_t n_desktops = 1; - DBusMessage *reply; + return g_strcmp0(a, b); +} - /* TODO: implement support for multiple virtual 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; +static gboolean +seq_remove_string (GSequence *seq, gchar *str) +{ + GSequenceIter *iter; + gchar *item; + gboolean res = FALSE; + + iter = g_sequence_search (seq, str, (GCompareDataFunc) data_str_cmp, NULL); + iter = g_sequence_iter_prev (iter); + + if (!g_sequence_iter_is_end (iter)) + { + item = g_sequence_get (iter); + if (!g_strcmp0 (item, str)) + { + g_sequence_remove (iter); + res = TRUE; + } + } + return res; } -/** - * getDesktop: - * @n: the index of the requested @Desktop. - * return values: a reference to the requested @Desktop. - * - * Get the nth accessible desktop. - * - **/ -static DBusMessage * -impl_accessibility_registry_get_desktop (DBusConnection *bus, DBusMessage *message, void *user_data) +static void +handle_register_application (SpiRegistry *reg, DBusMessage *message) { - DBusError error; - dbus_int16_t n; - const char *path; - DBusMessage *reply; + gchar *app_name; - /* TODO: implement support for multiple virtual desktops */ - 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; + if (dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &app_name, DBUS_TYPE_INVALID)) + g_sequence_insert_sorted (reg->apps, app_name, (GCompareDataFunc) data_str_cmp, NULL); } - -/** - * getDesktopList: - * return values: a sequence containing references to - * the @Desktops. - * - * Get a list of accessible desktops. - * - **/ -static DBusMessage * -impl_accessibility_registry_get_desktop_list (DBusConnection *bus, DBusMessage *message, void *user_data) +static void +handle_deregister_application (SpiRegistry *reg, DBusMessage *message) { - DBusMessage *reply; - DBusMessageIter iter, iter_array; - const char *path = SPI_DBUS_PATH_DESKTOP; + gchar *app_name; - 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_OBJECT_PATH, &path); - if (!dbus_message_iter_close_container (&iter, &iter_array)) goto oom; - return reply; -oom: - // TODO: handle out-of-memory - return reply; + if (dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &app_name, DBUS_TYPE_INVALID)) + seq_remove_string (reg->apps, app_name); } - -static DBusMessage * -impl_accessibility_registry_get_device_event_controller (DBusConnection *bus, DBusMessage *message, void *user_data) +static void +handle_disconnection (SpiRegistry *reg, DBusMessage *message) { - DBusMessage *reply; - const char *path = SPI_DBUS_PATH_DEC; + char *name, *old, *new; - reply = dbus_message_new_method_return (message); - if (reply) + if (dbus_message_get_args (message, NULL, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &old, + DBUS_TYPE_STRING, &new, + DBUS_TYPE_INVALID)) { - dbus_message_append_args (reply, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID); + if (*old != '\0' && *new == '\0') + { + if (seq_remove_string (reg->apps, old)) + { + /*Emit deregistered signal here*/ + emit (reg, SPI_DBUS_INTERFACE_TREE, "deregisterApplication", DBUS_TYPE_STRING, old); + /*TODO spi_remove_device_listeners (registry->de_controller, old);*/ + } + } } - return reply; } - -static void -spi_registry_class_init (SpiRegistryClass *klass) +static DBusHandlerResult +signal_handler (DBusConnection *bus, DBusMessage *message, void *user_data) { - GObjectClass * object_class = (GObjectClass *) klass; + SpiRegistry *registry = SPI_REGISTRY (user_data); + guint res = DBUS_HANDLER_RESULT_HANDLED; + const char *iface = dbus_message_get_interface (message); + const char *member = dbus_message_get_member (message); + + g_print ("\n%s", iface); + g_print ("\n%d", dbus_message_get_type (message)); + g_print ("\n%s\n", member); + +#if 0 + if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) + handle_disconnection (registry, message); + else if (dbus_message_is_signal (message, SPI_DBUS_INTERFACE_TREE, "registerApplication")) + handle_register_application (registry, message); + else if (dbus_message_is_signal (message, SPI_DBUS_INTERFACE_TREE, "deregisterApplication")) + handle_deregister_application (registry, message); + else + res = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +#endif - spi_registry_parent_class = g_type_class_ref (G_TYPE_OBJECT); - - object_class->finalize = spi_registry_object_finalize; + if (!g_strcmp0(iface, DBUS_INTERFACE_DBUS) && !g_strcmp0(member, "NameOwnerChanged")) + handle_disconnection (registry, message); + else if (!g_strcmp0(iface, SPI_DBUS_INTERFACE_TREE) && !g_strcmp0(member, "registerApplication")) + handle_register_application (registry, message); + else if (!g_strcmp0(iface, SPI_DBUS_INTERFACE_TREE) && !g_strcmp0(member, "deregisterApplication")) + handle_deregister_application (registry, message); + else + res = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + return res; } -static DBusObjectPathVTable droute_vtable = +/*---------------------------------------------------------------------------*/ + +static gchar *app_reg_sig_match = "type='signal', interface='org.freedesktop.atspi.Tree', member='registerApplication'"; +static gchar *app_dereg_sig_match = "type='signal', interface='org.freedesktop.atspi.Tree', member='deregisterApplication'"; + +static DBusObjectPathVTable reg_vtable = { NULL, - &droute_message, + &message_handler, NULL, NULL, NULL, NULL }; -DBusHandlerResult -disconnect_watch (DBusConnection *bus, DBusMessage *message, void *user_data) -{ - SpiRegistry *registry = SPI_REGISTRY (user_data); - const char *name, *old, *new; - - if (!dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) - { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &old, DBUS_TYPE_STRING, &new, DBUS_TYPE_INVALID)) - { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - if (*old != '\0' && *new == '\0') - { - spi_desktop_remove_application (registry->desktop, old); - spi_remove_device_listeners (registry->de_controller, old); - } - return DBUS_HANDLER_RESULT_HANDLED; -} - -static void -spi_registry_init (SpiRegistry *registry) +SpiRegistry * +spi_registry_new (DBusConnection *bus) { - DBusError error; - - spi_registry_set_debug (g_getenv ("AT_SPI_DEBUG")); - /* - * TODO: FIXME, this module makes the foolish assumptions that - * registryd uses the same display as the apps, and that the - * DISPLAY environment variable is set. - */ - gdk_init (NULL, NULL); - - registry->exit_notify_timeout = 200; - registry->queue_handler_id = 0; - - 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; - } - registry->droute.user_data = registry; - 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()); + SpiRegistry *reg = g_object_new (SPI_REGISTRY_TYPE, NULL); - // 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), - "application_added", - G_CALLBACK (desktop_add_application), - registry); + reg->bus = bus; - g_signal_connect (G_OBJECT (registry->desktop), - "application_removed", - G_CALLBACK (desktop_remove_application), - registry); + dbus_connection_register_object_path(bus, SPI_DBUS_PATH_REGISTRY, ®_vtable, reg); - registry->de_controller = spi_device_event_controller_new (registry); + dbus_bus_add_match (bus, app_reg_sig_match, NULL); + dbus_bus_add_match (bus, app_dereg_sig_match, NULL); + dbus_connection_add_filter (bus, signal_handler, reg, NULL); - dbus_connection_add_filter (registry->droute.bus, disconnect_watch, registry, NULL); -} - -SpiRegistry * -spi_registry_new (void) -{ - SpiRegistry *retval = g_object_new (SPI_REGISTRY_TYPE, NULL); - return retval; + return reg; } - -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 7dea784..87f6bed 100644 --- a/registryd/registry.h +++ b/registryd/registry.h @@ -24,13 +24,11 @@ #ifndef SPI_REGISTRY_H_ #define SPI_REGISTRY_H_ -#include -#include +#include +#include typedef struct _SpiRegistry SpiRegistry; - -#include "desktop.h" -#include "deviceeventcontroller.h" +typedef struct _SpiRegistryClass SpiRegistryClass; G_BEGIN_DECLS @@ -42,33 +40,18 @@ G_BEGIN_DECLS struct _SpiRegistry { GObject parent; + GSequence *apps; - GList *object_listeners; - GList *window_listeners; - GList *toolkit_listeners; - GQueue *deferred_event_queue; - gboolean is_queueing; - guint exit_notify_timeout; - guint queue_handler_id; - char *focus_object_bus; - char *focus_object_path; - SpiDEController *de_controller; - SpiDesktop *desktop; - DRouteData droute; + DBusConnection *bus; }; -typedef struct { +struct _SpiRegistryClass { 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, ...); +SpiRegistry *spi_registry_new (DBusConnection *bus); -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_ */