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, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 #include "atkmarshal.c"
26 * @Short_description: A set of ATK utility functions for event and toolkit support.
29 * A set of ATK utility functions which are used to support event
30 * registration of various types, and obtaining the 'root' accessible
31 * of a process and information about the current ATK implementation
32 * and toolkit version.
35 static void atk_util_class_init (AtkUtilClass
*klass
);
37 static AtkObject
*previous_focus_object
= NULL
;
39 typedef struct _AtkUtilListenerInfo AtkUtilListenerInfo
;
40 struct _AtkUtilListenerInfo
46 static GHashTable
*listener_list
= NULL
;
49 atk_util_get_type (void)
51 static GType type
= 0;
55 static const GTypeInfo typeInfo
=
57 sizeof (AtkUtilClass
),
59 (GBaseFinalizeFunc
) NULL
,
60 (GClassInitFunc
) atk_util_class_init
,
61 (GClassFinalizeFunc
) NULL
,
65 (GInstanceInitFunc
) NULL
,
67 type
= g_type_register_static (G_TYPE_OBJECT
, "AtkUtil", &typeInfo
, 0) ;
73 * This file supports the addition and removal of multiple focus handlers
74 * as long as they are all called in the same thread.
76 static AtkEventListenerInit focus_tracker_init
= (AtkEventListenerInit
) NULL
;
78 static gboolean init_done
= FALSE
;
81 * Array of FocusTracker structs
83 static GArray
*trackers
= NULL
;
84 static guint global_index
= 0;
86 typedef struct _FocusTracker FocusTracker
;
88 struct _FocusTracker
{
90 AtkEventListener func
;
94 * atk_focus_tracker_init:
95 * @init: Function to be called for focus tracker initialization
97 * Specifies the function to be called for focus tracker initialization.
98 * This function should be called by an implementation of the
99 * ATK interface if any specific work needs to be done to enable
102 * Deprecated: This method is deprecated since ATK version
103 * 2.9.4. Focus tracking has been dropped as a feature to be
104 * implemented by ATK itself.
108 atk_focus_tracker_init (AtkEventListenerInit init
)
110 if (!focus_tracker_init
)
111 focus_tracker_init
= init
;
115 * atk_add_focus_tracker:
116 * @focus_tracker: Function to be added to the list of functions to be called
117 * when an object receives focus.
119 * Adds the specified function to the list of functions to be called
120 * when an object receives focus.
122 * Deprecated: This method is deprecated since ATK version
123 * 2.9.4. Focus tracking has been dropped as a feature to be
124 * implemented by ATK itself. If you need focus tracking on your
125 * implementation, subscribe to the state-changed:focused signal.
127 * Returns: added focus tracker id, or 0 on failure.
130 atk_add_focus_tracker (AtkEventListener focus_tracker
)
132 g_return_val_if_fail (focus_tracker
, 0);
136 if (focus_tracker_init
)
138 focus_tracker_init ();
140 trackers
= g_array_sized_new (FALSE
, TRUE
, sizeof (FocusTracker
), 0);
147 item
.index
= ++global_index
;
148 item
.func
= focus_tracker
;
149 trackers
= g_array_append_val (trackers
, item
);
159 * atk_remove_focus_tracker:
160 * @tracker_id: the id of the focus tracker to remove
162 * Deprecated: This method is deprecated since ATK version
163 * 2.9.4. Focus tracking has been dropped as a feature to be
164 * implemented by ATK itself. If you need focus tracking on your
165 * implementation, subscribe to the state-changed:focused signal.
167 * Removes the specified focus tracker from the list of functions
168 * to be called when any object receives focus.
171 atk_remove_focus_tracker (guint tracker_id
)
176 if (trackers
== NULL
)
182 for (i
= 0; i
< trackers
->len
; i
++)
184 item
= &g_array_index (trackers
, FocusTracker
, i
);
185 if (item
->index
== tracker_id
)
187 trackers
= g_array_remove_index (trackers
, i
);
194 * atk_focus_tracker_notify:
195 * @object: an #AtkObject
197 * Cause the focus tracker functions which have been specified to be
198 * executed for the object.
200 * Deprecated: This method is deprecated since ATK version
201 * 2.9.4. Focus tracking has been dropped as a feature to be
202 * implemented by ATK itself.
206 atk_focus_tracker_notify (AtkObject
*object
)
211 if (trackers
== NULL
)
214 if (object
== previous_focus_object
)
218 if (previous_focus_object
)
219 g_object_unref (previous_focus_object
);
221 previous_focus_object
= object
;
224 g_object_ref (object
);
226 for (i
= 0; i
< trackers
->len
; i
++)
228 item
= &g_array_index (trackers
, FocusTracker
, i
);
229 g_return_if_fail (item
!= NULL
);
238 add_listener (GSignalEmissionHook listener
,
239 const gchar
*object_type
,
240 const gchar
*signal_name
,
241 const gchar
*detail_string
,
242 const gchar
*hook_data
)
247 static gint listener_idx
= 1;
248 GQuark detail_quark
= 0;
250 type
= g_type_from_name (object_type
);
253 signal_id
= g_signal_lookup (signal_name
, type
);
254 detail_quark
= g_quark_from_string (detail_string
);
258 AtkUtilListenerInfo
*listener_info
;
262 listener_info
= g_new (AtkUtilListenerInfo
, 1);
263 listener_info
->key
= listener_idx
;
264 listener_info
->hook_id
=
265 g_signal_add_emission_hook (signal_id
, detail_quark
, listener
,
266 g_strdup (hook_data
),
267 (GDestroyNotify
) g_free
);
268 listener_info
->signal_id
= signal_id
;
270 g_hash_table_insert(listener_list
, &(listener_info
->key
), listener_info
);
275 g_debug ("Signal type %s not supported\n", signal_name
);
280 g_warning("Invalid object type %s\n", object_type
);
286 atk_util_real_add_global_event_listener (GSignalEmissionHook listener
,
287 const gchar
*event_type
)
290 gchar
**split_string
;
293 split_string
= g_strsplit (event_type
, ":", 0);
294 length
= g_strv_length (split_string
);
296 if ((length
== 3) || (length
== 4))
297 rc
= add_listener (listener
, split_string
[1], split_string
[2],
298 split_string
[3], event_type
);
300 g_strfreev (split_string
);
306 atk_util_real_remove_global_event_listener (guint remove_listener
)
308 if (remove_listener
> 0)
310 AtkUtilListenerInfo
*listener_info
;
311 gint tmp_idx
= remove_listener
;
313 listener_info
= (AtkUtilListenerInfo
*)
314 g_hash_table_lookup(listener_list
, &tmp_idx
);
316 if (listener_info
!= NULL
)
318 /* Hook id of 0 and signal id of 0 are invalid */
319 if (listener_info
->hook_id
!= 0 && listener_info
->signal_id
!= 0)
321 /* Remove the emission hook */
322 g_signal_remove_emission_hook(listener_info
->signal_id
,
323 listener_info
->hook_id
);
325 /* Remove the element from the hash */
326 g_hash_table_remove(listener_list
, &tmp_idx
);
330 g_warning("Invalid listener hook_id %ld or signal_id %d\n",
331 listener_info
->hook_id
, listener_info
->signal_id
);
336 g_warning("No listener with the specified listener id %d",
342 g_warning("Invalid listener_id %d", remove_listener
);
348 * atk_add_global_event_listener:
349 * @listener: the listener to notify
350 * @event_type: the type of event for which notification is requested
352 * Adds the specified function to the list of functions to be called
353 * when an ATK event of type event_type occurs.
355 * The format of event_type is the following:
356 * "ATK:<atk_type>:<atk_event>:<atk_event_detail>
358 * Where "ATK" works as the namespace, <atk_interface> is the name of
359 * the ATK type (interface or object), <atk_event> is the name of the
360 * signal defined on that interface and <atk_event_detail> is the
361 * gsignal detail of that signal. You can find more info about gsignal
363 * http://developer.gnome.org/gobject/stable/gobject-Signals.html
365 * The first three parameters are mandatory. The last one is optional.
368 * ATK:AtkObject:state-change
369 * ATK:AtkText:text-selection-changed
370 * ATK:AtkText:text-insert:system
372 * Toolkit implementor note: Atk provides a default implementation for
373 * this virtual method, and that implementation should be enough for
374 * most of the cases. You should have a really good reason to
375 * reimplement this method.
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, and that implementation should be enough for
408 * most of the cases. You should have a really good reason to
409 * reimplement this method.
411 * Removes the specified event listener
414 atk_remove_global_event_listener (guint listener_id
)
416 AtkUtilClass
*klass
= g_type_class_peek (ATK_TYPE_UTIL
);
418 if (klass
&& klass
->remove_global_event_listener
)
419 klass
->remove_global_event_listener (listener_id
);
423 * atk_add_key_event_listener:
424 * @listener: the listener to notify
425 * @data: a #gpointer that points to a block of data that should be sent to the registered listeners,
426 * along with the event notification, when it occurs.
428 * Adds the specified function to the list of functions to be called
429 * when a key event occurs. The @data element will be passed to the
430 * #AtkKeySnoopFunc (@listener) as the @func_data param, on notification.
432 * Returns: added event listener id, or 0 on failure.
435 atk_add_key_event_listener (AtkKeySnoopFunc listener
, gpointer data
)
438 AtkUtilClass
*klass
= g_type_class_peek (ATK_TYPE_UTIL
);
439 if (klass
&& klass
->add_key_event_listener
)
441 retval
= klass
->add_key_event_listener (listener
, data
);
452 * atk_remove_key_event_listener:
453 * @listener_id: the id of the event listener to remove
455 * @listener_id is the value returned by #atk_add_key_event_listener
456 * when you registered that event listener.
458 * Removes the specified event listener.
461 atk_remove_key_event_listener (guint listener_id
)
463 AtkUtilClass
*klass
= g_type_class_peek (ATK_TYPE_UTIL
);
465 if (klass
->remove_key_event_listener
)
466 klass
->remove_key_event_listener (listener_id
);
472 * Gets the root accessible container for the current application.
474 * Returns: (transfer none): the root accessible container for the current
480 AtkUtilClass
*klass
= g_type_class_ref (ATK_TYPE_UTIL
);
484 retval
= klass
->get_root ();
490 g_type_class_unref (klass
);
496 * atk_get_focus_object:
498 * Gets the currently focused object.
502 * Returns: (transfer none): the currently focused object for the current
506 atk_get_focus_object (void)
508 return previous_focus_object
;
512 * atk_get_toolkit_name:
514 * Gets name string for the GUI toolkit implementing ATK for this application.
516 * Returns: name string for the GUI toolkit implementing ATK for this application
519 atk_get_toolkit_name (void)
522 AtkUtilClass
*klass
= g_type_class_ref (ATK_TYPE_UTIL
);
523 if (klass
->get_toolkit_name
)
525 retval
= klass
->get_toolkit_name ();
531 g_type_class_unref (klass
);
537 * atk_get_toolkit_version:
539 * Gets version string for the GUI toolkit implementing ATK for this application.
541 * Returns: version string for the GUI toolkit implementing ATK for this application
544 atk_get_toolkit_version (void)
547 AtkUtilClass
*klass
= g_type_class_ref (ATK_TYPE_UTIL
);
548 if (klass
->get_toolkit_version
)
550 retval
= klass
->get_toolkit_version ();
556 g_type_class_unref (klass
);
564 * Gets the current version for ATK.
566 * Returns: version string for ATK
571 atk_get_version (void)
577 atk_util_class_init (AtkUtilClass
*klass
)
579 klass
->add_global_event_listener
= atk_util_real_add_global_event_listener
;
580 klass
->remove_global_event_listener
= atk_util_real_remove_global_event_listener
;
581 klass
->get_root
= NULL
;
582 klass
->get_toolkit_name
= NULL
;
583 klass
->get_toolkit_version
= NULL
;
585 listener_list
= g_hash_table_new_full (g_int_hash
, g_int_equal
, NULL
,