+static guint
+add_listener (GSignalEmissionHook listener,
+ const gchar *object_type,
+ const gchar *signal_name,
+ const gchar *detail_string,
+ const gchar *hook_data)
+{
+ GType type;
+ guint signal_id;
+ gint rc = 0;
+ static gint listener_idx = 1;
+ GQuark detail_quark = 0;
+
+ type = g_type_from_name (object_type);
+ if (type)
+ {
+ signal_id = g_signal_lookup (signal_name, type);
+ detail_quark = g_quark_from_string (detail_string);
+
+ if (signal_id > 0)
+ {
+ AtkUtilListenerInfo *listener_info;
+
+ rc = listener_idx;
+
+ listener_info = g_new (AtkUtilListenerInfo, 1);
+ listener_info->key = listener_idx;
+ listener_info->hook_id =
+ g_signal_add_emission_hook (signal_id, detail_quark, listener,
+ g_strdup (hook_data),
+ (GDestroyNotify) g_free);
+ listener_info->signal_id = signal_id;
+
+ g_hash_table_insert(listener_list, &(listener_info->key), listener_info);
+ listener_idx++;
+ }
+ else
+ {
+ g_debug ("Signal type %s not supported\n", signal_name);
+ }
+ }
+ else
+ {
+ g_warning("Invalid object type %s\n", object_type);
+ }
+ return rc;
+}
+
+static guint
+atk_util_real_add_global_event_listener (GSignalEmissionHook listener,
+ const gchar *event_type)
+{
+ guint rc = 0;
+ gchar **split_string;
+ guint length;
+
+ split_string = g_strsplit (event_type, ":", 0);
+ length = g_strv_length (split_string);
+
+ if ((length == 3) || (length == 4))
+ rc = add_listener (listener, split_string[1], split_string[2],
+ split_string[3], event_type);
+
+ g_strfreev (split_string);
+
+ return rc;
+}
+
+static void
+atk_util_real_remove_global_event_listener (guint remove_listener)
+{
+ if (remove_listener > 0)
+ {
+ AtkUtilListenerInfo *listener_info;
+ gint tmp_idx = remove_listener;
+
+ listener_info = (AtkUtilListenerInfo *)
+ g_hash_table_lookup(listener_list, &tmp_idx);
+
+ if (listener_info != NULL)
+ {
+ /* Hook id of 0 and signal id of 0 are invalid */
+ if (listener_info->hook_id != 0 && listener_info->signal_id != 0)
+ {
+ /* Remove the emission hook */
+ g_signal_remove_emission_hook(listener_info->signal_id,
+ listener_info->hook_id);
+
+ /* Remove the element from the hash */
+ g_hash_table_remove(listener_list, &tmp_idx);
+ }
+ else
+ {
+ g_warning("Invalid listener hook_id %ld or signal_id %d\n",
+ listener_info->hook_id, listener_info->signal_id);
+ }
+ }
+ else
+ {
+ g_warning("No listener with the specified listener id %d",
+ remove_listener);
+ }
+ }
+ else
+ {
+ g_warning("Invalid listener_id %d", remove_listener);
+ }
+}
+
+