1 /* ATK - Accessibility Toolkit
2 * Copyright 2001 Sun Microsystems Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 #include "atkmarshal.c"
24 * @Short_description: A set of ATK utility functions for event and toolkit support.
27 * A set of ATK utility functions which are used to support event
28 * registration of various types, and obtaining the 'root' accessible
29 * of a process and information about the current ATK implementation
30 * and toolkit version.
33 static void atk_util_class_init (AtkUtilClass *klass);
35 static AtkObject *previous_focus_object = NULL;
37 typedef struct _AtkUtilListenerInfo AtkUtilListenerInfo;
38 struct _AtkUtilListenerInfo
44 static GHashTable *listener_list = NULL;
47 atk_util_get_type (void)
49 static GType type = 0;
53 static const GTypeInfo typeInfo =
55 sizeof (AtkUtilClass),
57 (GBaseFinalizeFunc) NULL,
58 (GClassInitFunc) atk_util_class_init,
59 (GClassFinalizeFunc) NULL,
63 (GInstanceInitFunc) NULL,
65 type = g_type_register_static (G_TYPE_OBJECT, "AtkUtil", &typeInfo, 0) ;
71 * This file supports the addition and removal of multiple focus handlers
72 * as long as they are all called in the same thread.
74 static AtkEventListenerInit focus_tracker_init = (AtkEventListenerInit) NULL;
76 static gboolean init_done = FALSE;
79 * Array of FocusTracker structs
81 static GArray *trackers = NULL;
82 static guint global_index = 0;
84 typedef struct _FocusTracker FocusTracker;
86 struct _FocusTracker {
88 AtkEventListener func;
92 * atk_focus_tracker_init:
93 * @init: Function to be called for focus tracker initialization
95 * Specifies the function to be called for focus tracker initialization.
96 * This function should be called by an implementation of the
97 * ATK interface if any specific work needs to be done to enable
100 * Deprecated: This method is deprecated since ATK version
101 * 2.9.4. Focus tracking has been dropped as a feature to be
102 * implemented by ATK itself.
106 atk_focus_tracker_init (AtkEventListenerInit init)
108 if (!focus_tracker_init)
109 focus_tracker_init = init;
113 * atk_add_focus_tracker:
114 * @focus_tracker: Function to be added to the list of functions to be called
115 * when an object receives focus.
117 * Adds the specified function to the list of functions to be called
118 * when an object receives focus.
120 * Deprecated: This method is deprecated since ATK version
121 * 2.9.4. Focus tracking has been dropped as a feature to be
122 * implemented by ATK itself. If you need focus tracking on your
123 * implementation, subscribe to the state-changed:focused signal.
125 * Returns: added focus tracker id, or 0 on failure.
128 atk_add_focus_tracker (AtkEventListener focus_tracker)
130 g_return_val_if_fail (focus_tracker, 0);
134 if (focus_tracker_init)
136 focus_tracker_init ();
138 trackers = g_array_sized_new (FALSE, TRUE, sizeof (FocusTracker), 0);
145 item.index = ++global_index;
146 item.func = focus_tracker;
147 trackers = g_array_append_val (trackers, item);
157 * atk_remove_focus_tracker:
158 * @tracker_id: the id of the focus tracker to remove
160 * Deprecated: This method is deprecated since ATK version
161 * 2.9.4. Focus tracking has been dropped as a feature to be
162 * implemented by ATK itself. If you need focus tracking on your
163 * implementation, subscribe to the state-changed:focused signal.
165 * Removes the specified focus tracker from the list of functions
166 * to be called when any object receives focus.
169 atk_remove_focus_tracker (guint tracker_id)
174 if (trackers == NULL)
180 for (i = 0; i < trackers->len; i++)
182 item = &g_array_index (trackers, FocusTracker, i);
183 if (item->index == tracker_id)
185 trackers = g_array_remove_index (trackers, i);
192 * atk_focus_tracker_notify:
193 * @object: an #AtkObject
195 * Cause the focus tracker functions which have been specified to be
196 * executed for the object.
198 * Deprecated: This method is deprecated since ATK version
199 * 2.9.4. Focus tracking has been dropped as a feature to be
200 * implemented by ATK itself.
204 atk_focus_tracker_notify (AtkObject *object)
209 if (trackers == NULL)
212 if (object == previous_focus_object)
216 if (previous_focus_object)
217 g_object_unref (previous_focus_object);
219 previous_focus_object = object;
222 g_object_ref (object);
224 for (i = 0; i < trackers->len; i++)
226 item = &g_array_index (trackers, FocusTracker, i);
227 g_return_if_fail (item != NULL);
236 add_listener (GSignalEmissionHook listener,
237 const gchar *object_type,
238 const gchar *signal_name,
239 const gchar *detail_string,
240 const gchar *hook_data)
245 static gint listener_idx = 1;
246 GQuark detail_quark = 0;
248 type = g_type_from_name (object_type);
251 signal_id = g_signal_lookup (signal_name, type);
252 detail_quark = g_quark_from_string (detail_string);
256 AtkUtilListenerInfo *listener_info;
260 listener_info = g_new (AtkUtilListenerInfo, 1);
261 listener_info->key = listener_idx;
262 listener_info->hook_id =
263 g_signal_add_emission_hook (signal_id, detail_quark, listener,
264 g_strdup (hook_data),
265 (GDestroyNotify) g_free);
266 listener_info->signal_id = signal_id;
268 g_hash_table_insert(listener_list, &(listener_info->key), listener_info);
273 g_debug ("Signal type %s not supported\n", signal_name);
278 g_warning("Invalid object type %s\n", object_type);
284 atk_util_real_add_global_event_listener (GSignalEmissionHook listener,
285 const gchar *event_type)
288 gchar **split_string;
291 split_string = g_strsplit (event_type, ":", 0);
292 length = g_strv_length (split_string);
294 if ((length == 3) || (length == 4))
295 rc = add_listener (listener, split_string[1], split_string[2],
296 split_string[3], event_type);
298 g_strfreev (split_string);
304 atk_util_real_remove_global_event_listener (guint remove_listener)
306 if (remove_listener > 0)
308 AtkUtilListenerInfo *listener_info;
309 gint tmp_idx = remove_listener;
311 listener_info = (AtkUtilListenerInfo *)
312 g_hash_table_lookup(listener_list, &tmp_idx);
314 if (listener_info != NULL)
316 /* Hook id of 0 and signal id of 0 are invalid */
317 if (listener_info->hook_id != 0 && listener_info->signal_id != 0)
319 /* Remove the emission hook */
320 g_signal_remove_emission_hook(listener_info->signal_id,
321 listener_info->hook_id);
323 /* Remove the element from the hash */
324 g_hash_table_remove(listener_list, &tmp_idx);
328 g_warning("Invalid listener hook_id %ld or signal_id %d\n",
329 listener_info->hook_id, listener_info->signal_id);
334 g_warning("No listener with the specified listener id %d",
340 g_warning("Invalid listener_id %d", remove_listener);
346 * atk_add_global_event_listener:
347 * @listener: the listener to notify
348 * @event_type: the type of event for which notification is requested
350 * Adds the specified function to the list of functions to be called
351 * when an ATK event of type event_type occurs.
353 * The format of event_type is the following:
354 * "ATK:<atk_type>:<atk_event>:<atk_event_detail>
356 * Where "ATK" works as the namespace, <atk_interface> is the name of
357 * the ATK type (interface or object), <atk_event> is the name of the
358 * signal defined on that interface and <atk_event_detail> is the
359 * gsignal detail of that signal. You can find more info about gsignal
361 * http://developer.gnome.org/gobject/stable/gobject-Signals.html
363 * The first three parameters are mandatory. The last one is optional.
366 * ATK:AtkObject:state-change
367 * ATK:AtkText:text-selection-changed
368 * ATK:AtkText:text-insert:system
370 * Toolkit implementor note: ATK provides a default implementation for
371 * this virtual method. ATK implementors are discouraged from
372 * reimplementing this method.
374 * Toolkit implementor note: this method is not intended to be used by
375 * ATK implementors but by ATK consumers.
377 * Returns: added event listener id, or 0 on failure.
380 atk_add_global_event_listener (GSignalEmissionHook listener,
381 const gchar *event_type)
384 AtkUtilClass *klass = g_type_class_ref (ATK_TYPE_UTIL);
386 if (klass->add_global_event_listener)
388 retval = klass->add_global_event_listener (listener, event_type);
394 g_type_class_unref (klass);
400 * atk_remove_global_event_listener:
401 * @listener_id: the id of the event listener to remove
403 * @listener_id is the value returned by #atk_add_global_event_listener
404 * when you registered that event listener.
406 * Toolkit implementor note: ATK provides a default implementation for
407 * this virtual method. ATK implementors are discouraged from
408 * reimplementing this method.
410 * Toolkit implementor note: this method is not intended to be used by
411 * ATK implementors but by ATK consumers.
413 * Removes the specified event listener
416 atk_remove_global_event_listener (guint listener_id)
418 AtkUtilClass *klass = g_type_class_peek (ATK_TYPE_UTIL);
420 if (klass && klass->remove_global_event_listener)
421 klass->remove_global_event_listener (listener_id);
425 * atk_add_key_event_listener:
426 * @listener: the listener to notify
427 * @data: a #gpointer that points to a block of data that should be sent to the registered listeners,
428 * along with the event notification, when it occurs.
430 * Adds the specified function to the list of functions to be called
431 * when a key event occurs. The @data element will be passed to the
432 * #AtkKeySnoopFunc (@listener) as the @func_data param, on notification.
434 * Returns: added event listener id, or 0 on failure.
437 atk_add_key_event_listener (AtkKeySnoopFunc listener, gpointer data)
440 AtkUtilClass *klass = g_type_class_peek (ATK_TYPE_UTIL);
441 if (klass && klass->add_key_event_listener)
443 retval = klass->add_key_event_listener (listener, data);
454 * atk_remove_key_event_listener:
455 * @listener_id: the id of the event listener to remove
457 * @listener_id is the value returned by #atk_add_key_event_listener
458 * when you registered that event listener.
460 * Removes the specified event listener.
463 atk_remove_key_event_listener (guint listener_id)
465 AtkUtilClass *klass = g_type_class_peek (ATK_TYPE_UTIL);
467 if (klass->remove_key_event_listener)
468 klass->remove_key_event_listener (listener_id);
474 * Gets the root accessible container for the current application.
476 * Returns: (transfer none): the root accessible container for the current
482 AtkUtilClass *klass = g_type_class_ref (ATK_TYPE_UTIL);
486 retval = klass->get_root ();
492 g_type_class_unref (klass);
498 * atk_get_focus_object:
500 * Gets the currently focused object.
504 * Returns: (transfer none): the currently focused object for the current
508 atk_get_focus_object (void)
510 return previous_focus_object;
514 * atk_get_toolkit_name:
516 * Gets name string for the GUI toolkit implementing ATK for this application.
518 * Returns: name string for the GUI toolkit implementing ATK for this application
521 atk_get_toolkit_name (void)
524 AtkUtilClass *klass = g_type_class_ref (ATK_TYPE_UTIL);
525 if (klass->get_toolkit_name)
527 retval = klass->get_toolkit_name ();
533 g_type_class_unref (klass);
539 * atk_get_toolkit_version:
541 * Gets version string for the GUI toolkit implementing ATK for this application.
543 * Returns: version string for the GUI toolkit implementing ATK for this application
546 atk_get_toolkit_version (void)
549 AtkUtilClass *klass = g_type_class_ref (ATK_TYPE_UTIL);
550 if (klass->get_toolkit_version)
552 retval = klass->get_toolkit_version ();
558 g_type_class_unref (klass);
566 * Gets the current version for ATK.
568 * Returns: version string for ATK
573 atk_get_version (void)
579 atk_util_class_init (AtkUtilClass *klass)
581 klass->add_global_event_listener = atk_util_real_add_global_event_listener;
582 klass->remove_global_event_listener = atk_util_real_remove_global_event_listener;
583 klass->get_root = NULL;
584 klass->get_toolkit_name = NULL;
585 klass->get_toolkit_version = NULL;
587 listener_list = g_hash_table_new_full (g_int_hash, g_int_equal, NULL,