X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git;a=blobdiff_plain;f=registryd%2Fregistry.c;h=51aaa4d3cb7e7f10560073a5bf6eef96267e501d;hp=506843d05ad668b52dfce2bdda3176f61e4ab634;hb=95ac4886d1b6649d54daffa7191be1b2bbaf2989;hpb=aca3c37006a1198a76e5ead8e29a7534f94f2569 diff --git a/registryd/registry.c b/registryd/registry.c index 506843d..51aaa4d 100644 --- a/registryd/registry.c +++ b/registryd/registry.c @@ -2,7 +2,9 @@ * AT-SPI - Assistive Technology Service Provider Interface * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap) * - * Copyright 2001 Sun Microsystems Inc. + * Copyright 2008, Codethink Ltd. + * 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 @@ -20,311 +22,263 @@ * Boston, MA 02111-1307, USA. */ -/* - * registry.c: test for accessibility implementation - * - */ - -#ifdef SPI_DEBUG -#include -#endif #include -#include +#include +#include -/* - * This pulls the CORBA definitions for the "Accessibility::Registry" server - */ -#include - -/* - * This pulls the definition for the BonoboObject (GType) - */ #include "registry.h" -/* - * Our parent GObject type - */ -#define PARENT_TYPE LISTENER_TYPE - -/* - * A pointer to our parent object class - */ -static ListenerClass *registry_parent_class; - -/* - * Implemented GObject::finalize - */ -static void -registry_object_finalize (GObject *object) +enum { -/* Registry *registry = REGISTRY (object); */ - GObjectClass *object_class = G_OBJECT_GET_CLASS( object); + REGISTRY_APPLICATION_REMOVE = 0, + REGISTRY_APPLICATION_ADD = 1 +}; - printf("registry_object_finalize called\n"); +/*---------------------------------------------------------------------------*/ - object_class->finalize (object); -} +G_DEFINE_TYPE(SpiRegistry, spi_registry, G_TYPE_OBJECT) -/** - * registerApplication: - * @application: a reference to the requesting @Application - * return values: 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) +spi_registry_class_init (SpiRegistryClass *klass) { - Registry *registry = REGISTRY (bonobo_object_from_servant (servant)); - -#ifdef SPI_DEBUG - fprintf (stderr, "registering app %p\n", application); -#endif - - registry->desktop->applications = g_list_append (registry->desktop->applications, CORBA_Object_duplicate (application, ev)); - /* - * TODO: change the implementation below to a WM-aware one; - * e.g. don't add all apps to the Desktop - */ - /* registry->desktop->applications = registry->applications;*/ -} + GObjectClass * object_class = (GObjectClass *) klass; -/** - * deregisterApplication: - * @application: a reference to the @Application - * to be deregistered. - * return values: void - * - * 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) -{ - Registry *registry = REGISTRY (bonobo_object_from_servant (servant)); - registry->applications = g_list_remove (registry->applications, application); + spi_registry_parent_class = g_type_class_ref (G_TYPE_OBJECT); } -/* - * 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) +spi_registry_init (SpiRegistry *registry) { - /** - * TODO: - * - * distinguish between event types - * register with app toolkits only for requested event types - * maintain list of requested types and number of listeners - * find non-strcmp method of matching event types to listeners - * - **/ - - Registry *registry = REGISTRY (bonobo_object_from_servant (servant)); - /* fprintf(stderr, "registering %x/%x\n", listener, *listener); */ - registry->listeners = g_list_append (registry->listeners, CORBA_Object_duplicate(listener, ev)); - /* fprintf(stderr, "there are now %d listeners registered.\n", g_list_length(registry->listeners)); */ - /* should use hashtable and CORBA_Object_hash (...) */ + registry->apps = g_sequence_new (g_free); } -/* - * CORBA Accessibility::Registry::deregisterGlobalEventListener method implementation - */ -static void -impl_accessibility_registry_deregister_global_event_listener - (PortableServer_Servant servant, - Accessibility_EventListener listener, - CORBA_Environment *ev) +/*---------------------------------------------------------------------------*/ + +static void emit(SpiRegistry *reg, const char *itf, const char *name, int ftype, ...) { - Registry *registry = REGISTRY (bonobo_object_from_servant (servant)); - /* TODO: this won't work since 'listener' is a duplicate ref */ - registry->listeners = g_list_remove (registry->listeners, listener); - /* fprintf(stderr, "deregister\n"); */ + va_list arg; + + va_start(arg, ftype); + spi_dbus_emit_valist(reg->bus, SPI_DBUS_PATH_DEC, itf, name, ftype, arg); + va_end(arg); } +/*---------------------------------------------------------------------------*/ -/** - * getDesktopCount: - * return values: a short integer indicating the current number of - * @Desktops. - * - * Get the current number of desktops. - * - **/ -static short -impl_accessibility_registry_get_desktop_count (PortableServer_Servant servant, - CORBA_Environment * ev) +static gint +data_str_cmp (gpointer a, gpointer b, gpointer data) { - /* TODO: implement support for multiple virtual desktops */ - CORBA_short n_desktops; - n_desktops = (CORBA_short) 1; - return n_desktops; + return g_strcmp0(a, b); } -/** - * getDesktop: - * @n: the index of the requested @Desktop. - * return values: a reference to the requested @Desktop. - * - * Get the nth accessible desktop. - * - **/ -static Accessibility_Desktop -impl_accessibility_registry_get_desktop (PortableServer_Servant servant, - const CORBA_short n, - CORBA_Environment * ev) +static gboolean +seq_add_string (GSequence *seq, gchar *str) { - Registry *registry = REGISTRY (bonobo_object_from_servant (servant)); + GSequenceIter *iter; + gchar *item; + gboolean res = FALSE; + + iter = g_sequence_search (seq, str, (GCompareDataFunc) data_str_cmp, NULL); + iter = g_sequence_iter_prev (iter); - /* TODO: implement support for multiple virtual desktops */ - if (n == 0) + if (!g_sequence_iter_is_end (iter)) { - return (Accessibility_Desktop) - CORBA_Object_duplicate ( - bonobo_object_corba_objref (bonobo_object (registry->desktop)), ev); + item = g_sequence_get (iter); + if (g_strcmp0 (item, str)) + { + g_sequence_insert_sorted (seq, g_strdup(str), (GCompareDataFunc) data_str_cmp, NULL); + res = TRUE; + } } else { - return (Accessibility_Desktop) CORBA_OBJECT_NIL; + g_sequence_insert_sorted (seq, g_strdup(str), (GCompareDataFunc) data_str_cmp, NULL); + res = TRUE; } + + return res; } -/** - * getDesktopList: - * return values: a sequence containing references to - * the @Desktops. - * - * Get a list of accessible desktops. - * - **/ -static Accessibility_DesktopSeq * -impl_accessibility_registry_get_desktop_list (PortableServer_Servant servant, - CORBA_Environment * ev) +static gboolean +seq_remove_string (GSequence *seq, gchar *str) { - /* TODO: implement support for multiple virtual desktops */ - return (Accessibility_DesktopSeq *) NULL; + 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; } -static CORBA_Object -impl_accessibility_registry_get_device_event_controller (PortableServer_Servant servant, - CORBA_Environment * ev) +static void +add_application (DBusConnection *bus, SpiRegistry *reg, gchar *app) { - /* TODO: not yet implemented! */ - return CORBA_OBJECT_NIL; + guint add = REGISTRY_APPLICATION_ADD; + + if (seq_add_string (reg->apps, app)) + { + emit (reg, + SPI_DBUS_INTERFACE_REGISTRY, + "updateApplications", + DBUS_TYPE_INT32, + &add, + DBUS_TYPE_STRING, + &app, + DBUS_TYPE_INVALID); + } } static void -impl_registry_notify_event (PortableServer_Servant servant, - const Accessibility_Event *e, - CORBA_Environment *ev) +remove_application (DBusConnection *bus, SpiRegistry *reg, gchar *app) { - int n; - int len; - Registry *registry = REGISTRY (bonobo_object_from_servant (servant)); - - /** - * TODO: - * - * distinguish between event types - * find non-strcmp method of matching event types to listeners - * - **/ - - len = g_list_length (registry->listeners); - /* fprintf(stderr, "%d listeners registered\n", len); */ - - for (n=0; napps, app)) { -#ifdef SPI_DEBUG - fprintf(stderr, "notifying listener #%d\n", n); - fprintf(stderr, "event name %s\n", Accessibility_Accessible__get_name(e->target, ev)); -#endif - Accessibility_EventListener_notifyEvent ( - (Accessibility_EventListener) g_list_nth_data (registry->listeners, n), - e, - ev); + /*TODO spi_remove_device_listeners (registry->de_controller, old);*/ + emit (reg, + SPI_DBUS_INTERFACE_REGISTRY, + "updateApplications", + DBUS_TYPE_INT32, + &remove, + DBUS_TYPE_STRING, + &app, + DBUS_TYPE_INVALID); } } +/*---------------------------------------------------------------------------*/ + +static void +add_bus_name_cb (gpointer item, gpointer data) +{ + DBusMessageIter *iter_array = (DBusMessageIter *) data; + + dbus_message_iter_append_basic (iter_array, DBUS_TYPE_STRING, (gchar **) &item); +} + +static DBusMessage * +impl_getApplications (DBusConnection *bus, DBusMessage *message, void *user_data) +{ + DBusMessage *reply; + DBusMessageIter iter, iter_array; + SpiRegistry *reg = SPI_REGISTRY (user_data); + + reply = 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; +} + +/*---------------------------------------------------------------------------*/ + static void -registry_class_init (RegistryClass *klass) +impl_registerApplication (DBusConnection *bus, DBusMessage *message, void *user_data) { - GObjectClass * object_class = (GObjectClass *) klass; - POA_Accessibility_Registry__epv *epv = &klass->epv; - - registry_parent_class = g_type_class_ref (LISTENER_TYPE); - - object_class->finalize = registry_object_finalize; - - 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->getDesktopCount = impl_accessibility_registry_get_desktop_count; - epv->getDesktop = impl_accessibility_registry_get_desktop; - epv->getDesktopList = impl_accessibility_registry_get_desktop_list; - epv->getDeviceEventController = impl_accessibility_registry_get_device_event_controller; - ((ListenerClass *) klass)->epv.notifyEvent = impl_registry_notify_event; + gchar *app_name; + SpiRegistry *reg = SPI_REGISTRY (user_data); + + if (dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &app_name, DBUS_TYPE_INVALID)) + add_application(bus, reg, app_name); } static void -registry_init (Registry *registry) +impl_deregisterApplication (DBusConnection *bus, DBusMessage *message, void *user_data) { - registry->listeners = NULL; - registry->applications = NULL; - registry->desktop = desktop_new(); + gchar *app_name; + SpiRegistry *reg = SPI_REGISTRY (user_data); + + if (dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &app_name, DBUS_TYPE_INVALID)) + remove_application(bus, reg, app_name); } -GType -registry_get_type (void) +/*---------------------------------------------------------------------------*/ + +static void +handle_disconnection (DBusConnection *bus, DBusMessage *message, void *user_data) { - static GType type = 0; - - if (!type) { - static const GTypeInfo tinfo = { - sizeof (RegistryClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) registry_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class data */ - sizeof (Registry), - 0, /* n preallocs */ - (GInstanceInitFunc) registry_init, - NULL /* value table */ - }; - /* - * Here we use bonobo_x_type_unique instead of - * gtk_type_unique, this auto-generates a load of - * CORBA structures for us. All derived types must - * use bonobo_x_type_unique. - */ - type = bonobo_x_type_unique ( - PARENT_TYPE, - POA_Accessibility_Registry__init, - NULL, - G_STRUCT_OFFSET (RegistryClass, epv), - &tinfo, - "Registry"); + char *name, *old, *new; + SpiRegistry *reg = SPI_REGISTRY (user_data); + + if (dbus_message_get_args (message, NULL, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &old, + DBUS_TYPE_STRING, &new, + DBUS_TYPE_INVALID)) + { + if (*old != '\0' && *new == '\0') + { + remove_application(bus, reg, old); } + } +} + +/*---------------------------------------------------------------------------*/ - return type; +static DBusHandlerResult +signal_filter (DBusConnection *bus, DBusMessage *message, void *user_data) +{ + 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); + + if (!g_strcmp0(iface, DBUS_INTERFACE_DBUS) && !g_strcmp0(member, "NameOwnerChanged")) + handle_disconnection (bus, message, user_data); + else + res = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + return res; } -Registry * -registry_new (void) +/*---------------------------------------------------------------------------*/ + +static gchar *app_sig_match_name_owner = + "type='signal', interface='org.freedesktop.DBus', member='NameOwnerChanged'"; + +static DRouteMethod dev_methods[] = { - Registry *retval = - REGISTRY (g_object_new (registry_get_type (), NULL)); - return retval; + { impl_getApplications, "getApplications" }, + { impl_registerApplication, "registerApplication" }, + { impl_deregisterApplication, "deregisterApplication" }, + { NULL, NULL } +}; + +SpiRegistry * +spi_registry_new (DBusConnection *bus, DRouteContext *droute) +{ + SpiRegistry *reg = g_object_new (SPI_REGISTRY_TYPE, NULL); + DRoutePath *path; + + reg->bus = bus; + + dbus_bus_add_match (bus, app_sig_match_name_owner, NULL); + dbus_connection_add_filter (bus, signal_filter, reg, NULL); + + path = droute_add_one (droute, + SPI_DBUS_PATH_REGISTRY, + reg); + + droute_path_add_interface (path, + SPI_DBUS_INTERFACE_DEC, + dev_methods, + NULL); + + return reg; } + +/*END------------------------------------------------------------------------*/