X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=libspi%2Fregistry.c;h=a8b318cdec848a3a30a22ca71f0816bb420edbfb;hb=7e6b190892ea47bb90da75abcab856436a7ac222;hp=ff794f8fa6be275cd077026129c4cde85a259f51;hpb=d0405018df7bc391ef2988f03dcc836c9d563a55;p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git diff --git a/libspi/registry.c b/libspi/registry.c index ff794f8..a8b318c 100644 --- a/libspi/registry.c +++ b/libspi/registry.c @@ -56,10 +56,12 @@ typedef enum { ETYPE_WINDOW, ETYPE_TOOLKIT, ETYPE_LAST_DEFINED -} EventTypeMajor; +} EventTypeCategory; typedef struct { - EventTypeMajor major; + char *event_name; + EventTypeCategory type_cat; + char * major; char * minor; char * detail; guint hash; @@ -68,13 +70,16 @@ typedef struct { typedef struct { Accessibility_EventListener listener; guint event_type_hash; + EventTypeCategory event_type_cat; } ListenerStruct; /* static function prototypes */ -static void registry_notify_listeners ( GList *listeners, +static void _registry_notify_listeners ( GList *listeners, const Accessibility_Event *e, CORBA_Environment *ev); +static long _get_unique_id(); + /* * Implemented GObject::finalize */ @@ -107,12 +112,11 @@ impl_accessibility_registry_register_application (PortableServer_Servant servant #ifdef SPI_DEBUG fprintf (stderr, "registering app %p\n", application); #endif - ORBit_register_objref (application); registry->desktop->applications = g_list_append (registry->desktop->applications, CORBA_Object_duplicate (application, ev)); - /* TODO: create unique string here (with libuuid call ?) */ - Accessibility_Application__set_id (application, "test-some-unique-string", ev); + /* TODO: create unique string here (with libuuid call ?) and hash ? */ + Accessibility_Application__set_id (application, _get_unique_id(), ev); /* * TODO: change the implementation below to a WM-aware one; @@ -129,6 +133,39 @@ compare_object_hash (gconstpointer p1, gconstpointer p2) return ((diff < 0) ? -1 : ((diff > 0) ? 1 : 0)); } +static void +register_with_toolkits (Registry *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_object_corba_objref (bonobo_object (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); + } + } +} + static gint compare_listener_hash (gconstpointer p1, gconstpointer p2) { @@ -138,56 +175,56 @@ compare_listener_hash (gconstpointer p1, gconstpointer p2) static void parse_event_type (EventTypeStruct *etype, char *event_name) { - static gunichar delimiter = 0; - char * major_delim_char; - char * minor_delim_char; guint nbytes = 0; + gchar **split_string; - if (!delimiter) - { - delimiter = g_utf8_get_char (":"); - } - - major_delim_char = g_utf8_strchr (event_name, (gssize) 32, delimiter); - minor_delim_char = g_utf8_strrchr (event_name, (gssize) 255, delimiter); + split_string = g_strsplit(event_name, ":", 4); + etype->event_name = g_strndup(event_name, 255); - nbytes = (guint)((gint64) minor_delim_char - - (gint64) major_delim_char); - - fprintf (stderr, "nbytes = %ld\n", (long) nbytes); if (!g_ascii_strncasecmp (event_name, "focus:", 6)) { - etype->major = ETYPE_FOCUS; + etype->type_cat = ETYPE_FOCUS; } else if (!g_ascii_strncasecmp (event_name, "window:", 7)) { - etype->major = ETYPE_WINDOW; + etype->type_cat = ETYPE_WINDOW; } else { - etype->major = ETYPE_TOOLKIT; + etype->type_cat = ETYPE_TOOLKIT; } - if (major_delim_char) + if (split_string[1]) { - etype->minor = g_strndup (major_delim_char, nbytes); - etype->hash = g_str_hash (major_delim_char); + etype->major = split_string[1]; + if (split_string[2]) + { + etype->minor = split_string[2]; + if (split_string[3]) + { + etype->detail = split_string[3]; + etype->hash = g_str_hash ( g_strconcat (split_string[1], split_string[2], split_string[3], NULL)); + } + else + { + etype->detail = g_strdup (""); + etype->hash = g_str_hash ( g_strconcat (split_string[1], split_string[2], NULL)); + } + } + else + { + etype->minor = g_strdup (""); + etype->hash = g_str_hash ( split_string[1]); + } } else { + etype->major = g_strdup (""); etype->minor = g_strdup (""); - etype->hash = g_str_hash (""); - } - if (major_delim_char != minor_delim_char) - { - etype->detail = g_strdup (minor_delim_char); - } - else - { etype->detail = g_strdup (""); + etype->hash = g_str_hash (""); } - /* TODO: don't forget to free the strings from caller when done ! */ } @@ -224,26 +261,18 @@ impl_accessibility_registry_register_global_event_listener const CORBA_char *event_name, CORBA_Environment *ev) { - /** - * 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); */ ListenerStruct *ls = g_malloc (sizeof (ListenerStruct)); - EventTypeStruct etype; + + fprintf(stderr, "registering for events of type %s\n", event_name); + + /* parse, check major event type and add listener accordingly */ parse_event_type (&etype, event_name); ls->event_type_hash = etype.hash; + ls->event_type_cat = etype.type_cat; - /* parse, check major event type and add listener accordingly */ - switch (etype.major) + switch (etype.type_cat) { case (ETYPE_FOCUS) : ls->listener = CORBA_Object_duplicate (listener, ev); @@ -251,8 +280,13 @@ impl_accessibility_registry_register_global_event_listener g_list_append (registry->focus_listeners, ls); break; case (ETYPE_WINDOW) : + /* Support for Window Manager Events is not yet implemented */ break; case (ETYPE_TOOLKIT) : + ls->listener = CORBA_Object_duplicate (listener, ev); + registry->toolkit_listeners = + g_list_append (registry->toolkit_listeners, ls); + register_with_toolkits (registry, &etype, ev); break; default: break; @@ -270,12 +304,25 @@ impl_accessibility_registry_deregister_global_event_listener_all { Registry *registry = REGISTRY (bonobo_object_from_servant (servant)); GList *list = g_list_find_custom (registry->focus_listeners, listener, compare_object_hash); + + /* + * TODO : de-register with toolkit if the last instance of a listener + * to a particular toolkit event type has been deregistered. + */ + while (list) { fprintf (stderr, "deregistering listener\n"); registry->focus_listeners = g_list_delete_link (registry->focus_listeners, list); list = g_list_find_custom (registry->focus_listeners, listener, compare_object_hash); } + list = g_list_find_custom (registry->toolkit_listeners, listener, compare_object_hash); + while (list) + { + fprintf (stderr, "deregistering listener\n"); + registry->toolkit_listeners = g_list_delete_link (registry->toolkit_listeners, list); + list = g_list_find_custom (registry->toolkit_listeners, listener, compare_object_hash); + } } /* @@ -292,14 +339,32 @@ impl_accessibility_registry_deregister_global_event_listener ListenerStruct ls; EventTypeStruct etype; GList *list; + GList **listeners; + parse_event_type (&etype, event_name); + switch (etype.type_cat) + { + case (ETYPE_FOCUS) : + listeners = ®istry->focus_listeners; + break; + case (ETYPE_WINDOW) : + /* Support for Window Manager Events is not yet implemented */ + break; + case (ETYPE_TOOLKIT) : + listeners = ®istry->toolkit_listeners; + break; + default: + break; + } + ls.event_type_hash = etype.hash; - list = g_list_find_custom (registry->focus_listeners, &ls, compare_listener_hash); + list = g_list_find_custom (*listeners, &ls, compare_listener_hash); - if (list) + while (list) { fprintf (stderr, "deregistering listener\n"); - registry->applications = g_list_delete_link (registry->focus_listeners, list); + *listeners = g_list_delete_link (*listeners, list); + list = g_list_find_custom (*listeners, &ls, compare_listener_hash); } } @@ -384,25 +449,32 @@ impl_registry_notify_event (PortableServer_Servant servant, parse_event_type (&etype, e->type); - switch (etype.major) + switch (etype.type_cat) { case (ETYPE_FOCUS) : - registry_notify_listeners (registry->focus_listeners, e, ev); + _registry_notify_listeners (registry->focus_listeners, e, ev); break; case (ETYPE_WINDOW) : - registry_notify_listeners (registry->window_listeners, e, ev); + _registry_notify_listeners (registry->window_listeners, e, ev); break; case (ETYPE_TOOLKIT) : - registry_notify_listeners (registry->toolkit_listeners, e, ev); + _registry_notify_listeners (registry->toolkit_listeners, e, ev); break; default: break; } - Accessibility_Accessible_unref (e->target, ev); + bonobo_object_release_unref (e->source, ev); +} + +static long +_get_unique_id () +{ + static long id = 0; + return ++id; } static void -registry_notify_listeners ( GList *listeners, +_registry_notify_listeners ( GList *listeners, const Accessibility_Event *e, CORBA_Environment *ev) { @@ -412,22 +484,23 @@ registry_notify_listeners ( GList *listeners, EventTypeStruct etype; guint minor_hash; parse_event_type (&etype, e->type); - minor_hash = g_str_hash (etype.minor); + minor_hash = g_str_hash (g_strconcat (etype.major, etype.minor, NULL)); len = g_list_length (listeners); for (n=0; nevent_type_hash, etype.hash); + fprintf(stderr, "event hashes: %lx %lx %lx\n", ls->event_type_hash, etype.hash, minor_hash); + fprintf(stderr, "event name: %s\n", etype.event_name); #endif if ((ls->event_type_hash == etype.hash) || (ls->event_type_hash == minor_hash)) { #ifdef SPI_DEBUG fprintf(stderr, "notifying listener #%d\n", n); - fprintf(stderr, "event name %s\n", Accessibility_Accessible__get_name(e->target, ev)); + fprintf(stderr, "event name %s\n", Accessibility_Accessible__get_name(e->source, ev)); #endif - Accessibility_Accessible_ref (e->target, ev); + bonobo_object_dup_ref ( e->source, ev); Accessibility_EventListener_notifyEvent ((Accessibility_EventListener) ls->listener, e, ev);