2002-08-12 Michael Meeks <michael@ximian.com>
[platform/core/uifw/at-spi2-atk.git] / atk-bridge / bridge.c
index 96f64fc..cb46eaa 100644 (file)
 #undef SPI_BRIDGE_DEBUG
 
 static CORBA_Environment ev;
-static Accessibility_Registry registry;
+static Accessibility_Registry registry = NULL;
 static SpiApplication *this_app = NULL;
+static gboolean registry_died = FALSE;
 
+static Accessibility_Registry spi_atk_bridge_get_registry (void);
 static void     spi_atk_bridge_exit_func               (void);
 static void     spi_atk_register_event_listeners       (void);
-static gboolean spi_atk_bridge_idle_init               (gpointer               user_data);
 static void     spi_atk_bridge_focus_tracker           (AtkObject             *object);
+static void     spi_atk_bridge_register_application    (Accessibility_Registry registry);
 static gboolean spi_atk_bridge_property_event_listener (GSignalInvocationHint *signal_hint,
                                                        guint                  n_param_values,
                                                        const GValue          *param_values,
@@ -53,6 +55,11 @@ spi_atk_bridge_window_event_listener (GSignalInvocationHint *signal_hint,
                                guint n_param_values,
                                const GValue *param_values,
                                gpointer data);
+static gboolean
+spi_atk_bridge_state_event_listener (GSignalInvocationHint *signal_hint,
+                                    guint n_param_values,
+                                    const GValue *param_values,
+                                    gpointer data);
 static gboolean spi_atk_bridge_signal_listener         (GSignalInvocationHint *signal_hint,
                                                        guint                  n_param_values,
                                                        const GValue          *param_values,
@@ -67,7 +74,6 @@ extern void gnome_accessibility_module_shutdown (void);
 static int     atk_bridge_initialized = FALSE;
 static guint   atk_bridge_focus_tracker_id = 0;
 static guint   atk_bridge_key_event_listener_id = 0;
-static guint   idle_init_id = 0;
 static GArray *listener_ids = NULL;
 
 /*
@@ -104,18 +110,7 @@ atk_bridge_init (gint *argc, gchar **argv[])
 
   CORBA_exception_init(&ev);
 
-  registry = bonobo_activation_activate_from_id (
-         "OAFIID:Accessibility_Registry:proto0.1", 0, NULL, &ev);
-  
-  if (ev._major != CORBA_NO_EXCEPTION)
-    {
-      g_error ("Accessibility app error: exception during "
-              "registry activation from id: %s\n",
-              CORBA_exception_id (&ev));
-      CORBA_exception_free (&ev);
-    }
-
-  if (registry == CORBA_OBJECT_NIL)
+  if (spi_atk_bridge_get_registry () == CORBA_OBJECT_NIL)
     {
       g_error ("Could not locate registry");
     }
@@ -128,33 +123,55 @@ atk_bridge_init (gint *argc, gchar **argv[])
 
   fprintf (stderr, "About to register application\n");
 
-  Accessibility_Registry_registerApplication (registry,
-                                              BONOBO_OBJREF (this_app),
-                                              &ev);
-
+  spi_atk_bridge_register_application (spi_atk_bridge_get_registry ());
+  
   g_atexit (spi_atk_bridge_exit_func);
 
-  idle_init_id = g_idle_add (spi_atk_bridge_idle_init, NULL);
+  fprintf (stderr, "Application registered & listening\n");
 
   return 0;
 }
 
-int
-gtk_module_init (gint *argc, gchar **argv[])
+static void
+spi_atk_bridge_register_application (Accessibility_Registry registry)
 {
-       return atk_bridge_init (argc, argv);
+  Accessibility_Registry_registerApplication (spi_atk_bridge_get_registry (),
+                                              BONOBO_OBJREF (this_app),
+                                              &ev);
+  spi_atk_register_event_listeners ();
 }
 
-static gboolean
-spi_atk_bridge_idle_init (gpointer user_data)
+static Accessibility_Registry
+spi_atk_bridge_get_registry ()
 {
-  idle_init_id = 0;
-
-  spi_atk_register_event_listeners ();
+  CORBA_Environment ev;
 
-  fprintf (stderr, "Application registered & listening\n");
+  if (registry_died || (registry == NULL)) {
+         CORBA_exception_init (&ev);
+         if (registry_died) g_warning ("registry died! restarting...");
+         registry = bonobo_activation_activate_from_id (
+                 "OAFIID:Accessibility_Registry:1.0", 0, NULL, &ev);
+         
+         if (ev._major != CORBA_NO_EXCEPTION)
+         {
+                 g_error ("Accessibility app error: exception during "
+                          "registry activation from id: %s\n",
+                          CORBA_exception_id (&ev));
+                 CORBA_exception_free (&ev);
+         }
+         
+         if (registry_died && registry) {
+                 registry_died = FALSE;
+                 spi_atk_bridge_register_application (registry);
+         }
+  }
+  return registry;
+}
 
-  return FALSE;
+int
+gtk_module_init (gint *argc, gchar **argv[])
+{
+       return atk_bridge_init (argc, argv);
 }
 
 static void
@@ -209,8 +226,10 @@ spi_atk_register_event_listeners (void)
   id = atk_add_global_event_listener (spi_atk_bridge_window_event_listener,
                                      "window:deactivate");
   g_array_append_val (listener_ids, id);
+  id = atk_add_global_event_listener (spi_atk_bridge_state_event_listener,
+                                     "Gtk:AtkObject:state-change");
+  g_array_append_val (listener_ids, id);
 
-  add_signal_listener ("Gtk:AtkObject:state-change");
   add_signal_listener ("Gtk:AtkObject:children-changed");
   add_signal_listener ("Gtk:AtkObject:visible-data-changed");
   add_signal_listener ("Gtk:AtkSelection:selection-changed");
@@ -240,8 +259,8 @@ spi_atk_register_event_listeners (void)
 static void
 deregister_application (BonoboObject *app)
 {
-  Accessibility_Registry_deregisterApplication (
-         registry, BONOBO_OBJREF (app), &ev);
+  Accessibility_Registry registry = spi_atk_bridge_get_registry ();    
+  Accessibility_Registry_deregisterApplication (registry, BONOBO_OBJREF (app), &ev);
 
   registry = bonobo_object_release_unref (registry, &ev);
   
@@ -295,7 +314,9 @@ void
 gnome_accessibility_module_shutdown (void)
 {
   BonoboObject *app = (BonoboObject *) this_app;
-
+  int     i;
+  GArray *ids = listener_ids;
+  
   if (!atk_bridge_initialized)
     {
       return;
@@ -305,26 +326,15 @@ gnome_accessibility_module_shutdown (void)
 
   g_print("Atk Accessibilty bridge shutdown\n");
 
-  if (idle_init_id)
-    {
-      g_source_remove (idle_init_id);
-      idle_init_id = 0;
-    }
-  else
-    {
-      int     i;
-      GArray *ids = listener_ids;
-
-      listener_ids = NULL;
-      atk_remove_focus_tracker (atk_bridge_focus_tracker_id);
-      
-      for (i = 0; ids && i < ids->len; i++)
-        {
+  listener_ids = NULL;
+  atk_remove_focus_tracker (atk_bridge_focus_tracker_id);
+  
+  for (i = 0; ids && i < ids->len; i++)
+  {
           atk_remove_global_event_listener (g_array_index (ids, guint, i));
-       }
-
-      atk_remove_key_event_listener (atk_bridge_key_event_listener_id);
-    }
+  }
+  
+  atk_remove_key_event_listener (atk_bridge_key_event_listener_id);
 
   deregister_application (app);
 }
@@ -342,8 +352,11 @@ spi_atk_bridge_focus_tracker (AtkObject *object)
   e.detail1 = 0;
   e.detail2 = 0;
 
-  Accessibility_Registry_notifyEvent (registry, &e, &ev);
-
+  Accessibility_Registry_notifyEvent (spi_atk_bridge_get_registry (), &e, &ev);
+  if (BONOBO_EX (&ev)) registry_died = TRUE;
+  
+  Accessibility_Accessible_unref (e.source, &ev);
+  
   CORBA_exception_free (&ev);
 }
 
@@ -395,7 +408,16 @@ spi_atk_emit_eventv (GObject      *gobject,
       CORBA_free (s);
 #endif
 
-      Accessibility_Registry_notifyEvent (registry, &e, &ev);
+      Accessibility_Registry_notifyEvent (spi_atk_bridge_get_registry (), &e, &ev);
+#ifdef SPI_BRIDGE_DEBUG
+      if (ev._major != CORBA_NO_EXCEPTION)
+             g_warning ("error emitting event %s, (%d) %s",
+                        e.type,
+                        ev._major,
+                        CORBA_exception_id(&ev));
+#endif       
+      if (BONOBO_EX (&ev)) registry_died = TRUE;
+      Accessibility_Accessible_unref (e.source, &ev);
 
       CORBA_exception_free (&ev);
 
@@ -403,6 +425,7 @@ spi_atk_emit_eventv (GObject      *gobject,
     }
 
   va_end (args);
+
 }
 
 static gboolean
@@ -438,7 +461,6 @@ spi_atk_bridge_property_event_listener (GSignalInvocationHint *signal_hint,
   return TRUE;
 }
 
-#if THIS_WILL_EVER_BE_USED
 static gboolean
 spi_atk_bridge_state_event_listener (GSignalInvocationHint *signal_hint,
                                     guint n_param_values,
@@ -446,7 +468,9 @@ spi_atk_bridge_state_event_listener (GSignalInvocationHint *signal_hint,
                                     gpointer data)
 {
   GObject *gobject;
-  AtkPropertyValues *values;
+  gchar *property_name;
+  gchar *type;
+  unsigned long detail1;
 #ifdef SPI_BRIDGE_DEBUG
   GSignalQuery signal_query;
   const gchar *name;
@@ -458,16 +482,19 @@ spi_atk_bridge_state_event_listener (GSignalInvocationHint *signal_hint,
 #endif
 
   gobject = g_value_get_object (param_values + 0);
-  values = (AtkPropertyValues*) g_value_get_pointer (param_values + 1);
-
+  property_name = g_strdup (g_value_get_string (param_values + 1));
+  detail1 = (g_value_get_boolean (param_values + 2))
+    ? 1 : 0;
+  type = g_strdup_printf ("object:state-changed:%s", property_name);
   spi_atk_emit_eventv (gobject, 
-                      (unsigned long) values->old_value.data[0].v_ulong,
-                      (unsigned long) values->new_value.data[0].v_ulong,
-                      "object:%s:?", values->property_name);
-  
+                      detail1,
+                      0,
+                      type);
+  g_free (property_name);
+  g_free (type);
   return TRUE;
 }
-#endif
+
 
 static void
 spi_init_keystroke_from_atk_key_event (Accessibility_DeviceEvent  *keystroke,
@@ -502,10 +529,10 @@ spi_init_keystroke_from_atk_key_event (Accessibility_DeviceEvent  *keystroke,
   switch (event->type)
     {
     case (ATK_KEY_EVENT_PRESS):
-      keystroke->type = Accessibility_KEY_PRESSED;
+      keystroke->type = Accessibility_KEY_PRESSED_EVENT;
       break;
     case (ATK_KEY_EVENT_RELEASE):
-      keystroke->type = Accessibility_KEY_RELEASED;
+      keystroke->type = Accessibility_KEY_RELEASED_EVENT;
       break;
     default:
       keystroke->type = 0;
@@ -524,13 +551,20 @@ spi_atk_bridge_key_listener (AtkKeyEventStruct *event, gpointer data)
 {
   CORBA_boolean             result;
   Accessibility_DeviceEvent key_event;
-  Accessibility_DeviceEventController controller =
-    Accessibility_Registry_getDeviceEventController (registry, &ev);
+  Accessibility_DeviceEventController controller;
+       
+  if (BONOBO_EX (&ev))
+       g_warning ("failure: pre-listener get dec\n");
+
+  controller =
+    Accessibility_Registry_getDeviceEventController (
+           spi_atk_bridge_get_registry (), &ev);
 
   if (BONOBO_EX (&ev))
     {
       g_warning ("failure: no deviceeventcontroller found\n");
       CORBA_exception_free (&ev);
+      registry_died = TRUE;
       result = FALSE;
     }
   else
@@ -541,6 +575,7 @@ spi_atk_bridge_key_listener (AtkKeyEventStruct *event, gpointer data)
       result = Accessibility_DeviceEventController_notifyListenersSync (
         controller, &key_event, &ev);
 
+      bonobo_object_release_unref (controller, &ev);
       CORBA_exception_free (&ev);
     }