Toolkit events are now correctly registered for and dispatched
authorbillh <billh@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Fri, 17 Aug 2001 16:36:35 +0000 (16:36 +0000)
committerbillh <billh@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Fri, 17 Aug 2001 16:36:35 +0000 (16:36 +0000)
to listening at clients.

git-svn-id: http://svn.gnome.org/svn/at-spi/trunk@33 e2bd861d-eb25-0410-b326-f6ed22b6b98c

ChangeLog
at-bridge/bridge.c
atk-bridge/bridge.c
idl/Accessibility_Application.idl
idl/Application.idl
libspi/application.c
libspi/listener.c
libspi/registry.c
registryd/registry.c
test/at.c

index 15339b9..f8b973d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2001-08-17  Bill Haneman <bill.haneman@sun.com>
+       * libspi/registry.c :
+       * libspi/application.c :
+       * idl/Application.idl :
+       Made registration with toolkit an application method,
+       which is required since each app has its own toolkit static
+       environment.  Thus the bridge must register for 
+       notification of toolkit events from each application in turn.
+       Toolkit notifications are now successfully registered for, and
+       sent to the listening at client.
+       * test/at.c :
+       Changed toolkit event string to use hyphens rather than underscores.
+       * libspi/listener.c :
+       listner now gives more info in debug mode - it reports the
+       name of the event received, as well as the name of the source.
+       
+
 2001-08-16  Bill Haneman <bill.haneman@sun.com>
 
        * libspi/registry.c :
index 04545a9..9da60d4 100644 (file)
@@ -112,3 +112,8 @@ static void bridge_focus_tracker (AtkObject *object)
   e->detail2 = 0;
   Accessibility_Registry_notifyEvent (registry, e, &ev);
 }
+
+static Accessibility_Registry bridge_get_registry ()
+{
+  return registry;
+}
index 04545a9..9da60d4 100644 (file)
@@ -112,3 +112,8 @@ static void bridge_focus_tracker (AtkObject *object)
   e->detail2 = 0;
   Accessibility_Registry_notifyEvent (registry, e, &ev);
 }
+
+static Accessibility_Registry bridge_get_registry ()
+{
+  return registry;
+}
index 6ecd658..033b24d 100644 (file)
@@ -51,6 +51,12 @@ module Accessibility {
     attribute string id;
 
     /**
+     * Register with this application's toolkit for "toolkit" event notifications.
+     *
+     **/
+    void registerToolkitEventListener (in EventListener listener, in string eventName);
+
+    /**
      * pause:
      * Returns: %true if the request succeeded, %false otherwise.
      *
index 6ecd658..033b24d 100644 (file)
@@ -51,6 +51,12 @@ module Accessibility {
     attribute string id;
 
     /**
+     * Register with this application's toolkit for "toolkit" event notifications.
+     *
+     **/
+    void registerToolkitEventListener (in EventListener listener, in string eventName);
+
+    /**
      * pause:
      * Returns: %true if the request succeeded, %false otherwise.
      *
index 99746d4..c305ae4 100644 (file)
@@ -48,6 +48,8 @@
  */
 static AccessibleClass *application_parent_class;
 
+Accessibility_EventListener the_toolkit_listener;
+
 /*
  * Implemented GObject::finalize
  */
@@ -102,6 +104,62 @@ impl_accessibility_application_set_id (PortableServer_Servant servant,
   application->id = id;
 }
 
+#define APP_STATIC_BUFF_SZ 64
+
+static gboolean
+application_toolkit_listener (GSignalInvocationHint *signal_hint,
+                              guint n_param_values,
+                              const GValue *param_values,
+                              gpointer data)
+{
+  Accessibility_Event *e = g_new0(Accessibility_Event, 1);
+  AtkObject *aobject;
+  GObject *gobject;
+  CORBA_Environment ev;
+  GSignalQuery signal_query;
+  gchar *name;
+  char sbuf[APP_STATIC_BUFF_SZ];
+
+  g_signal_query (signal_hint->signal_id, &signal_query);
+  name = signal_query.signal_name;
+  fprintf (stderr, "Received signal %s:%s\n", g_type_name (signal_query.itype), name);
+
+  /* TODO: move GTK dependency out of app.c into bridge */
+  snprintf(sbuf, APP_STATIC_BUFF_SZ, "Gtk:%s:%s", g_type_name (signal_query.itype), name);
+
+
+  gobject = g_value_get_object (param_values + 0);
+  /* notify the actual listeners */
+  if (ATK_IS_IMPLEMENTOR (gobject))
+    {
+      aobject = atk_implementor_ref_accessible (ATK_IMPLEMENTOR (gobject));
+      e->type = CORBA_string_dup (sbuf);
+      e->target = bonobo_object_corba_objref (bonobo_object (accessible_new (aobject)));
+      e->detail1 = 0;
+      e->detail2 = 0;
+      Accessibility_EventListener_notifyEvent (the_toolkit_listener, e, &ev);
+      g_object_unref (aobject);
+    }
+  return TRUE;
+}
+
+static void
+impl_accessibility_application_register_toolkit_event_listener (PortableServer_Servant servant,
+                                                                Accessibility_EventListener listener,
+                                                                const CORBA_char *event_name,
+                                                                CORBA_Environment *ev)
+{
+  guint listener_id;
+  listener_id =
+     atk_add_global_event_listener (application_toolkit_listener, event_name);
+  the_toolkit_listener = CORBA_Object_duplicate (listener, ev);
+#ifdef SPI_DEBUG
+  fprintf (stderr, "registered %d for toolkit events named: %s\n",
+           listener_id,
+           event_name);
+#endif
+}
+
 static void
 application_class_init (ApplicationClass *klass)
 {
@@ -116,6 +174,7 @@ application_class_init (ApplicationClass *klass)
   epv->_get_version = impl_accessibility_application_get_version;
   epv->_get_id = impl_accessibility_application_get_id;
   epv->_set_id = impl_accessibility_application_set_id;
+  epv->registerToolkitEventListener = impl_accessibility_application_register_toolkit_event_listener;
 }
 
 static void
index 8ab2c80..d6d6efc 100644 (file)
@@ -72,7 +72,7 @@ impl_notify_event (PortableServer_Servant     servant,
                    CORBA_Environment         *ev)
 {
 #ifdef SPI_DEBUG
-  fprintf (stderr, "notify...\n");
+  fprintf (stderr, "notify %s...\n", e->type);
   fprintf (stderr, "source name: '%s'\n",
            Accessibility_Accessible__get_name(e->target, ev));
   if (ev->_major != CORBA_NO_EXCEPTION) {
index 0cca46a..e7dbf3e 100644 (file)
@@ -56,11 +56,12 @@ typedef enum {
   ETYPE_WINDOW,
   ETYPE_TOOLKIT,
   ETYPE_LAST_DEFINED
-} EventTypeMajor;
+} EventTypeCategory;
 
 typedef struct {
   char *event_name;
-  EventTypeMajor major;
+  EventTypeCategory type_cat;
+  char * major;
   char * minor;
   char * detail;
   guint hash;
@@ -69,7 +70,7 @@ typedef struct {
 typedef struct {
   Accessibility_EventListener listener;
   guint event_type_hash;
-  EventTypeMajor event_type_major;
+  EventTypeCategory event_type_cat;
 } ListenerStruct;
 
 /* static function prototypes */
@@ -130,32 +131,36 @@ compare_object_hash (gconstpointer p1, gconstpointer p2)
   return ((diff < 0) ? -1 : ((diff > 0) ? 1 : 0));
 }
 
-static gboolean
-toolkit_listener (GSignalInvocationHint *signal_hint,
-                  guint n_param_values,
-                  const GValue *param_values,
-                  gpointer data)
+static void
+register_with_toolkits (Registry *registry_bonobo_object, EventTypeStruct *etype, CORBA_Environment *ev)
 {
-  gchar *name =
-    g_signal_name (signal_hint->signal_id);
-  fprintf (stderr, "Received signal %s\n", name);
+  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));
 
-  /* TODO: notify the actual listeners! */
+  /* for each app in each desktop, call bridge_register_toolkit_event */
 
-  return TRUE;
-}
+  n_desktops = Accessibility_Registry_getDesktopCount (registry, ev);
 
-static void
-register_with_toolkit (EventTypeStruct *etype)
-{
-  guint listener_id;
-  listener_id =
-     atk_add_global_event_listener (toolkit_listener, etype->event_name);
-#ifdef SPI_DEBUG
-  fprintf (stderr, "registered %d for toolkit events named: %s\n",
-           listener_id,
-           etype->event_name);
-#endif
+  for (i=0; i<n_desktops; ++i)
+    {
+      desktop = Accessibility_Registry_getDesktop (registry, i, ev);
+      n_apps = Accessibility_Desktop__get_childCount (desktop, ev);
+      for (j=0; j<n_apps; ++j)
+        {
+          app = (Accessibility_Application) Accessibility_Desktop_getChildAtIndex (desktop,
+                                                                                   j,
+                                                                                   ev);
+          Accessibility_Application_registerToolkitEventListener (app,
+                                                                  registry,
+                                                                  CORBA_string_dup (etype->event_name),
+                                                                  ev);
+        }
+    }
 }
 
 static gint
@@ -167,57 +172,54 @@ 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;
 
+  split_string = g_strsplit(event_name, ":", 4);
   etype->event_name = g_strndup(event_name, 255);
 
-  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);
-
-  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 != minor_delim_char)
-    {
-      etype->minor = g_strndup (major_delim_char, nbytes);
-      etype->detail = g_strdup (minor_delim_char);
-      etype->hash = g_str_hash (major_delim_char);
-    }
-  else
+  if (split_string[1])
     {
-      if (* (major_delim_char+1))
+      etype->major = split_string[1];
+      if (split_string[2])
         {
-          etype->minor = g_strdup (major_delim_char+1);
-          etype->hash = g_str_hash (major_delim_char+1);
+          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 ("");
+          etype->hash = g_str_hash ( split_string[1]);
         }
+    }
+  else
+    {
+      etype->major = g_strdup ("");
+      etype->minor = g_strdup ("");
       etype->detail = g_strdup ("");
+      etype->hash = g_str_hash ("");
     }
 
   /* TODO: don't forget to free the strings from caller when done ! */
@@ -256,25 +258,18 @@ impl_accessibility_registry_register_global_event_listener
                                              const CORBA_char *event_name,
                                              CORBA_Environment      *ev)
 {
-  /**
-   *  TODO:
-   *
-   *  register with app toolkits only for requested event types
-   *
-   **/
-
   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_major = etype.major;
+  ls->event_type_cat = etype.type_cat;
 
-  switch (etype.major)
+  switch (etype.type_cat)
     {
     case (ETYPE_FOCUS) :
       ls->listener = CORBA_Object_duplicate (listener, ev);
@@ -288,7 +283,7 @@ impl_accessibility_registry_register_global_event_listener
       ls->listener = CORBA_Object_duplicate (listener, ev);
       registry->toolkit_listeners =
         g_list_append (registry->toolkit_listeners, ls);
-      register_with_toolkit (&etype);
+      register_with_toolkits (registry, &etype, ev);
       break;
     default:
       break;
@@ -344,7 +339,7 @@ impl_accessibility_registry_deregister_global_event_listener
   GList **listeners;
 
   parse_event_type (&etype, event_name);
-  switch (etype.major)
+  switch (etype.type_cat)
     {
     case (ETYPE_FOCUS) :
       listeners = &registry->focus_listeners;
@@ -451,7 +446,7 @@ 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);
@@ -479,14 +474,15 @@ 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; n<len; ++n)
     {
       ls =  (ListenerStruct *) g_list_nth_data (listeners, n);
 #ifdef SPI_DEBUG
-      fprintf(stderr, "event hashes: %lx %lx\n", ls->event_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))
         {
index 0cca46a..e7dbf3e 100644 (file)
@@ -56,11 +56,12 @@ typedef enum {
   ETYPE_WINDOW,
   ETYPE_TOOLKIT,
   ETYPE_LAST_DEFINED
-} EventTypeMajor;
+} EventTypeCategory;
 
 typedef struct {
   char *event_name;
-  EventTypeMajor major;
+  EventTypeCategory type_cat;
+  char * major;
   char * minor;
   char * detail;
   guint hash;
@@ -69,7 +70,7 @@ typedef struct {
 typedef struct {
   Accessibility_EventListener listener;
   guint event_type_hash;
-  EventTypeMajor event_type_major;
+  EventTypeCategory event_type_cat;
 } ListenerStruct;
 
 /* static function prototypes */
@@ -130,32 +131,36 @@ compare_object_hash (gconstpointer p1, gconstpointer p2)
   return ((diff < 0) ? -1 : ((diff > 0) ? 1 : 0));
 }
 
-static gboolean
-toolkit_listener (GSignalInvocationHint *signal_hint,
-                  guint n_param_values,
-                  const GValue *param_values,
-                  gpointer data)
+static void
+register_with_toolkits (Registry *registry_bonobo_object, EventTypeStruct *etype, CORBA_Environment *ev)
 {
-  gchar *name =
-    g_signal_name (signal_hint->signal_id);
-  fprintf (stderr, "Received signal %s\n", name);
+  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));
 
-  /* TODO: notify the actual listeners! */
+  /* for each app in each desktop, call bridge_register_toolkit_event */
 
-  return TRUE;
-}
+  n_desktops = Accessibility_Registry_getDesktopCount (registry, ev);
 
-static void
-register_with_toolkit (EventTypeStruct *etype)
-{
-  guint listener_id;
-  listener_id =
-     atk_add_global_event_listener (toolkit_listener, etype->event_name);
-#ifdef SPI_DEBUG
-  fprintf (stderr, "registered %d for toolkit events named: %s\n",
-           listener_id,
-           etype->event_name);
-#endif
+  for (i=0; i<n_desktops; ++i)
+    {
+      desktop = Accessibility_Registry_getDesktop (registry, i, ev);
+      n_apps = Accessibility_Desktop__get_childCount (desktop, ev);
+      for (j=0; j<n_apps; ++j)
+        {
+          app = (Accessibility_Application) Accessibility_Desktop_getChildAtIndex (desktop,
+                                                                                   j,
+                                                                                   ev);
+          Accessibility_Application_registerToolkitEventListener (app,
+                                                                  registry,
+                                                                  CORBA_string_dup (etype->event_name),
+                                                                  ev);
+        }
+    }
 }
 
 static gint
@@ -167,57 +172,54 @@ 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;
 
+  split_string = g_strsplit(event_name, ":", 4);
   etype->event_name = g_strndup(event_name, 255);
 
-  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);
-
-  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 != minor_delim_char)
-    {
-      etype->minor = g_strndup (major_delim_char, nbytes);
-      etype->detail = g_strdup (minor_delim_char);
-      etype->hash = g_str_hash (major_delim_char);
-    }
-  else
+  if (split_string[1])
     {
-      if (* (major_delim_char+1))
+      etype->major = split_string[1];
+      if (split_string[2])
         {
-          etype->minor = g_strdup (major_delim_char+1);
-          etype->hash = g_str_hash (major_delim_char+1);
+          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 ("");
+          etype->hash = g_str_hash ( split_string[1]);
         }
+    }
+  else
+    {
+      etype->major = g_strdup ("");
+      etype->minor = g_strdup ("");
       etype->detail = g_strdup ("");
+      etype->hash = g_str_hash ("");
     }
 
   /* TODO: don't forget to free the strings from caller when done ! */
@@ -256,25 +258,18 @@ impl_accessibility_registry_register_global_event_listener
                                              const CORBA_char *event_name,
                                              CORBA_Environment      *ev)
 {
-  /**
-   *  TODO:
-   *
-   *  register with app toolkits only for requested event types
-   *
-   **/
-
   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_major = etype.major;
+  ls->event_type_cat = etype.type_cat;
 
-  switch (etype.major)
+  switch (etype.type_cat)
     {
     case (ETYPE_FOCUS) :
       ls->listener = CORBA_Object_duplicate (listener, ev);
@@ -288,7 +283,7 @@ impl_accessibility_registry_register_global_event_listener
       ls->listener = CORBA_Object_duplicate (listener, ev);
       registry->toolkit_listeners =
         g_list_append (registry->toolkit_listeners, ls);
-      register_with_toolkit (&etype);
+      register_with_toolkits (registry, &etype, ev);
       break;
     default:
       break;
@@ -344,7 +339,7 @@ impl_accessibility_registry_deregister_global_event_listener
   GList **listeners;
 
   parse_event_type (&etype, event_name);
-  switch (etype.major)
+  switch (etype.type_cat)
     {
     case (ETYPE_FOCUS) :
       listeners = &registry->focus_listeners;
@@ -451,7 +446,7 @@ 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);
@@ -479,14 +474,15 @@ 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; n<len; ++n)
     {
       ls =  (ListenerStruct *) g_list_nth_data (listeners, n);
 #ifdef SPI_DEBUG
-      fprintf(stderr, "event hashes: %lx %lx\n", ls->event_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))
         {
index b0aa7ab..5a57be6 100644 (file)
--- a/test/at.c
+++ b/test/at.c
@@ -96,7 +96,7 @@ main(int argc, char **argv)
                                    (registry,
                                     (Accessibility_EventListener)
                                          bonobo_object_corba_objref (bonobo_object (listener)),
-                                    "Gtk:GtkWidget:button_press_event",
+                                    "Gtk:GtkWidget:button-press-event",
                                     &ev);
         check_ev (&ev, "register:button_press");
         fprintf (stderr, "AT callback registered.\n");