[at-spi2-core] Initial pass at adding i18n and proper object disposal



commit f8230043c35757edf02c2f8ce7217f51294e52e8
Author: Mike Gorse <mgorse novell com>
Date:   Wed Dec 29 19:12:55 2010 -0500

    Initial pass at adding i18n and proper object disposal
    
    Objects are now "disposed" when RemoveAccessible is received or the application
    goes away.  This allows the objects to be dereferenced and properly cleaned up.
    Also fix some related bugs and add i18n.
    Some reference leaks remain, however.

 Makefile.am                  |    2 +-
 atspi/atspi-accessible.c     |  103 ++++++++++++++++++++++++++++-------------
 atspi/atspi-application.c    |   34 +++++++++++++-
 atspi/atspi-event-listener.c |    7 ++-
 atspi/atspi-hyperlink.c      |   11 -----
 atspi/atspi-matchrule.c      |   23 +++++++++-
 atspi/atspi-misc-private.h   |   20 ++++++++
 atspi/atspi-misc.c           |   66 +++++++++++++++++----------
 atspi/atspi-object.c         |   18 +++++++-
 atspi/atspi-private.h        |    2 +
 atspi/atspi-relation.c       |    6 ++-
 atspi/atspi-stateset.c       |    2 +
 configure.ac                 |    9 +++-
 po/Makefile.in.in            |    1 +
 po/POTFILES.in               |    3 +
 15 files changed, 227 insertions(+), 80 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 394c0fd..5b96147 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5,6 +5,6 @@ INTROSPECTION_GIRS =
 INTROSPECTION_SCANNER_ARGS = --add-include-path=$(srcdir)
 INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir)
 
-SUBDIRS=registryd xml bus dbind atspi doc
+SUBDIRS=po registryd xml bus dbind atspi doc
 
 ACLOCAL_AMFLAGS=-I m4
diff --git a/atspi/atspi-accessible.c b/atspi/atspi-accessible.c
index 2a00d36..3325499 100644
--- a/atspi/atspi-accessible.c
+++ b/atspi/atspi-accessible.c
@@ -91,17 +91,79 @@ G_DEFINE_TYPE_WITH_CODE (AtspiAccessible, atspi_accessible, ATSPI_TYPE_OBJECT,
                          G_IMPLEMENT_INTERFACE (ATSPI_TYPE_TEXT, atspi_text_interface_init)
                          G_IMPLEMENT_INTERFACE (ATSPI_TYPE_VALUE, atspi_value_interface_init))
 
+#ifdef DEBUG_REF_COUNTS
+static gint accessible_count = 0;
+#endif
+
 static void
 atspi_accessible_init (AtspiAccessible *accessible)
 {
+#ifdef DEBUG_REF_COUNTS
+  accessible_count++;
+  printf("at-spi: init: %d objects\n", accessible_count);
+#endif
+}
+
+static void
+atspi_accessible_dispose (GObject *object)
+{
+  AtspiAccessible *accessible = ATSPI_ACCESSIBLE (object);
+  gboolean cached;
+  AtspiEvent e;
+  AtspiAccessible *parent;
+
+  /* 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;
+  _atspi_send_event (&e);
+
+  if (accessible->states)
+  {
+    g_object_unref (accessible->states);
+    accessible->states = NULL;
+  }
+
+  parent = accessible->accessible_parent;
+  if (parent && parent->children)
+  {
+    GList*ls = g_list_find (parent->children, accessible);
+    if(ls)
+    {
+      gboolean replace = (ls == parent->children);
+      ls = g_list_remove (ls, accessible);
+      if (replace)
+        parent->children = ls;
+      g_object_unref (object);
+    }
+  }
+
+  if (parent)
+  {
+    g_object_unref (parent);
+    accessible->accessible_parent = NULL;
+  }
+
+  G_OBJECT_CLASS (atspi_accessible_parent_class) ->dispose (object);
 }
 
 static void
-atspi_accessible_finalize (GObject *obj)
+atspi_accessible_finalize (GObject *object)
 {
-  /*AtspiAccessible *accessible = ATSPI_ACCESSIBLE (obj); */
+  AtspiAccessible *accessible = ATSPI_ACCESSIBLE (object);
+
+    g_free (accessible->description);
+    g_free (accessible->name);
+
+#ifdef DEBUG_REF_COUNTS
+  accessible_count--;
+  printf("at-spi: finalize: %d objects\n", accessible_count);
+#endif
 
-  /* TODO: Unref parent/children, etc. */
+  G_OBJECT_CLASS (atspi_accessible_parent_class)
+    ->finalize (object);
 }
 
 static void
@@ -109,6 +171,7 @@ atspi_accessible_class_init (AtspiAccessibleClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
+  object_class->dispose = atspi_accessible_dispose;
   object_class->finalize = atspi_accessible_finalize;
 }
 
@@ -631,12 +694,14 @@ atspi_accessible_get_application (AtspiAccessible *obj, GError **error)
 {
   AtspiAccessible *parent;
 
+  g_object_ref (obj);
   for (;;)
   {
     parent = atspi_accessible_get_parent (obj, NULL);
     if (!parent || parent == obj ||
         atspi_accessible_get_role (parent, NULL) == ATSPI_ROLE_DESKTOP_FRAME)
-    return g_object_ref (obj);
+    return obj;
+    g_object_unref (obj);
     obj = parent;
   }
 }
@@ -730,13 +795,8 @@ atspi_accessible_is_application (AtspiAccessible *obj)
 gboolean
 atspi_accessible_is_collection (AtspiAccessible *obj)
 {
-#if 0
-     g_warning ("Collections not implemented");
      return _atspi_accessible_is_a (obj,
 			      atspi_interface_collection);
-#else
-     return FALSE;
-#endif
 }
 
 /**
@@ -868,7 +928,7 @@ atspi_accessible_is_streamable_content (AtspiAccessible *obj)
   return _atspi_accessible_is_a (obj,
 			      atspi_interface_streamable_content);
 #else
-  g_warning ("Streamable content not implemented");
+  g_warning (_("Streamable content not implemented"));
   return FALSE;
 #endif
 }
@@ -1198,29 +1258,6 @@ atspi_accessible_get_interfaces (AtspiAccessible *obj)
   return ret;
 }
 
-/* TODO: Move to a finalizer */
-static void
-cspi_object_destroyed (AtspiAccessible *accessible)
-{
-  gboolean cached;
-  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;
-  _atspi_send_event (&e);
-
-    g_free (accessible->parent.path);
-
-    if (accessible->states)
-      g_object_unref (accessible->states);
-    g_free (accessible->description);
-    g_free (accessible->name);
-}
-
 AtspiAccessible *
 atspi_accessible_new (AtspiApplication *app, const gchar *path)
 {
diff --git a/atspi/atspi-application.c b/atspi/atspi-application.c
index 6dbadce..c2202a1 100644
--- a/atspi/atspi-application.c
+++ b/atspi/atspi-application.c
@@ -31,12 +31,41 @@ atspi_application_init (AtspiApplication *application)
 }
 
 static void
-atspi_application_finalize (GObject *obj)
+dispose_accessible (gpointer key, gpointer obj_data, gpointer data)
 {
-  AtspiApplication *application = ATSPI_APPLICATION (obj);
+  g_object_run_dispose (obj_data);
+}
+
+static void
+atspi_application_dispose (GObject *object)
+{
+  AtspiApplication *application = ATSPI_APPLICATION (object);
+
+  if (application->bus)
+  {
+    dbus_connection_unref (application->bus);
+    application->bus = NULL;
+  }
+
+  if (application->hash)
+  {
+    g_hash_table_foreach (application->hash, dispose_accessible, NULL);
+    g_hash_table_unref (application->hash);
+    application->hash = NULL;
+  }
+
+  G_OBJECT_CLASS (atspi_application_parent_class)->dispose (object);
+}
+
+static void
+atspi_application_finalize (GObject *object)
+{
+  AtspiApplication *application = ATSPI_APPLICATION (object);
 
   if (application->bus_name)
     g_free (application->bus_name);
+
+  G_OBJECT_CLASS (atspi_application_parent_class)->finalize (object);
 }
 
 static void
@@ -44,6 +73,7 @@ atspi_application_class_init (AtspiApplicationClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
+  object_class->dispose = atspi_application_dispose;
   object_class->finalize = atspi_application_finalize;
 }
 
diff --git a/atspi/atspi-event-listener.c b/atspi/atspi-event-listener.c
index 565f789..9156b3b 100644
--- a/atspi/atspi-event-listener.c
+++ b/atspi/atspi-event-listener.c
@@ -185,6 +185,9 @@ cache_process_children_changed (AtspiEvent *event)
   else if (g_list_find (event->source->children, child))
   {
     event->source->children = g_list_remove (event->source->children, child);
+    if (child == child->parent.app->root)
+      g_object_run_dispose (child->parent.app);
+    g_object_unref (child);
   }
 }
 
@@ -752,7 +755,7 @@ atspi_dbus_handle_event (DBusConnection *bus, DBusMessage *message, void *data)
 
   if (strcmp (signature, "siiv(so)") != 0)
   {
-    g_warning ("Got invalid signature %s for signal %s from interface %s\n", signature, member, category);
+    g_warning (_("Got invalid signature %s for signal %s from interface %s\n"), signature, member, category);
     return;
   }
 
@@ -773,7 +776,6 @@ atspi_dbus_handle_event (DBusConnection *bus, DBusMessage *message, void *data)
   dbus_message_iter_get_basic (&iter, &detail1);
   e.detail1 = detail1;
   dbus_message_iter_next (&iter);
-  g_return_val_if_fail (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_INT32, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
   dbus_message_iter_get_basic (&iter, &detail2);
   e.detail2 = detail2;
   dbus_message_iter_next (&iter);
@@ -830,6 +832,7 @@ atspi_dbus_handle_event (DBusConnection *bus, DBusMessage *message, void *data)
 	accessible = _atspi_dbus_return_accessible_from_iter (&iter_variant);
 	g_value_init (&e.any_data, ATSPI_TYPE_ACCESSIBLE);
 	g_value_set_instance (&e.any_data, accessible);
+	g_object_unref (accessible);	/* value now owns it */
       }
       break;
     }
diff --git a/atspi/atspi-hyperlink.c b/atspi/atspi-hyperlink.c
index ced8e27..a8ca42a 100644
--- a/atspi/atspi-hyperlink.c
+++ b/atspi/atspi-hyperlink.c
@@ -31,19 +31,8 @@ atspi_hyperlink_init (AtspiHyperlink *hyperlink)
 }
 
 static void
-atspi_hyperlink_finalize (GObject *obj)
-{
-  /*AtspiHyperlink *hyperlink = ATSPI_HYPERLINK (obj); */
-
-  /* TODO: Unref parent/children, etc. */
-}
-
-static void
 atspi_hyperlink_class_init (AtspiHyperlinkClass *klass)
 {
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-  object_class->finalize = atspi_hyperlink_finalize;
 }
 
 AtspiHyperlink *
diff --git a/atspi/atspi-matchrule.c b/atspi/atspi-matchrule.c
index f706f56..3083bf1 100644
--- a/atspi/atspi-matchrule.c
+++ b/atspi/atspi-matchrule.c
@@ -31,17 +31,35 @@ atspi_match_rule_init (AtspiMatchRule *match_rule)
 }
 
 static void
-atspi_match_rule_finalize (GObject *obj)
+atspi_match_rule_dispose (GObject *object)
 {
-  AtspiMatchRule *rule = ATSPI_MATCH_RULE (obj);
+  AtspiMatchRule *rule = ATSPI_MATCH_RULE (object);
 
   if (rule->states)
+  {
     g_object_unref (rule->states);
+    rule->states = NULL;
+  }
+
   if (rule->attributes)
+  {
     g_hash_table_unref (rule->attributes);
+    rule->attributes = NULL;
+  }
+
+  G_OBJECT_CLASS (atspi_match_rule_parent_class)->dispose (object);
+}
+
+static void
+atspi_match_rule_finalize (GObject *object)
+{
+  AtspiMatchRule *rule = ATSPI_MATCH_RULE (object);
+
   /* TODO: Check that interfaces don't leak */
   if (rule->interfaces)
     g_array_free (rule->interfaces, TRUE);
+
+  G_OBJECT_CLASS (atspi_match_rule_parent_class)->finalize (object);
 }
 
 static void
@@ -49,6 +67,7 @@ atspi_match_rule_class_init (AtspiMatchRuleClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
+  object_class->dispose = atspi_match_rule_dispose;
   object_class->finalize = atspi_match_rule_finalize;
 }
 
diff --git a/atspi/atspi-misc-private.h b/atspi/atspi-misc-private.h
index ec87049..4814719 100644
--- a/atspi/atspi-misc-private.h
+++ b/atspi/atspi-misc-private.h
@@ -158,4 +158,24 @@ void _atspi_dbus_set_state (AtspiAccessible *accessible, DBusMessageIter *iter);
     dbus_message_unref (message); \
     return (ret); \
   }
+
+
+/**
+ * ATSPI_ERROR:
+ *
+ * Error domain for AT-SPI IPC failures. Errors in this domain will
+ * be from the #ATSPIAtspiError enumeration. See #GError for information on
+ * error domains.
+ */
+#define ATSPI_ERROR atspi_error_quark()
+GQuark atspi_error_quark (void);
+
+/**
+ * AtspiError:
+ * @ATSPI_APPLICATION_NO_LONGER_EXISTS: The application has quit.
+ */
+typedef enum
+{
+  ATSPI_ERROR_APPLICATION_GONE
+} AtspiError;
 #endif	/* _ATSPI_MISC_PRIVATE_H_ */
diff --git a/atspi/atspi-misc.c b/atspi/atspi-misc.c
index 1bc1554..d8feb32 100644
--- a/atspi/atspi-misc.c
+++ b/atspi/atspi-misc.c
@@ -232,7 +232,7 @@ ref_accessible (const char *app_name, const char *path)
   a = atspi_accessible_new (app, path);
   if (!a)
     return NULL;
-  g_hash_table_insert (app->hash, a->parent.path, a);
+  g_hash_table_insert (app->hash, g_strdup (a->parent.path), a);
   g_object_ref (a);	/* for the hash */
   return a;
 }
@@ -285,24 +285,21 @@ handle_remove_accessible (DBusConnection *bus, DBusMessage *message, void *user_
 
   if (strcmp (signature, "(so)") != 0)
   {
-    g_warning ("at-spi: Unknown signature %s for RemoveAccessible", signature);
+    g_warning (_("AT-SPI: Unknown signature %s for RemoveAccessible"), signature);
     return DBUS_HANDLER_RESULT_HANDLED;
   }
 
   dbus_message_iter_init (message, &iter);
   dbus_message_iter_recurse (&iter, &iter_struct);
   dbus_message_iter_get_basic (&iter_struct, &sender);
+  dbus_message_iter_next (&iter_struct);
   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);
-    g_object_unref (a);
-  }
-  g_hash_table_remove (app->hash, app->bus_name);
+  g_object_run_dispose (G_OBJECT (a));
+  g_hash_table_remove (app->hash, a->parent.path);
   g_object_unref (a);	/* unref our own ref */
   return DBUS_HANDLER_RESULT_HANDLED;
 }
@@ -326,7 +323,7 @@ add_app_to_desktop (AtspiAccessible *a, const char *bus_name)
   }
   else
   {
-    g_warning ("Error calling getRoot for %s: %s", bus_name, error.message);
+    g_warning (_("AT-SPI: Error calling getRoot for %s: %s"), bus_name, error.message);
   }
   return FALSE;
 }
@@ -369,7 +366,6 @@ remove_app_from_desktop (AtspiAccessible *a, const char *bus_name)
   }
   if (!l)
   {
-    g_warning ("Removing unregistered app %s; doing nothing\n", bus_name);
     return FALSE;
   }
   send_children_changed (a, child, FALSE);
@@ -487,7 +483,7 @@ handle_get_items (DBusPendingCall *pending, void *user_data)
     const char *error = NULL;
     dbus_message_get_args (reply, NULL, DBUS_TYPE_STRING, &error,
                            DBUS_TYPE_INVALID);
-    g_warning ("Atspi: Error in GetItems, sender=%s, error=%s", sender, error);
+    g_warning (_("AT-SPI: Error in GetItems, sender=%s, error=%s"), sender, error);
     dbus_message_unref (reply);
     return;
   }
@@ -512,6 +508,7 @@ ref_accessible_desktop (AtspiApplication *app)
   gint i;
   DBusMessage *message, *reply;
   DBusMessageIter iter, iter_array;
+  gchar *bus_name_dup;
 
   if (desktop)
   {
@@ -550,6 +547,12 @@ ref_accessible_desktop (AtspiApplication *app)
     add_app_to_desktop (desktop, app_name);
   }
   dbus_message_unref (reply);
+
+  /* Record the alternate name as an alias for org.a11y.atspi.Registry */
+  bus_name_dup = g_strdup (dbus_message_get_sender (reply));
+  if (bus_name_dup)
+    g_hash_table_insert (app_hash, bus_name_dup, app);
+
   return desktop;
 }
 
@@ -583,7 +586,7 @@ _atspi_dbus_return_accessible_from_message (DBusMessage *message)
   }
   else
   {
-    g_warning ("Atspi: Called _atspi_dbus_return_accessible_from_message with strange signature %s", signature);
+    g_warning (_("AT-SPI: Called _atspi_dbus_return_accessible_from_message with strange signature %s"), signature);
   }
   dbus_message_unref (message);
   return retval;
@@ -612,7 +615,7 @@ _atspi_dbus_return_hyperlink_from_message (DBusMessage *message)
   }
   else
   {
-    g_warning ("Atspi: Called _atspi_dbus_return_hyperlink_from_message with strange signature %s", signature);
+    g_warning (_("AT-SPI: Called _atspi_dbus_return_hyperlink_from_message with strange signature %s"), signature);
   }
   dbus_message_unref (message);
   return retval;
@@ -639,7 +642,8 @@ handle_add_accessible (DBusConnection *bus, DBusMessage *message, void *user_dat
 
   if (strcmp (dbus_message_get_signature (message), cache_signal_type) != 0)
   {
-    g_warning ("atspi: AddAccessible with unknown signature %s\n", dbus_message_get_signature (message));
+    g_warning (_("AT-SPI: AddAccessible with unknown signature %s\n"),
+               dbus_message_get_signature (message));
     return;
   }
 
@@ -828,7 +832,7 @@ get_accessibility_bus ()
   bridge_display = XOpenDisplay (spi_display_name ());
   if (!bridge_display)
     {
-      g_warning ("AT_SPI: Could not get the display\n");
+      g_warning (_("AT-SPI: Could not get the display\n"));
       return NULL;
     }
 
@@ -845,11 +849,11 @@ get_accessibility_bus ()
   if (data == NULL)
     {
       g_warning
-        ("AT-SPI: Accessibility bus not found - Using session bus.\n");
+        (_("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);
+          g_warning (_("AT-SPI: Couldn't connect to bus: %s\n"), error.message);
           return NULL;
         }
     }
@@ -858,14 +862,14 @@ get_accessibility_bus ()
       bus = dbus_connection_open (data, &error);
       if (!bus)
         {
-          g_warning ("AT-SPI: Couldn't connect to bus: %s\n", error.message);
+          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);
+              g_warning (_("AT-SPI: Couldn't register with bus: %s\n"), error.message);
               return NULL;
             }
         }
@@ -1046,6 +1050,13 @@ _atspi_dbus_call_partial_va (gpointer obj,
 
   dbus_error_init (&err);
 
+  if (!aobj->app || !aobj->app->bus)
+  {
+    g_set_error_literal (error, ATSPI_ERROR, ATSPI_ERROR_APPLICATION_GONE,
+                          _("The application no longer exists"));
+    goto out;
+  }
+
     msg = dbus_message_new_method_call (aobj->app->bus_name, aobj->path, interface, method);
     if (!msg)
         goto out;
@@ -1100,13 +1111,13 @@ _atspi_dbus_get_property (gpointer obj, const char *interface, const char *name,
   dbus_message_iter_init (reply, &iter);
   if (dbus_message_iter_get_arg_type (&iter) != 'v')
   {
-    g_warning ("at-spi: expected a variant when fetching %s from interface %s; got %s\n", name, interface, dbus_message_get_signature (reply));
+    g_warning (_("AT-SPI: expected a variant when fetching %s from interface %s; got %s\n"), name, interface, dbus_message_get_signature (reply));
     goto done;
   }
   dbus_message_iter_recurse (&iter, &iter_variant);
   if (dbus_message_iter_get_arg_type (&iter_variant) != type[0])
   {
-    g_warning ("atspi_dbus_get_property: Wrong type: expected %s, got %c\n", type, dbus_message_iter_get_arg_type (&iter_variant));
+    g_warning (_("atspi_dbus_get_property: Wrong type: expected %s, got %c\n"), type, dbus_message_iter_get_arg_type (&iter_variant));
     goto done;
   }
   if (!strcmp (type, "(so)"))
@@ -1140,7 +1151,7 @@ _atspi_dbus_send_with_reply_and_block (DBusMessage *message)
   _atspi_process_deferred_messages ((gpointer)TRUE);
   dbus_message_unref (message);
   if (err.message)
-    g_warning ("Atspi: Got error: %s\n", err.message);
+    g_warning (_("AT-SPI: Got error: %s\n"), err.message);
   return reply;
 }
 
@@ -1235,7 +1246,7 @@ _atspi_dbus_set_interfaces (AtspiAccessible *accessible, DBusMessageIter *iter)
     n = _atspi_get_iface_num (iface);
     if (n == -1)
     {
-      g_warning ("at-spi: Unknown interface %s", iface);
+      g_warning (_("AT-SPI: Unknown interface %s"), iface);
     }
     else
       accessible->interfaces |= (1 << n);
@@ -1255,7 +1266,7 @@ _atspi_dbus_set_state (AtspiAccessible *accessible, DBusMessageIter *iter)
   dbus_message_iter_get_fixed_array (&iter_array, &states, &count);
   if (count != 2)
   {
-    g_warning ("at-spi: expected 2 values in states array; got %d\n", count);
+    g_warning (_("AT-SPI: expected 2 values in states array; got %d\n"), count);
     if (!accessible->states)
       accessible->states = _atspi_state_set_new_internal (accessible, 0);
   }
@@ -1270,3 +1281,10 @@ _atspi_dbus_set_state (AtspiAccessible *accessible, DBusMessageIter *iter)
   }
   accessible->cached_properties |= ATSPI_CACHE_STATES;
 }
+
+GQuark
+atspi_error_quark (void)
+{
+  return g_quark_from_static_string ("atspi_error");
+}
+
diff --git a/atspi/atspi-object.c b/atspi/atspi-object.c
index f69d350..3545845 100644
--- a/atspi/atspi-object.c
+++ b/atspi/atspi-object.c
@@ -31,14 +31,27 @@ atspi_object_init (AtspiObject *obj)
 }
 
 static void
-atspi_object_finalize (GObject *obj)
+atspi_object_dispose (GObject *object)
 {
-  AtspiObject *aobj = ATSPI_OBJECT (obj);
+  AtspiObject *aobj = ATSPI_OBJECT (object);
 
   if (aobj->app)
+  {
     g_object_unref (aobj->app);
+    aobj->app = NULL;
+  }
+
+  G_OBJECT_CLASS (atspi_object_parent_class)->dispose (object);
+}
+
+static void
+atspi_object_finalize (GObject *object)
+{
+  AtspiObject *aobj = ATSPI_OBJECT (object);
 
   g_free (aobj->path);
+
+  G_OBJECT_CLASS (atspi_object_parent_class)->finalize (object);
 }
 
 static void
@@ -46,5 +59,6 @@ atspi_object_class_init (AtspiObjectClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
+  object_class->dispose = atspi_object_dispose;
   object_class->finalize = atspi_object_finalize;
 }
diff --git a/atspi/atspi-private.h b/atspi/atspi-private.h
index b396be8..9977be7 100644
--- a/atspi/atspi-private.h
+++ b/atspi/atspi-private.h
@@ -30,6 +30,8 @@
 #include "atspi-matchrule-private.h"
 #include "atspi-misc-private.h"
 
+#include "glib/gi18n.h"
+
 #include "atspi.h"
 
 #endif	/* _ATSPI_PRIVATE_H_ */
diff --git a/atspi/atspi-relation.c b/atspi/atspi-relation.c
index 6fc5591..cbd6b2d 100644
--- a/atspi/atspi-relation.c
+++ b/atspi/atspi-relation.c
@@ -116,14 +116,16 @@ atspi_relation_init (AtspiRelation *relation)
 }
 
 static void
-atspi_relation_finalize (GObject *obj)
+atspi_relation_finalize (GObject *object)
 {
-  AtspiRelation *relation = ATSPI_RELATION (obj);
+  AtspiRelation *relation = ATSPI_RELATION (object);
   gint i;
 
   for (i = 0; i < relation->targets->len; i++)
   g_object_unref (g_array_index (relation->targets, AtspiAccessible *, i));
   g_array_free (relation->targets, TRUE);
+
+  G_OBJECT_CLASS (atspi_relation_parent_class)->finalize (object);
 }
 
 static void
diff --git a/atspi/atspi-stateset.c b/atspi/atspi-stateset.c
index 958b734..e4adaa0 100644
--- a/atspi/atspi-stateset.c
+++ b/atspi/atspi-stateset.c
@@ -197,6 +197,8 @@ gboolean
 atspi_state_set_contains (AtspiStateSet *set,
 			     AtspiStateType state)
 {
+  if (!set)
+    return FALSE;
   refresh_states (set);
   return (set->states & (1 << state)) ? TRUE : FALSE;
 }
diff --git a/configure.ac b/configure.ac
index 481cea8..3d82d3f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -28,6 +28,13 @@ PKG_PROG_PKG_CONFIG
 
 AC_CONFIG_HEADERS([config.h])
 
+dnl translation of at-spi strings
+IT_PROG_INTLTOOL([0.40.0])
+
+
+GETTEXT_PACKAGE="${PACKAGE}"
+AC_SUBST(GETTEXT_PACKAGE)
+
 PKG_CHECK_MODULES(DBUS, [dbus-1 >= 1.0])
 AC_SUBST(DBUS_LIBS)
 AC_SUBST(DBUS_CFLAGS)
@@ -190,7 +197,7 @@ DBIND_CHECK_ALIGNOF(dbind_struct)
 GTK_DOC_CHECK([1.09])
 
 CPPFLAGS=$orig_CPPFLAGS 
-AC_CONFIG_FILES([Makefile
+AC_CONFIG_FILES([Makefile po/Makefile.in
 	xml/Makefile
 	dbind/Makefile
 dbind/dbind-config.h
diff --git a/po/Makefile.in.in b/po/Makefile.in.in
new file mode 120000
index 0000000..e4713cf
--- /dev/null
+++ b/po/Makefile.in.in
@@ -0,0 +1 @@
+/usr/share/intltool/Makefile.in.in
\ No newline at end of file
diff --git a/po/POTFILES.in b/po/POTFILES.in
new file mode 100644
index 0000000..9f476bd
--- /dev/null
+++ b/po/POTFILES.in
@@ -0,0 +1,3 @@
+# List of source files containing translatable strings.
+# Please keep this file sorted alphabetically.
+atspi/atspi-misc.c



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]