Fixed some problems when shutting down and restarting the module
[platform/core/uifw/at-spi2-atk.git] / atk-adaptor / event.c
index d489a13..e940e00 100644 (file)
@@ -32,7 +32,7 @@
 #include "bridge.h"
 #include "accessible-register.h"
 
-#include "common/spi-dbus.h"
+#include "spi-dbus.h"
 #include "event.h"
 #include "object.h"
 
@@ -114,7 +114,7 @@ send_and_allow_reentry (DBusConnection * bus, DBusMessage * message)
 
 static gboolean
 Accessibility_DeviceEventController_NotifyListenersSync (const
-                                                         Accessibility_DeviceEvent
+                                                         AtspiDeviceEvent
                                                          * key_event)
 {
   DBusMessage *message;
@@ -123,8 +123,8 @@ Accessibility_DeviceEventController_NotifyListenersSync (const
 
   message =
     dbus_message_new_method_call (SPI_DBUS_NAME_REGISTRY,
-                                  SPI_DBUS_PATH_DEC,
-                                  SPI_DBUS_INTERFACE_DEC,
+                                  ATSPI_DBUS_PATH_DEC,
+                                  ATSPI_DBUS_INTERFACE_DEC,
                                   "NotifyListenersSync");
 
   dbus_error_init (&error);
@@ -146,7 +146,7 @@ Accessibility_DeviceEventController_NotifyListenersSync (const
 }
 
 static void
-spi_init_keystroke_from_atk_key_event (Accessibility_DeviceEvent * keystroke,
+spi_init_keystroke_from_atk_key_event (AtspiDeviceEvent * keystroke,
                                        AtkKeyEventStruct * event)
 {
   keystroke->id = (dbus_int32_t) event->keyval;
@@ -172,10 +172,10 @@ spi_init_keystroke_from_atk_key_event (Accessibility_DeviceEvent * keystroke,
   switch (event->type)
     {
     case (ATK_KEY_EVENT_PRESS):
-      keystroke->type = Accessibility_KEY_PRESSED_EVENT;
+      keystroke->type = ATSPI_KEY_PRESSED;
       break;
     case (ATK_KEY_EVENT_RELEASE):
-      keystroke->type = Accessibility_KEY_RELEASED_EVENT;
+      keystroke->type = ATSPI_KEY_RELEASED;
       break;
     default:
       keystroke->type = 0;
@@ -195,7 +195,7 @@ static gint
 spi_atk_bridge_key_listener (AtkKeyEventStruct * event, gpointer data)
 {
   gboolean result;
-  Accessibility_DeviceEvent key_event;
+  AtspiDeviceEvent key_event;
 
   spi_init_keystroke_from_atk_key_event (&key_event, event);
 
@@ -228,7 +228,7 @@ convert_signal_name (const gchar * s)
 }
 
 static const void *
-replace_null (const gint type,
+validate_for_dbus (const gint type,
               const void *val)
 {
   switch (type)
@@ -237,6 +237,11 @@ replace_null (const gint type,
       case DBUS_TYPE_OBJECT_PATH:
           if (!val)
              return "";
+          else if (!g_utf8_validate (val, -1, NULL))
+             {
+              g_warning ("atk-bridge: Received bad UTF-8 string when emitting event");
+              return "";
+               }
           else
              return val;
       default:
@@ -253,7 +258,7 @@ append_basic (DBusMessageIter *iter,
 
   dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, type, &sub);
 
-    val = replace_null ((int) *type, val);
+    val = validate_for_dbus ((int) *type, val);
     dbus_message_iter_append_basic(&sub, (int) *type, &val);
 
   dbus_message_iter_close_container(iter, &sub);
@@ -358,6 +363,19 @@ signal_is_needed (const gchar *klass, const gchar *major, const gchar *minor)
   data [2] = ensure_proper_format (minor);
   data [3] = NULL;
 
+  /* Hack: Always pass events that update the cache.
+   * TODO: FOr 2.2, have at-spi2-core define a special "cache listener" for
+   * this instead, so that we don't send these if no one is listening */
+  if (!g_strcmp0 (data [1], "ChildrenChanged") ||
+      !g_strcmp0 (data [1], "PropertyChange") ||
+      !g_strcmp0 (data [1], "StateChanged"))
+  {
+    g_free (data [2]);
+    g_free (data [1]);
+    g_free (data [0]);
+    return TRUE;
+  }
+
   /* Hack: events such as "object::text-changed::insert:system" as
      generated by Gecko */
   data [2][strcspn (data [2], ":")] = '\0';
@@ -371,7 +389,9 @@ signal_is_needed (const gchar *klass, const gchar *major, const gchar *minor)
         }
     }
 
-//printf("event: %s %s %s: %d\n", data[0], data[1], data[2], ret);
+#if 0
+  g_print("event: %s %s %s: %d\n", data[0], data[1], data[2], ret);
+#endif
   g_free (data [2]);
   g_free (data [1]);
   g_free (data [0]);
@@ -586,15 +606,15 @@ state_event_listener (GSignalInvocationHint * signal_hint,
   guint detail1;
 
   accessible = ATK_OBJECT (g_value_get_object (&param_values[0]));
-  pname = g_strdup (g_value_get_string (&param_values[1]));
+  pname = g_value_get_string (&param_values[1]);
 
-  /* TODO - Possibly ignore a change to the 'defunct' state.
-   * This is because without reference counting defunct objects should be removed.
-   */
   detail1 = (g_value_get_boolean (&param_values[2])) ? 1 : 0;
   emit_event (accessible, ITF_EVENT_OBJECT, STATE_CHANGED, pname, detail1, 0,
               DBUS_TYPE_INT32_AS_STRING, 0, append_basic);
-  g_free (pname);
+
+  if (!g_strcmp0 (pname, "defunct"))
+    spi_register_deregister_object (spi_global_register, G_OBJECT (accessible),
+                                    TRUE);
   return TRUE;
 }
 
@@ -740,7 +760,7 @@ link_selected_event_listener (GSignalInvocationHint * signal_hint,
   AtkObject *accessible;
   GSignalQuery signal_query;
   const gchar *name, *minor;
-  gint detail1;
+  gint detail1 = 0;
 
   g_signal_query (signal_hint->signal_id, &signal_query);
   name = signal_query.signal_name;
@@ -774,7 +794,7 @@ text_changed_event_listener (GSignalInvocationHint * signal_hint,
   GSignalQuery signal_query;
   const gchar *name, *minor;
   gchar *selected;
-  gint detail1, detail2;
+  gint detail1 = 0, detail2 = 0;
 
   g_signal_query (signal_hint->signal_id, &signal_query);
   name = signal_query.signal_name;
@@ -813,7 +833,7 @@ text_insert_event_listener (GSignalInvocationHint * signal_hint,
   GSignalQuery signal_query;
   const gchar *name;
   gchar *minor, *text;
-  gint detail1, detail2;
+  gint detail1 = 0, detail2 = 0;
 
   accessible = ATK_OBJECT (g_value_get_object (&param_values[0]));
   /* Get signal name for 'Gtk:AtkText:text-changed' so
@@ -861,7 +881,7 @@ text_remove_event_listener (GSignalInvocationHint * signal_hint,
   GSignalQuery signal_query;
   const gchar *name;
   gchar *minor, *text;
-  gint detail1, detail2;
+  gint detail1 = 0, detail2 = 0;
 
   accessible = ATK_OBJECT (g_value_get_object (&param_values[0]));
   /* Get signal name for 'Gtk:AtkText:text-changed' so
@@ -912,7 +932,7 @@ text_selection_changed_event_listener (GSignalInvocationHint * signal_hint,
   AtkObject *accessible;
   GSignalQuery signal_query;
   const gchar *name, *minor;
-  gint detail1, detail2;
+  gint detail1 = 0, detail2 = 0;
 
   g_signal_query (signal_hint->signal_id, &signal_query);
   name = signal_query.signal_name;
@@ -950,7 +970,7 @@ children_changed_event_listener (GSignalInvocationHint * signal_hint,
 {
   GSignalQuery signal_query;
   const gchar *name, *minor;
-  gint detail1, detail2 = 0;
+  gint detail1 = 0, detail2 = 0;
 
   AtkObject *accessible, *ao=NULL;
   gpointer child;
@@ -1076,6 +1096,12 @@ spi_atk_register_event_listeners (void)
   g_object_unref (G_OBJECT (bo));
   g_object_unref (ao);
 
+  if (listener_ids)
+  {
+    g_warning ("atk_bridge: spi_atk-register_event_listeners called multiple times");
+    return;
+  }
+
   /* Register for focus event notifications, and register app with central registry  */
   listener_ids = g_array_sized_new (FALSE, TRUE, sizeof (guint), 16);
 
@@ -1129,10 +1155,7 @@ spi_atk_register_event_listeners (void)
                        "Gtk:AtkTable:column-reordered");
   add_signal_listener (generic_event_listener, "Gtk:AtkTable:column-deleted");
   add_signal_listener (generic_event_listener, "Gtk:AtkTable:model-changed");
-
-  /* Children signal listeners */
-  atk_add_global_event_listener (children_changed_event_listener,
-                                 "Gtk:AtkObject:children-changed");
+  add_signal_listener (children_changed_event_listener, "Gtk:AtkObject:children-changed");
 
 #if 0
   g_signal_connect (G_OBJECT (spi_global_app_data->root),
@@ -1167,15 +1190,25 @@ spi_atk_deregister_event_listeners (void)
   listener_ids = NULL;
 
   if (atk_bridge_focus_tracker_id)
+  {
     atk_remove_focus_tracker (atk_bridge_focus_tracker_id);
+    atk_bridge_focus_tracker_id = 0;
+  }
 
-  for (i = 0; ids && i < ids->len; i++)
+  if (ids)
     {
-      atk_remove_global_event_listener (g_array_index (ids, guint, i));
+      for (i = 0; i < ids->len; i++)
+        {
+          atk_remove_global_event_listener (g_array_index (ids, guint, i));
+        }
+      g_array_free (ids, TRUE);
     }
 
   if (atk_bridge_key_event_listener_id)
+  {
     atk_remove_key_event_listener (atk_bridge_key_event_listener_id);
+    atk_bridge_key_event_listener_id = 0;
+  }
 }
 
 /*---------------------------------------------------------------------------*/