Various fixes
authorMike Gorse <mgorse@novell.com>
Fri, 12 Nov 2010 18:17:41 +0000 (13:17 -0500)
committerMike Gorse <mgorse@novell.com>
Fri, 12 Nov 2010 18:17:41 +0000 (13:17 -0500)
atspi/atspi-accessible.c
atspi/atspi-accessible.h
atspi/atspi-event-listener.c
atspi/atspi-event-types.h
atspi/atspi-misc.c
dbind/dbind.c
dbind/dbind.h

index 1c441e1..a3c1c8d 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include "atspi-private.h"
+#include <string.h>
 
 G_DEFINE_TYPE (AtspiAccessible, atspi_accessible, G_TYPE_OBJECT)
 
@@ -48,6 +49,7 @@ atspi_accessible_class_init (AtspiAccessibleClass *klass)
 
   object_class->finalize = atspi_accessible_finalize;
 }
+
 /* TODO: Generate following from spec? */
 static const char *role_names [] =
 {
@@ -179,9 +181,9 @@ gchar *
 atspi_accessible_get_name (AtspiAccessible *obj, GError **error)
 {
   g_return_val_if_fail (obj != NULL, NULL);
-  if (!obj->cached_properties & ATSPI_CACHE_NAME)
+  if (!(obj->cached_properties & ATSPI_CACHE_NAME))
   {
-    if (!_atspi_dbus_call (obj, atspi_interface_accessible, "GetName", NULL, "=>s", &obj->name))
+    if (!_atspi_dbus_get_property (obj, atspi_interface_accessible, "Name", NULL, "s", &obj->name))
       return NULL;
     obj->cached_properties |= ATSPI_CACHE_NAME;
   }
@@ -202,7 +204,7 @@ atspi_accessible_get_description (AtspiAccessible *obj, GError **error)
 {
   g_return_val_if_fail (obj != NULL, NULL);
 
-  if (!obj->cached_properties & ATSPI_CACHE_DESCRIPTION)
+  if (!(obj->cached_properties & ATSPI_CACHE_DESCRIPTION))
   {
     if (!_atspi_dbus_call (obj, atspi_interface_accessible, "GetDescription", NULL, "=>s", &obj->description))
       return NULL;
@@ -211,6 +213,8 @@ atspi_accessible_get_description (AtspiAccessible *obj, GError **error)
   return g_strdup (obj->description);
 }
 
+const char *str_parent = "Parent";
+
 /**
  * atspi_accessible_get_parent:
  * @obj: a pointer to the #AtspiAccessible object to query.
@@ -227,6 +231,29 @@ atspi_accessible_get_parent (AtspiAccessible *obj, GError **error)
 {
   g_return_val_if_fail (obj != NULL, NULL);
 
+  if (!(obj->cached_properties & ATSPI_CACHE_PARENT))
+  {
+    DBusMessage *message, *reply;
+    DBusMessageIter iter, iter_variant;
+    message = dbus_message_new_method_call (obj->app->bus_name, obj->path,
+                                            DBUS_INTERFACE_PROPERTIES, "Get");
+    if (!message)
+      return NULL;
+    dbus_message_append_args (message, DBUS_TYPE_STRING, &atspi_interface_accessible,
+                               DBUS_TYPE_STRING, &str_parent,
+                              DBUS_TYPE_INVALID);
+    reply = _atspi_dbus_send_with_reply_and_block (message);
+    if (!reply ||
+       (strcmp (dbus_message_get_signature (reply), "v") != 0))
+      return NULL;
+    dbus_message_iter_init (reply, &iter);
+    dbus_message_iter_recurse (&iter, &iter_variant);
+    obj->accessible_parent = _atspi_dbus_return_accessible_from_iter (&iter_variant);
+    dbus_message_unref (reply);
+    obj->cached_properties |= ATSPI_CACHE_PARENT;
+  }
+  if (!obj->accessible_parent)
+    return NULL;
   return g_object_ref (obj->accessible_parent);
 }
 
@@ -349,9 +376,10 @@ atspi_accessible_get_role (AtspiAccessible *obj, GError **error)
 {
   g_return_val_if_fail (obj != NULL, ATSPI_ROLE_INVALID);
 
-  if (!obj->cached_properties & ATSPI_CACHE_ROLE)
+  if (!(obj->cached_properties & ATSPI_CACHE_ROLE))
   {
     dbus_uint32_t role;
+    /* TODO: Make this a property */
     if (_atspi_dbus_call (obj, atspi_interface_accessible, "GetRole", NULL, "=>u", &role))
     {
       obj->cached_properties |= ATSPI_CACHE_ROLE;
@@ -486,9 +514,16 @@ atspi_accessible_get_attributes_as_array (AtspiAccessible *obj, GError **error)
 AtspiAccessible *
 atspi_accessible_get_host_application (AtspiAccessible *obj, GError **error)
 {
-  while (obj->accessible_parent && atspi_accessible_get_role (obj->accessible_parent, NULL) != ATSPI_ROLE_DESKTOP_FRAME)
-    obj = obj->accessible_parent;
-  return g_object_ref (obj);
+  AtspiAccessible *parent;
+
+  for (;;)
+  {
+    parent = atspi_accessible_get_parent (obj, NULL);
+    if (!parent || parent == obj ||
+        atspi_accessible_get_role (parent, NULL) == ATSPI_ROLE_DESKTOP_FRAME)
+    return obj;
+    obj = parent;
+  }
 }
 
 #if 0  // TODO: interfaces */
@@ -1256,11 +1291,11 @@ cspi_object_destroyed (AtspiAccessible *accessible)
   AtspiEvent e;
 
   /* TODO: Only fire if object not already marked defunct */
+  memset (&e, 0, sizeof (e));
   e.type = "object:state-change:defunct";
   e.source = accessible;
   e.detail1 = 1;
   e.detail2 = 0;
-  g_value_unset (&e.any);
   _atspi_send_event (&e);
 
     g_free (accessible->path);
index d22db4c..8866f7a 100644 (file)
@@ -43,13 +43,12 @@ typedef struct _AtspiAccessible AtspiAccessible;
 struct _AtspiAccessible
 {
   GObject parent;
-  gint ref_count;
   AtspiAccessible *accessible_parent;
   GList *children;
   AtspiApplication *app;
   char *path;
-  gint role : 8;
-  gint interfaces : 24;
+  AtspiRole role;
+  gint interfaces;
   char *name;
   char *description;
   AtspiStateSet *states;
index 9b0f8d2..ce3c390 100644 (file)
@@ -75,12 +75,12 @@ cache_process_children_changed (AtspiEvent *event)
 {
   AtspiAccessible *child;
 
-  if (!G_VALUE_HOLDS (&event->any, ATSPI_TYPE_ACCESSIBLE) ||
+  if (!G_VALUE_HOLDS (&event->any_data, ATSPI_TYPE_ACCESSIBLE) ||
       !event->source->children ||
       atspi_state_set_contains (event->source->states, ATSPI_STATE_MANAGES_DESCENDANTS))
     return;
 
-  child = g_value_get_object (&event->any);
+  child = g_value_get_object (&event->any_data);
 
   if (!strncmp (event->type, "object:children-changed:add", 27))
   {
@@ -101,9 +101,9 @@ cache_process_property_change (AtspiEvent *event)
   {
     if (event->source->accessible_parent)
       g_object_unref (event->source->accessible_parent);
-    if (G_VALUE_HOLDS (&event->any, ATSPI_TYPE_ACCESSIBLE))
+    if (G_VALUE_HOLDS (&event->any_data, ATSPI_TYPE_ACCESSIBLE))
     {
-      event->source->accessible_parent = g_value_dup_object (&event->any);
+      event->source->accessible_parent = g_value_dup_object (&event->any_data);
       event->source->cached_properties |= ATSPI_CACHE_PARENT;
     }
     else
@@ -116,9 +116,9 @@ cache_process_property_change (AtspiEvent *event)
   {
     if (event->source->name)
       g_free (event->source->name);
-    if (G_VALUE_HOLDS_STRING (&event->any))
+    if (G_VALUE_HOLDS_STRING (&event->any_data))
     {
-      event->source->name = g_value_dup_string (&event->any);
+      event->source->name = g_value_dup_string (&event->any_data);
       event->source->cached_properties |= ATSPI_CACHE_NAME;
     }
     else
@@ -131,9 +131,9 @@ cache_process_property_change (AtspiEvent *event)
   {
     if (event->source->description)
       g_free (event->source->description);
-    if (G_VALUE_HOLDS_STRING (&event->any))
+    if (G_VALUE_HOLDS_STRING (&event->any_data))
     {
-      event->source->description = g_value_dup_string (&event->any);
+      event->source->description = g_value_dup_string (&event->any_data);
       event->source->cached_properties |= ATSPI_CACHE_DESCRIPTION;
     }
     else
@@ -546,6 +546,11 @@ _atspi_send_event (AtspiEvent *e)
   char *category, *name, *detail;
   GList *l;
 
+  /* Ensure that the value is set to avoid a Python exception */
+  /* TODO: Figure out how to do this without using a private field */
+  if (e->any_data.g_type == 0)
+    g_value_set_int (&e->any_data, 0);
+
   if (!convert_event_type_to_dbus (e->type, &category, &name, &detail, NULL))
   {
     g_warning ("Atspi: Couldn't parse event: %s\n", e->type);
@@ -638,22 +643,22 @@ atspi_dbus_handle_event (DBusConnection *bus, DBusMessage *message, void *data)
       AtspiRect rect;
       if (demarshal_rect (&iter_variant, &rect))
       {
-       g_value_init (&e.any, ATSPI_TYPE_RECT);
-       g_value_set_boxed (&e.any, &rect);
+       g_value_init (&e.any_data, ATSPI_TYPE_RECT);
+       g_value_set_boxed (&e.any_data, &rect);
       }
       else
       {
         AtspiAccessible *accessible;
        accessible = _atspi_dbus_return_accessible_from_iter (&iter_variant);
-       g_value_init (&e.any, ATSPI_TYPE_ACCESSIBLE);
-       g_value_set_instance (&e.any, accessible);
+       g_value_init (&e.any_data, ATSPI_TYPE_ACCESSIBLE);
+       g_value_set_instance (&e.any_data, accessible);
       }
       break;
     }
     case DBUS_TYPE_STRING:
     {
       dbus_message_iter_get_basic (&iter_variant, &p);
-      g_value_set_string (&e.any, p);
+      g_value_set_string (&e.any_data, p);
       break;
     }
   default:
@@ -678,7 +683,7 @@ atspi_dbus_handle_event (DBusConnection *bus, DBusMessage *message, void *data)
   g_free (name);
   g_free (detail);
   g_object_unref (e.source);
-  g_value_unset (&e.any);
+  g_value_unset (&e.any_data);
   return DBUS_HANDLER_RESULT_HANDLED;
 }
 
@@ -689,7 +694,7 @@ atspi_event_copy (AtspiEvent *src)
   dst->type = g_strdup (src->type);
   dst->detail1 = src->detail1;
   dst->detail2 = src->detail2;
-  g_value_copy (&dst->any, &src->any);
+  g_value_copy (&dst->any_data, &src->any_data);
 }
 
 static void
@@ -697,7 +702,7 @@ atspi_event_free (AtspiEvent *event)
 {
   g_object_unref (event->source);
   g_free (event->type);
-  g_value_unset (&event->any);
+  g_value_unset (&event->any_data);
   g_free (event);
 }
 
index 3d52505..b08713c 100644 (file)
@@ -73,7 +73,7 @@ struct _AtspiEvent
   AtspiAccessible  *source;
   gint         detail1;
   gint         detail2;
-  GValue any;
+  GValue any_data;
 };
 
 /**
index 2ae565d..440c9d9 100644 (file)
@@ -30,6 +30,7 @@
 #include "atspi-private.h"
 #include "X11/Xlib.h"
 #include <stdio.h>
+#include <string.h>
 
 static DBusConnection *bus = NULL;
 static GHashTable *apps = NULL;
@@ -150,14 +151,7 @@ get_application (const char *bus_name)
   app = _atspi_application_new (bus_name);
   if (!app) return NULL;
   app->bus_name = bus_name_dup;
-  if (APP_IS_REGISTRY (app))
-  {
-    app->hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
-  }
-  else
-  {
-    app->hash = g_hash_table_new_full (g_int_hash, g_int_equal, g_free, g_object_unref);
-  }
+  app->hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
   g_hash_table_insert (app_hash, bus_name_dup, app);
   return app;
 }
@@ -168,6 +162,9 @@ ref_accessible (const char *app_name, const char *path)
   AtspiApplication *app = get_application (app_name);
   AtspiAccessible *a;
 
+  if (!strcmp (path, ATSPI_DBUS_PATH_NULL))
+    return NULL;
+
   if (!strcmp (path, "/org/a11y/atspi/accessible/root"))
   {
     if (!app->root)
@@ -181,8 +178,7 @@ ref_accessible (const char *app_name, const char *path)
   a = g_hash_table_lookup (app->hash, path);
   if (a)
   {
-    g_object_ref (a);
-    return a;
+    return g_object_ref (a);
   }
   a = atspi_accessible_new (app, path);
   if (!a)
@@ -227,6 +223,8 @@ handle_remove_accessible (DBusConnection *bus, DBusMessage *message, void *user_
   dbus_message_iter_get_basic (&iter_struct, &path);
   app = get_application (sender);
   a = ref_accessible (sender, path);
+  if (!a)
+    return DBUS_HANDLER_RESULT_HANDLED;
   if (a->accessible_parent && g_list_find (a->accessible_parent->children, a))
   {
     a->accessible_parent->children = g_list_remove (a->accessible_parent->children, a);
@@ -266,11 +264,11 @@ send_children_changed (AtspiAccessible *parent, AtspiAccessible *child, gboolean
 {
   AtspiEvent e;
 
+  memset (&e, 0, sizeof (e));
   e.type = (add? "object:children-changed:add": "object:children-changed:remove");
   e.source = parent;
   e.detail1 = g_list_index (parent->children, child);
   e.detail2 = 0;
-  g_value_unset (&e.any);
   _atspi_send_event (&e);
 }
 
@@ -341,6 +339,8 @@ add_accessible_from_iter (DBusMessageIter *iter)
   /* get accessible */
   get_reference_from_iter (&iter_struct, &app_name, &path);
   accessible = ref_accessible (app_name, path);
+  if (!accessible)
+    return;
 
   /* Get application: TODO */
   dbus_message_iter_next (&iter_struct);
@@ -930,6 +930,8 @@ _atspi_dbus_send_with_reply_and_block (DBusMessage *message)
   /* TODO: Write this function; allow reentrancy */
   reply = dbus_connection_send_with_reply_and_block (_atspi_bus(), message, 1000, &err);
   dbus_message_unref (message);
+  if (err.message)
+    g_warning ("Atspi: Got error: %s\n", err.message);
   return reply;
 }
 
index 5c49d66..0f301b5 100644 (file)
@@ -7,6 +7,8 @@
 #include "config.h"
 #include "dbind/dbind.h"
 
+static int dbind_timeout = -1;
+
 /*
  * FIXME: compare types - to ensure they match &
  *        do dynamic padding of structures etc.
 
 /*---------------------------------------------------------------------------*/
 
+typedef struct _SpiReentrantCallClosure 
+{
+  GMainLoop   *loop;
+  DBusMessage *reply;
+} SpiReentrantCallClosure;
+
 static void
-set_reply (DBusPendingCall *pending, void *user_data)
+set_reply (DBusPendingCall * pending, void *user_data)
 {
-    void **replyptr = (void **)user_data;
+  SpiReentrantCallClosure* closure = (SpiReentrantCallClosure *) user_data; 
 
-    *replyptr = dbus_pending_call_steal_reply (pending);
+  closure->reply = dbus_pending_call_steal_reply (pending);
+  g_main_loop_quit (closure->loop);
 }
 
 DBusMessage *
-dbind_send_and_allow_reentry (DBusConnection *bus, DBusMessage *message, DBusError *error)
+dbind_send_and_allow_reentry (DBusConnection * bus, DBusMessage * message, DBusError *error)
 {
-    DBusPendingCall *pending;
-    DBusMessage *reply = NULL;
+  DBusPendingCall *pending;
+  SpiReentrantCallClosure closure;
+
+  if (strcmp (dbus_message_get_destination (message),
+              dbus_bus_get_unique_name (bus)) != 0)
+    return dbus_connection_send_with_reply_and_block (bus, message, dbind_timeout, error);
 
-    if (!dbus_connection_send_with_reply (bus, message, &pending, -1))
+  if (!dbus_connection_send_with_reply (bus, message, &pending, dbind_timeout))
+      return NULL;
+  dbus_pending_call_set_notify (pending, set_reply, (void *) &closure, NULL);
+  closure.loop = g_main_loop_new (NULL, FALSE);
+  dbus_connection_setup_with_g_main(bus, NULL);
+
+  if (1)
     {
-        return NULL;
+      g_main_loop_run  (closure.loop);
     }
-    dbus_pending_call_set_notify (pending, set_reply, (void *)&reply, NULL);
-    while (!reply)
+  else
     {
-      if (!dbus_connection_read_write_dispatch (bus, -1)) return NULL;
+      closure.reply = NULL;
+      while (!closure.reply)
+        {
+          if (!dbus_connection_read_write_dispatch (bus, dbind_timeout))
+            return NULL;
+        }
     }
-    return reply;
+  
+  g_main_loop_unref (closure.loop);
+  return closure.reply;
 }
 
 dbus_bool_t
@@ -226,5 +251,11 @@ dbind_emit_signal (DBusConnection *cnx,
 
     return success;
 }
+void
+dbind_set_timeout (int timeout)
+{
+  dbind_timeout = timeout;
+}
+
 
 /*END------------------------------------------------------------------------*/
index 3a8b209..408099c 100644 (file)
@@ -46,4 +46,5 @@ dbind_emit_signal (DBusConnection *cnx,
                    const char     *arg_types,
                    ...);
 
+void dbind_set_timeout (int timeout);
 #endif /* _DBIND_H_ */