summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--atk-adaptor/accessible-cache.c14
-rw-r--r--atk-adaptor/accessible-cache.h2
-rw-r--r--atk-adaptor/accessible-leasing.c4
-rw-r--r--atk-adaptor/accessible-register.c29
-rw-r--r--atk-adaptor/accessible-register.h2
-rw-r--r--atk-adaptor/adaptors/cache-adaptor.c14
-rw-r--r--atk-adaptor/bridge.c76
-rw-r--r--atk-adaptor/event.c12
-rw-r--r--droute/droute.c27
-rw-r--r--droute/droute.h9
10 files changed, 135 insertions, 54 deletions
diff --git a/atk-adaptor/accessible-cache.c b/atk-adaptor/accessible-cache.c
index ad39819..4d5cdb3 100644
--- a/atk-adaptor/accessible-cache.c
+++ b/atk-adaptor/accessible-cache.c
@@ -125,8 +125,8 @@ spi_cache_init (SpiCache * cache)
add_subtree (cache, spi_global_app_data->root);
- atk_add_global_event_listener (child_added_listener,
- "Gtk:AtkObject:children-changed");
+ cache->child_added_listener = atk_add_global_event_listener (child_added_listener,
+ "Gtk:AtkObject:children-changed");
g_signal_connect (G_OBJECT (spi_global_app_data->root),
"children-changed::add",
@@ -141,7 +141,15 @@ spi_cache_finalize (GObject * object)
while (!g_queue_is_empty (cache->add_traversal))
g_object_unref (G_OBJECT (g_queue_pop_head (cache->add_traversal)));
g_queue_free (cache->add_traversal);
- g_free (cache->objects);
+ g_hash_table_unref (cache->objects);
+
+ g_signal_handlers_disconnect_by_func (spi_global_register,
+ (GCallback) remove_object, cache);
+
+ g_signal_handlers_disconnect_by_func (G_OBJECT (spi_global_app_data->root),
+ (GCallback) toplevel_added_listener, NULL);
+
+ atk_remove_global_event_listener (cache->child_added_listener);
G_OBJECT_CLASS (spi_cache_parent_class)->finalize (object);
}
diff --git a/atk-adaptor/accessible-cache.h b/atk-adaptor/accessible-cache.h
index 1089c6f..2f5be06 100644
--- a/atk-adaptor/accessible-cache.h
+++ b/atk-adaptor/accessible-cache.h
@@ -44,6 +44,8 @@ struct _SpiCache
GHashTable * objects;
GQueue *add_traversal;
gint add_pending_idle;
+
+ guint child_added_listener;
};
struct _SpiCacheClass
diff --git a/atk-adaptor/accessible-leasing.c b/atk-adaptor/accessible-leasing.c
index f4d0e2f..4370bff 100644
--- a/atk-adaptor/accessible-leasing.c
+++ b/atk-adaptor/accessible-leasing.c
@@ -72,7 +72,9 @@ spi_leasing_finalize (GObject * object)
{
SpiLeasing *leasing = SPI_LEASING (object);
- g_free (leasing->expiry_queue);
+ if (leasing->expiry_func_id)
+ g_source_remove (leasing->expiry_func_id);
+ g_queue_free (leasing->expiry_queue);
G_OBJECT_CLASS (spi_leasing_parent_class)->finalize (object);
}
diff --git a/atk-adaptor/accessible-register.c b/atk-adaptor/accessible-register.c
index 83c1c6d..14f256f 100644
--- a/atk-adaptor/accessible-register.c
+++ b/atk-adaptor/accessible-register.c
@@ -121,11 +121,26 @@ spi_register_init (SpiRegister * reg)
}
static void
+deregister_object (gpointer data, GObject * gobj)
+{
+ SpiRegister *reg = SPI_REGISTER (data);
+
+ spi_register_deregister_object (reg, gobj, FALSE);
+}
+
+static void
+spi_register_remove_weak_ref (gpointer key, gpointer val, gpointer reg)
+{
+ g_object_weak_unref (val, deregister_object, reg);
+}
+
+static void
spi_register_finalize (GObject * object)
{
SpiRegister *reg = SPI_REGISTER (object);
- g_free (reg->ref2ptr);
+ g_hash_table_foreach (reg->ref2ptr, spi_register_remove_weak_ref, reg);
+ g_hash_table_unref (reg->ref2ptr);
G_OBJECT_CLASS (spi_register_parent_class)->finalize (object);
}
@@ -186,16 +201,8 @@ ref_to_path (guint ref)
* Removes the AtkObject from the reference lookup tables, meaning
* it is no longer exposed over D-Bus.
*/
-static void
-deregister_object (gpointer data, GObject * gobj)
-{
- SpiRegister *reg = SPI_REGISTER (data);
-
- spi_register_deregister_object (reg, gobj);
-}
-
void
-spi_register_deregister_object (SpiRegister *reg, GObject *gobj)
+spi_register_deregister_object (SpiRegister *reg, GObject *gobj, gboolean unref)
{
guint ref;
@@ -206,6 +213,8 @@ spi_register_deregister_object (SpiRegister *reg, GObject *gobj)
register_signals [OBJECT_DEREGISTERED],
0,
gobj);
+ if (unref)
+ g_object_weak_unref (gobj, deregister_object, reg);
g_hash_table_remove (reg->ref2ptr, GINT_TO_POINTER (ref));
#ifdef SPI_ATK_DEBUG
diff --git a/atk-adaptor/accessible-register.h b/atk-adaptor/accessible-register.h
index edbe3c2..5a62ebb 100644
--- a/atk-adaptor/accessible-register.h
+++ b/atk-adaptor/accessible-register.h
@@ -73,7 +73,7 @@ gchar *
spi_register_root_object_path ();
void
-spi_register_deregister_object (SpiRegister *reg, GObject *gobj);
+spi_register_deregister_object (SpiRegister *reg, GObject *gobj, gboolean unref);
/*---------------------------------------------------------------------------*/
diff --git a/atk-adaptor/adaptors/cache-adaptor.c b/atk-adaptor/adaptors/cache-adaptor.c
index 3b5540c..e221920 100644
--- a/atk-adaptor/adaptors/cache-adaptor.c
+++ b/atk-adaptor/adaptors/cache-adaptor.c
@@ -318,15 +318,11 @@ spi_initialize_cache (DRoutePath * path)
{
droute_path_add_interface (path, ATSPI_DBUS_INTERFACE_CACHE, spi_org_a11y_atspi_Cache, methods, NULL);
- g_signal_connect (spi_global_cache,
- "object-added",
- (GCallback) emit_cache_add,
- NULL);
-
- g_signal_connect (spi_global_cache,
- "object-removed",
- (GCallback) emit_cache_remove,
- NULL);
+ g_signal_connect (spi_global_cache, "object-added",
+ (GCallback) emit_cache_add, NULL);
+
+ g_signal_connect (spi_global_cache, "object-removed",
+ (GCallback) emit_cache_remove, NULL);
};
/*END------------------------------------------------------------------------*/
diff --git a/atk-adaptor/bridge.c b/atk-adaptor/bridge.c
index bcae3b9..d049731 100644
--- a/atk-adaptor/bridge.c
+++ b/atk-adaptor/bridge.c
@@ -54,6 +54,9 @@
/*---------------------------------------------------------------------------*/
+static DBusHandlerResult
+signal_filter (DBusConnection *bus, DBusMessage *message, void *user_data);
+
SpiBridge *spi_global_app_data = NULL;
/*static Display *bridge_display = NULL;*/
@@ -301,28 +304,6 @@ deregister_application (SpiBridge * app)
/*---------------------------------------------------------------------------*/
-static void
-exit_func (void)
-{
- if (!spi_global_app_data)
- {
- return;
- }
-
- spi_atk_tidy_windows ();
- spi_atk_deregister_event_listeners ();
- deregister_application (spi_global_app_data);
-
- g_free (spi_global_app_data);
- spi_global_app_data = NULL;
-
- /* Not currently creating an XDisplay */
-#if 0
- if (bridge_display)
- XCloseDisplay (bridge_display);
-#endif
-}
-
/*---------------------------------------------------------------------------*/
static AtkPlugClass *plug_class;
@@ -498,9 +479,7 @@ new_connection_cb (DBusServer *server, DBusConnection *con, void *data)
droute_intercept_dbus (con);
droute_context_register (spi_global_app_data->droute, con);
- new_list = g_list_append (spi_global_app_data->direct_connections, con);
- if (new_list)
- spi_global_app_data->direct_connections = new_list;
+ spi_global_app_data->direct_connections = g_list_append (spi_global_app_data->direct_connections, con);
}
static int
@@ -851,8 +830,53 @@ gnome_accessibility_module_init (void)
void
gnome_accessibility_module_shutdown (void)
{
+ GList *l;
+
+ if (!spi_global_app_data)
+ return;
+
+ spi_atk_tidy_windows ();
spi_atk_deregister_event_listeners ();
- exit_func ();
+
+ deregister_application (spi_global_app_data);
+
+ if (spi_global_app_data->bus)
+ {
+ dbus_connection_remove_filter (spi_global_app_data->bus, signal_filter, NULL);
+ droute_context_unregister (spi_global_app_data->droute, spi_global_app_data->bus);
+ dbus_connection_unref (spi_global_app_data->bus);
+ }
+
+ for (l = spi_global_app_data->direct_connections; l; l = l->next)
+ {
+ droute_context_unregister (spi_global_app_data->droute, l->data);
+ droute_unintercept_dbus (l->data);
+ dbus_connection_unref (l);
+ }
+ g_list_free (spi_global_app_data->direct_connections);
+
+ for (l = clients; l; l = l->next)
+ g_free (l->data);
+ g_list_free (clients);
+ clients = NULL;
+
+ g_object_unref (spi_global_cache);
+ g_object_unref (spi_global_leasing);
+ g_object_unref (spi_global_register);
+
+ if (spi_global_app_data->main_context)
+ g_main_context_unref (spi_global_app_data->main_context);
+
+ droute_free (spi_global_app_data->droute);
+
+ g_free (spi_global_app_data);
+ spi_global_app_data = NULL;
+
+ /* Not currently creating an XDisplay */
+#if 0
+ if (bridge_display)
+ XCloseDisplay (bridge_display);
+#endif
}
static gchar *name_match_tmpl =
diff --git a/atk-adaptor/event.c b/atk-adaptor/event.c
index f5a2d2d..e940e00 100644
--- a/atk-adaptor/event.c
+++ b/atk-adaptor/event.c
@@ -613,7 +613,8 @@ state_event_listener (GSignalInvocationHint * signal_hint,
DBUS_TYPE_INT32_AS_STRING, 0, append_basic);
if (!g_strcmp0 (pname, "defunct"))
- spi_register_deregister_object (spi_global_register, G_OBJECT (accessible));
+ spi_register_deregister_object (spi_global_register, G_OBJECT (accessible),
+ TRUE);
return TRUE;
}
@@ -1194,11 +1195,14 @@ spi_atk_deregister_event_listeners (void)
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);
}
- g_array_free (ids, TRUE);
if (atk_bridge_key_event_listener_id)
{
diff --git a/droute/droute.c b/droute/droute.c
index 20c262f..9212e4d 100644
--- a/droute/droute.c
+++ b/droute/droute.c
@@ -686,6 +686,12 @@ droute_path_register (DRoutePath *path, DBusConnection *bus)
}
void
+droute_path_unregister (DRoutePath *path, DBusConnection *bus)
+{
+ dbus_connection_unregister_object_path (bus, path->path);
+}
+
+void
droute_context_register (DRouteContext *cnx, DBusConnection *bus)
{
g_ptr_array_foreach (cnx->registered_paths, (GFunc) droute_path_register,
@@ -693,9 +699,30 @@ droute_context_register (DRouteContext *cnx, DBusConnection *bus)
}
void
+droute_context_unregister (DRouteContext *cnx, DBusConnection *bus)
+{
+ g_ptr_array_foreach (cnx->registered_paths, (GFunc) droute_path_unregister,
+ bus);
+}
+
+void
+droute_context_deregister (DRouteContext *cnx, DBusConnection *bus)
+{
+ g_ptr_array_foreach (cnx->registered_paths, (GFunc) droute_path_unregister,
+ bus);
+}
+
+void
droute_intercept_dbus (DBusConnection *bus)
{
dbus_connection_register_object_path (bus, DBUS_PATH_DBUS,
&droute_vtable, NULL);
}
+
+void
+droute_unintercept_dbus (DBusConnection *bus)
+{
+ dbus_connection_unregister_object_path (bus, DBUS_PATH_DBUS);
+}
+
/*END------------------------------------------------------------------------*/
diff --git a/droute/droute.h b/droute/droute.h
index 766340e..b19dec6 100644
--- a/droute/droute.h
+++ b/droute/droute.h
@@ -97,8 +97,17 @@ void
droute_path_register (DRoutePath *path, DBusConnection *bus);
void
+droute_path_unregister (DRoutePath *path, DBusConnection *bus);
+
+void
droute_context_register (DRouteContext *cnx, DBusConnection *bus);
void
+droute_context_unregister (DRouteContext *cnx, DBusConnection *bus);
+
+void
droute_intercept_dbus (DBusConnection *connection);
+
+void
+droute_unintercept_dbus (DBusConnection *connection);
#endif /* _DROUTE_H */