Change log level to prevent abort.
[platform/upstream/at-spi2-core.git] / atspi / atspi-misc.c
index 12135e3..6d69d21 100644 (file)
 #include "atspi-gmain.h"
 #include <stdio.h>
 #include <string.h>
+#include <ctype.h>
+
+/* This value is not fixed, could be changed. */
+#define HASH_TABLE_SIZE_MAX 3000
 
 static void handle_get_items (DBusPendingCall *pending, void *user_data);
 
@@ -124,7 +128,10 @@ _atspi_bus ()
   if (!bus)
     atspi_init ();
   if (!bus)
-    g_error ("AT-SPI: Couldn't connect to accessibility bus. Is at-spi-bus-launcher running?");
+    {
+      g_warning ("AT-SPI: Couldn't connect to accessibility bus. Is at-spi-bus-launcher running?");
+      exit(0);
+    }
   return bus;
 }
 
@@ -147,17 +154,10 @@ cleanup ()
       g_hash_table_destroy (refs);
     }
 
-  if (bus)
-    {
-      dbus_connection_close (bus);
-      dbus_connection_unref (bus);
-      bus = NULL;
-    }
-
   cleanup_deferred_message();
 
   if (!desktop)
-    return;
+    goto end;
 
   /* TODO: Do we need this code, or should we just dispose the desktop? */
   for (i = desktop->children->len - 1; i >= 0; i--)
@@ -171,6 +171,14 @@ cleanup ()
   g_object_run_dispose (G_OBJECT (desktop->parent.app));
   g_object_unref (desktop);
   desktop = NULL;
+
+end:
+  if (bus)
+    {
+      dbus_connection_close (bus);
+      dbus_connection_unref (bus);
+      bus = NULL;
+    }
 }
 
 static gboolean atspi_inited = FALSE;
@@ -300,6 +308,13 @@ ref_accessible (const char *app_name, const char *path)
   a = _atspi_accessible_new (app, path);
   if (!a)
     return NULL;
+
+  if (g_hash_table_size (app->hash) > HASH_TABLE_SIZE_MAX)
+  {
+     g_warning ("Accessible hash table is bigger than MAX: %d\n", HASH_TABLE_SIZE_MAX);
+     g_hash_table_remove_all(app->hash);
+  }
+
   g_hash_table_insert (app->hash, g_strdup (a->parent.path), g_object_ref (a));
   return a;
 }
@@ -368,6 +383,21 @@ handle_remove_accessible (DBusConnection *bus, DBusMessage *message, void *user_
   return DBUS_HANDLER_RESULT_HANDLED;
 }
 
+void
+remove_accessible_from_app_hash (const char *app_name, AtspiAccessible *a)
+{
+  AtspiApplication *app;
+
+  if (!a) return;
+
+  app = get_application (app_name);
+  if (!app) return;
+
+  if (!g_hash_table_lookup (app->hash, a->parent.path)) return;
+
+  g_hash_table_remove (app->hash, a->parent.path);
+}
+
 static DBusHandlerResult
 handle_name_owner_changed (DBusConnection *bus, DBusMessage *message, void *user_data)
 {
@@ -459,12 +489,16 @@ add_accessible_from_iter (DBusMessageIter *iter)
     dbus_message_iter_get_basic (&iter_struct, &index);
     if (index >= 0 && accessible->accessible_parent)
     {
-      if (index >= accessible->accessible_parent->children->len) {
+      if (index >= accessible->accessible_parent->children->len)
+      {
         /* There is no room for this object */
         g_ptr_array_set_size (accessible->accessible_parent->children, index + 1);
-      } else {
+      }
+      else
+      {
         /* This place is already taken - let's free this place with dignity */
-        g_object_unref (g_ptr_array_index (accessible->accessible_parent->children, index));
+        if (g_ptr_array_index (accessible->accessible_parent->children, index))
+          g_object_unref (g_ptr_array_index (accessible->accessible_parent->children, index));
       }
       g_ptr_array_index (accessible->accessible_parent->children, index) = g_object_ref (accessible);
     }
@@ -781,13 +815,13 @@ destroy_deferred_message_item(gpointer ptr)
   BusDataClosure *c = ptr;
   dbus_message_unref (c->message);
   dbus_connection_unref (c->bus);
-  g_free(c);
+  g_free (c);
 }
 
 static void
 cleanup_deferred_message(void)
 {
-  g_queue_free_full(deferred_messages, destroy_deferred_message_item);
+  g_queue_free_full (deferred_messages, destroy_deferred_message_item);
   deferred_messages = NULL;
 }
 
@@ -875,43 +909,6 @@ atspi_dbus_filter (DBusConnection *bus, DBusMessage *message, void *data)
   return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 }
 
-/*
- * Returns a 'canonicalized' value for DISPLAY,
- * with the screen number stripped off if present.
- *
- * TODO: Avoid having duplicate functions for this here and in at-spi2-atk
- */
-static gchar *
-spi_display_name (void)
-{
-  char *canonical_display_name = NULL;
-  const gchar *display_env = g_getenv ("AT_SPI_DISPLAY");
-
-  if (!display_env)
-    {
-      display_env = g_getenv ("DISPLAY");
-      if (!display_env || !display_env[0])
-        return NULL;
-      else
-        {
-          gchar *display_p, *screen_p;
-          canonical_display_name = g_strdup (display_env);
-          display_p = g_utf8_strrchr (canonical_display_name, -1, ':');
-          screen_p = g_utf8_strrchr (canonical_display_name, -1, '.');
-          if (screen_p && display_p && (screen_p > display_p))
-            {
-              *screen_p = '\0';
-            }
-        }
-    }
-  else
-    {
-      canonical_display_name = g_strdup (display_env);
-    }
-
-  return canonical_display_name;
-}
-
 /**
  * atspi_init:
  *
@@ -1278,7 +1275,7 @@ _atspi_dbus_get_property (gpointer obj, const char *interface, const char *name,
   process_deferred_messages ();
   if (!reply)
   {
-    // TODO: throw exception
+    /* TODO: throw exception */
     goto done;
   }
 
@@ -1305,14 +1302,12 @@ _atspi_dbus_get_property (gpointer obj, const char *interface, const char *name,
   }
   if (!strcmp (type, "(so)"))
   {
-    g_object_unref(*(AtspiAccessible**)data);
     *((AtspiAccessible **)data) = _atspi_dbus_return_accessible_from_iter (&iter_variant);
   }
   else
   {
     if (type [0] == 's')
     {
-      g_free(*(char**)data);
       *(char**) data = NULL;
     }
 
@@ -1506,6 +1501,43 @@ _atspi_error_quark (void)
  * Gets the IOR from the XDisplay.
  */
 #ifdef HAVE_X11
+/*
+ * Returns a 'canonicalized' value for DISPLAY,
+ * with the screen number stripped off if present.
+ *
+ * TODO: Avoid having duplicate functions for this here and in at-spi2-atk
+ */
+static gchar *
+spi_display_name (void)
+{
+  char *canonical_display_name = NULL;
+  const gchar *display_env = g_getenv ("AT_SPI_DISPLAY");
+
+  if (!display_env)
+    {
+      display_env = g_getenv ("DISPLAY");
+      if (!display_env || !display_env[0])
+        return NULL;
+      else
+        {
+          gchar *display_p, *screen_p;
+          canonical_display_name = g_strdup (display_env);
+          display_p = g_utf8_strrchr (canonical_display_name, -1, ':');
+          screen_p = g_utf8_strrchr (canonical_display_name, -1, '.');
+          if (screen_p && display_p && (screen_p > display_p))
+            {
+              *screen_p = '\0';
+            }
+        }
+    }
+  else
+    {
+      canonical_display_name = g_strdup (display_env);
+    }
+
+  return canonical_display_name;
+}
+
 static char *
 get_accessibility_bus_address_x11 (void)
 {
@@ -1568,7 +1600,7 @@ get_accessibility_bus_address_dbus (void)
   dbus_error_init (&error);
   reply = dbus_connection_send_with_reply_and_block (session_bus,
                                                     message,
-                                                    -1,
+                                                    15000,
                                                     &error);
   dbus_message_unref (message);
 
@@ -1941,3 +1973,33 @@ _atspi_prepare_screen_reader_interface ()
   dbus_connection_add_filter (a11y_bus, screen_reader_filter, NULL, NULL);
   return TRUE;
 }
+
+gchar *
+_atspi_strdup_and_adjust_for_dbus (const char *s)
+{
+  gchar *d = g_strdup (s);
+  gchar *p;
+  int parts = 0;
+
+  if (!d)
+    return NULL;
+
+  for (p = d; *p; p++)
+  {
+    if (*p == '-')
+    {
+      memmove (p, p + 1, g_utf8_strlen (p, -1));
+      *p = toupper (*p);
+    }
+    else if (*p == ':')
+    {
+      parts++;
+      if (parts == 2)
+        break;
+      p [1] = toupper (p [1]);
+    }
+  }
+
+  d [0] = toupper (d [0]);
+  return d;
+}