Move atspi_get_a11y_bus back into libatspi and publicly export
[platform/upstream/at-spi2-core.git] / atspi / atspi-misc.c
index 1a3f412..248f0d9 100644 (file)
@@ -4,6 +4,7 @@
  *
  * Copyright 2001, 2002 Sun Microsystems Inc.,
  * Copyright 2001, 2002 Ximian, Inc.
+ * Copyright 2010, 2011 Novell, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -181,7 +182,7 @@ get_application (const char *bus_name)
 
   if (!app_hash)
   {
-    app_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_hash_table_unref);
+    app_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_object_unref);
     if (!app_hash) return NULL;
   }
   app = g_hash_table_lookup (app_hash, bus_name);
@@ -191,9 +192,9 @@ get_application (const char *bus_name)
   // TODO: change below to something that will send state-change:defunct notification if necessary */
   app = _atspi_application_new (bus_name);
   if (!app) return NULL;
-  app->bus_name = bus_name_dup;
   app->hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
   app->bus = dbus_connection_ref (_atspi_bus ());
+  app->cache = ATSPI_CACHE_UNDEFINED;
   g_hash_table_insert (app_hash, bus_name_dup, app);
   dbus_error_init (&error);
   message = dbus_message_new_method_call (bus_name, atspi_path_root,
@@ -458,10 +459,11 @@ add_accessible_from_iter (DBusMessageIter *iter)
   _atspi_dbus_set_state (accessible, &iter_struct);
   dbus_message_iter_next (&iter_struct);
 
-  accessible->cached_properties |= ATSPI_CACHE_NAME | ATSPI_CACHE_ROLE | ATSPI_CACHE_PARENT;
+  _atspi_accessible_add_cache (accessible, ATSPI_CACHE_NAME | ATSPI_CACHE_ROLE |
+                               ATSPI_CACHE_PARENT | ATSPI_CACHE_DESCRIPTION);
   if (!atspi_state_set_contains (accessible->states,
                                        ATSPI_STATE_MANAGES_DESCENDANTS))
-    accessible->cached_properties |= ATSPI_CACHE_CHILDREN;
+    _atspi_accessible_add_cache (accessible, ATSPI_CACHE_CHILDREN);
 
   /* This is a bit of a hack since the cache holds a ref, so we don't need
    * the one provided for us anymore */
@@ -529,7 +531,7 @@ ref_accessible_desktop (AtspiApplication *app)
   reply = _atspi_dbus_send_with_reply_and_block (message, NULL);
   if (!reply || strcmp (dbus_message_get_signature (reply), "a(so)") != 0)
   {
-    g_error ("Couldn't get application list: %s", error.message);
+    g_warning ("Couldn't get application list: %s", error.message);
     if (reply)
       dbus_message_unref (reply);
     return NULL;
@@ -559,7 +561,7 @@ _atspi_ref_accessible (const char *app, const char *path)
   if (!a) return NULL;
   if ( APP_IS_REGISTRY(a))
   {
-    return ref_accessible_desktop (a);
+    return a->root = ref_accessible_desktop (a);
   }
   return ref_accessible (app, path);
 }
@@ -643,6 +645,7 @@ handle_add_accessible (DBusConnection *bus, DBusMessage *message, void *user_dat
 
   dbus_message_iter_init (message, &iter);
   add_accessible_from_iter (&iter);
+  return DBUS_HANDLER_RESULT_HANDLED;
 }
 
 typedef struct
@@ -802,71 +805,6 @@ spi_display_name (void)
   return canonical_display_name;
 }
 
-/* TODO: Avoid having duplicate functions for this here and in at-spi2-atk */
-static DBusConnection *
-get_accessibility_bus ()
-{
-  Atom AT_SPI_BUS;
-  Atom actual_type;
-  Display *bridge_display;
-  int actual_format;
-  unsigned char *data = NULL;
-  unsigned long nitems;
-  unsigned long leftover;
-
-  DBusConnection *bus = NULL;
-  DBusError error;
-
-  bridge_display = XOpenDisplay (spi_display_name ());
-  if (!bridge_display)
-    {
-      g_warning (_("AT-SPI: Could not get the display\n"));
-      return NULL;
-    }
-
-  AT_SPI_BUS = XInternAtom (bridge_display, "AT_SPI_BUS", False);
-  XGetWindowProperty (bridge_display,
-                      XDefaultRootWindow (bridge_display),
-                      AT_SPI_BUS, 0L,
-                      (long) BUFSIZ, False,
-                      (Atom) 31, &actual_type, &actual_format,
-                      &nitems, &leftover, &data);
-  XCloseDisplay (bridge_display);
-
-  dbus_error_init (&error);
-
-  if (data == NULL)
-    {
-      g_warning
-        (_("AT-SPI: Accessibility bus not found - Using session bus.\n"));
-      bus = dbus_bus_get (DBUS_BUS_SESSION, &error);
-      if (!bus)
-        {
-          g_warning (_("AT-SPI: Couldn't connect to bus: %s\n"), error.message);
-          return NULL;
-        }
-    }
-  else
-    {
-      bus = dbus_connection_open (data, &error);
-      if (!bus)
-        {
-          g_warning (_("AT-SPI: Couldn't connect to bus: %s\n"), error.message);
-          return NULL;
-        }
-      else
-        {
-          if (!dbus_bus_register (bus, &error))
-            {
-              g_warning (_("AT-SPI: Couldn't register with bus: %s\n"), error.message);
-              return NULL;
-            }
-        }
-    }
-
-  return bus;
-}
-
 /**
  * atspi_init:
  *
@@ -892,12 +830,9 @@ atspi_init (void)
   get_live_refs();
 
   dbus_error_init (&error);
-  bus = get_accessibility_bus ();
+  bus = atspi_get_a11y_bus ();
   if (!bus)
-  {
-    g_error ("Couldn't get session bus");
     return 2;
-  }
   dbus_bus_register (bus, &error);
   dbus_connection_setup_with_g_main(bus, g_main_context_default());
   dbus_connection_add_filter (bus, atspi_dbus_filter, NULL, NULL);
@@ -1279,7 +1214,7 @@ _atspi_dbus_set_interfaces (AtspiAccessible *accessible, DBusMessageIter *iter)
       accessible->interfaces |= (1 << n);
     dbus_message_iter_next (&iter_array);
   }
-  accessible->cached_properties |= ATSPI_CACHE_INTERFACES;
+  _atspi_accessible_add_cache (accessible, ATSPI_CACHE_INTERFACES);
 }
 
 void
@@ -1306,7 +1241,7 @@ _atspi_dbus_set_state (AtspiAccessible *accessible, DBusMessageIter *iter)
     else
       accessible->states->states = val;
   }
-  accessible->cached_properties |= ATSPI_CACHE_STATES;
+  _atspi_accessible_add_cache (accessible, ATSPI_CACHE_STATES);
 }
 
 GQuark
@@ -1315,3 +1250,111 @@ atspi_error_quark (void)
   return g_quark_from_static_string ("atspi_error");
 }
 
+/*
+ * Gets the IOR from the XDisplay.
+ */
+static char *
+get_accessibility_bus_address_x11 (void)
+{
+  Atom AT_SPI_BUS;
+  Atom actual_type;
+  Display *bridge_display;
+  int actual_format;
+  unsigned char *data = NULL;
+  unsigned long nitems;
+  unsigned long leftover;
+
+  bridge_display = XOpenDisplay (spi_display_name ());
+  if (!bridge_display)
+    {
+      g_warning ("Could not open X display");
+      return NULL;
+    }
+      
+  AT_SPI_BUS = XInternAtom (bridge_display, "AT_SPI_BUS", False);
+  XGetWindowProperty (bridge_display,
+                     XDefaultRootWindow (bridge_display),
+                     AT_SPI_BUS, 0L,
+                     (long) BUFSIZ, False,
+                     (Atom) 31, &actual_type, &actual_format,
+                     &nitems, &leftover, &data);
+  XCloseDisplay (bridge_display);
+
+  return g_strdup (data);
+}
+
+static char *
+get_accessibility_bus_address_dbus (void)
+{
+  DBusConnection *session_bus = NULL;
+  DBusMessage *message;
+  DBusMessage *reply;
+  char *address = NULL;
+
+  session_bus = dbus_bus_get (DBUS_BUS_SESSION, NULL);
+  if (!session_bus)
+    return NULL;
+
+  message = dbus_message_new_method_call ("org.a11y.Bus",
+                                         "/org/a11y/bus",
+                                         "org.a11y.Bus",
+                                         "GetAddress");
+
+  reply = dbus_connection_send_with_reply_and_block (session_bus,
+                                                    message,
+                                                    -1,
+                                                    NULL);
+  dbus_message_unref (message);
+
+  if (!reply)
+    return NULL;
+  
+  {
+    const char *tmp_address;
+    if (!dbus_message_get_args (reply,
+                               NULL,
+                               DBUS_TYPE_STRING,
+                               &tmp_address,
+                               DBUS_TYPE_INVALID))
+      {
+       dbus_message_unref (reply);
+       return NULL;
+      }
+    address = g_strdup (tmp_address);
+    dbus_message_unref (reply);
+  }
+  
+  return address;
+}
+
+DBusConnection *
+atspi_get_a11y_bus (void)
+{
+  DBusConnection *bus = NULL;
+  DBusError error;
+  char *address;
+
+  address = get_accessibility_bus_address_x11 ();
+  if (!address)
+    address = get_accessibility_bus_address_dbus ();
+  if (!address)
+    return NULL;
+
+  dbus_error_init (&error);
+  bus = dbus_connection_open (address, &error);
+  if (!bus)
+    {
+      g_warning ("Couldn't connect to accessibility bus: %s", error.message);
+      return NULL;
+    }
+  else
+    {
+      if (!dbus_bus_register (bus, &error))
+       {
+         g_warning ("Couldn't register with accessibility bus: %s", error.message);
+         return NULL;
+       }
+    }
+  
+  return bus;
+}