doc: Adding extra doc on atk_remove_[key/global]_event_listener
[platform/upstream/atk.git] / atk / atkutil.c
1 /* ATK -  Accessibility Toolkit
2  * Copyright 2001 Sun Microsystems Inc.
3  *
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.
8  *
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.
13  *
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.
18  */
19
20 #include "atkutil.h"
21 #include "atkmarshal.c"
22 #include "config.h"
23
24 static void atk_util_class_init (AtkUtilClass *klass);
25
26 static AtkObject *previous_focus_object = NULL;
27
28 GType
29 atk_util_get_type (void)
30 {
31   static GType type = 0;
32
33   if (!type)
34     {
35       static const GTypeInfo typeInfo =
36       {
37         sizeof (AtkUtilClass),
38         (GBaseInitFunc) NULL,
39         (GBaseFinalizeFunc) NULL,
40         (GClassInitFunc) atk_util_class_init,
41         (GClassFinalizeFunc) NULL,
42         NULL,
43         sizeof (AtkUtil),
44         0,
45         (GInstanceInitFunc) NULL,
46       } ;
47       type = g_type_register_static (G_TYPE_OBJECT, "AtkUtil", &typeInfo, 0) ;
48     }
49   return type;
50 }
51
52 static void
53 atk_util_class_init (AtkUtilClass *klass)
54 {
55   klass->add_global_event_listener = NULL;
56   klass->remove_global_event_listener = NULL;
57   klass->get_root = NULL;
58   klass->get_toolkit_name = NULL;
59   klass->get_toolkit_version = NULL;
60 }
61
62 /*
63  * This file supports the addition and removal of multiple focus handlers
64  * as long as they are all called in the same thread.
65  */
66 static AtkEventListenerInit  focus_tracker_init = (AtkEventListenerInit) NULL;
67
68 static gboolean init_done = FALSE;
69
70 /*
71  * Array of FocusTracker structs
72  */
73 static GArray *trackers = NULL;
74 static guint  index = 0;
75
76 typedef struct _FocusTracker FocusTracker;
77
78 struct _FocusTracker {
79   guint index;
80   AtkEventListener func;
81 };
82
83 /**
84  * atk_focus_tracker_init:
85  * @init: Function to be called for focus tracker initialization
86  *
87  * Specifies the function to be called for focus tracker initialization.
88  * This function should be called by an implementation of the
89  * ATK interface if any specific work needs to be done to enable
90  * focus tracking.
91  **/
92 void
93 atk_focus_tracker_init (AtkEventListenerInit    init)
94 {
95   if (!focus_tracker_init)
96     focus_tracker_init = init;
97 }
98
99 /**
100  * atk_add_focus_tracker:
101  * @focus_tracker: Function to be added to the list of functions to be called
102  * when an object receives focus.
103  *
104  * Adds the specified function to the list of functions to be called
105  * when an object receives focus.
106  *
107  * Returns: added focus tracker id, or 0 on failure.
108  **/
109 guint
110 atk_add_focus_tracker (AtkEventListener   focus_tracker)
111 {
112   g_return_val_if_fail (focus_tracker, 0);
113
114   if (!init_done)
115   {
116     if (focus_tracker_init)
117     {
118       focus_tracker_init ();
119     }
120     trackers = g_array_sized_new (FALSE, TRUE, sizeof (FocusTracker), 0);
121     init_done = TRUE;
122   }
123   if (init_done)
124   {
125     FocusTracker item;
126
127     item.index = ++index;
128     item.func = focus_tracker;
129     trackers = g_array_append_val (trackers, item);
130     return index;
131   }
132   else
133   {
134     return 0;
135   }
136 }
137
138 /**
139  * atk_remove_focus_tracker:
140  * @tracker_id: the id of the focus tracker to remove
141  *
142  * Removes the specified focus tracker from the list of functions
143  * to be called when any object receives focus.
144  **/
145 void
146 atk_remove_focus_tracker (guint            tracker_id)
147 {
148   FocusTracker *item;
149   guint i;
150
151   if (trackers == NULL)
152     return;
153
154   if (tracker_id == 0)
155     return;
156
157   for (i = 0; i < trackers->len; i++)
158   {
159     item = &g_array_index (trackers, FocusTracker, i);
160     if (item->index == tracker_id)
161     {
162       trackers = g_array_remove_index (trackers, i);
163       break;
164     }
165   }
166 }
167
168 /**
169  * atk_focus_tracker_notify:
170  * @object: an #AtkObject
171  *
172  * Cause the focus tracker functions which have been specified to be
173  * executed for the object.
174  **/
175 void
176 atk_focus_tracker_notify (AtkObject       *object)
177 {
178   FocusTracker *item;
179   guint i;
180
181   if (trackers == NULL)
182     return;
183
184   if (object == previous_focus_object)
185     return;
186   else
187     {
188       if (previous_focus_object)
189         g_object_unref (previous_focus_object);
190
191       previous_focus_object = object;
192       if (object)
193         {
194           g_object_ref (object);
195
196           for (i = 0; i < trackers->len; i++)
197             {
198               item = &g_array_index (trackers, FocusTracker, i);
199               g_return_if_fail (item != NULL);
200               item->func (object);
201             }
202         }
203     
204     }
205 }
206
207 /**
208  * atk_add_global_event_listener:
209  * @listener: the listener to notify
210  * @event_type: the type of event for which notification is requested
211  *
212  * Adds the specified function to the list of functions to be called
213  * when an ATK event of type event_type occurs.
214  *
215  * The format of event_type is the following:
216  *  "ATK:<atk_type>:<atk_event>
217  *
218  * Where "ATK" works as the namespace, <atk_interface> is the name of
219  * the ATK type (interface or object) and <atk_event> is the name of
220  * the signal defined on that interface.
221  *
222  * For example:
223  *   ATK:AtkObject:state-change
224  *   ATK:AtkText:text-selection-changed
225  *
226  * Returns: added event listener id, or 0 on failure.
227  **/
228 guint
229 atk_add_global_event_listener (GSignalEmissionHook listener,
230                                const gchar        *event_type)
231 {
232   guint retval;
233   AtkUtilClass *klass = g_type_class_ref (ATK_TYPE_UTIL);
234
235   if (klass->add_global_event_listener)
236     {
237       retval = klass->add_global_event_listener (listener, event_type);
238     }
239   else
240     {
241       retval = 0;
242     }
243   g_type_class_unref (klass);
244
245   return retval;
246 }
247
248 /**
249  * atk_remove_global_event_listener:
250  * @listener_id: the id of the event listener to remove
251  *
252  * @listener_id is the value returned by #atk_add_global_event_listener
253  * when you registered that event listener.
254  *
255  * Removes the specified event listener
256  **/
257 void
258 atk_remove_global_event_listener (guint listener_id)
259 {
260   AtkUtilClass *klass = g_type_class_peek (ATK_TYPE_UTIL);
261
262   if (klass && klass->remove_global_event_listener)
263     klass->remove_global_event_listener (listener_id);
264 }
265
266 /**
267  * atk_add_key_event_listener:
268  * @listener: the listener to notify
269  * @data: a #gpointer that points to a block of data that should be sent to the registered listeners,
270  *        along with the event notification, when it occurs.  
271  *
272  * Adds the specified function to the list of functions to be called
273  *        when a key event occurs.  The @data element will be passed to the
274  *        #AtkKeySnoopFunc (@listener) as the @func_data param, on notification.
275  *
276  * Returns: added event listener id, or 0 on failure.
277  **/
278 guint
279 atk_add_key_event_listener (AtkKeySnoopFunc listener, gpointer data)
280 {
281   guint retval;
282   AtkUtilClass *klass = g_type_class_peek (ATK_TYPE_UTIL);
283   if (klass && klass->add_key_event_listener)
284     {
285       retval = klass->add_key_event_listener (listener, data);
286     }
287   else
288     {
289       retval = 0;
290     }
291
292   return retval;
293 }
294
295 /**
296  * atk_remove_key_event_listener:
297  * @listener_id: the id of the event listener to remove
298  *
299  * @listener_id is the value returned by #atk_add_key_event_listener
300  * when you registered that event listener.
301  *
302  * Removes the specified event listener.
303  **/
304 void
305 atk_remove_key_event_listener (guint listener_id)
306 {
307   AtkUtilClass *klass = g_type_class_peek (ATK_TYPE_UTIL);
308
309   if (klass->remove_key_event_listener)
310     klass->remove_key_event_listener (listener_id);
311 }
312
313 /**
314  * atk_get_root:
315  *
316  * Gets the root accessible container for the current application.
317  *
318  * Returns: (transfer none): the root accessible container for the current
319  * application
320  **/
321 AtkObject*
322 atk_get_root (void)
323 {
324   AtkUtilClass *klass = g_type_class_ref (ATK_TYPE_UTIL);
325   AtkObject    *retval;
326   if (klass->get_root)
327     {
328       retval = klass->get_root ();
329     }
330   else
331     {
332       retval = NULL;
333     }
334   g_type_class_unref (klass);
335
336   return retval;
337 }
338
339 /**
340  * atk_get_focus_object:
341  *
342  * Gets the currently focused object.
343  * 
344  * Since: 1.6
345  *
346  * Returns: (transfer none): the currently focused object for the current
347  * application
348  **/
349 AtkObject*
350 atk_get_focus_object (void)
351 {
352   return previous_focus_object;
353 }
354
355 /**
356  * atk_get_toolkit_name:
357  *
358  * Gets name string for the GUI toolkit implementing ATK for this application.
359  *
360  * Returns: name string for the GUI toolkit implementing ATK for this application
361  **/
362 const gchar*
363 atk_get_toolkit_name (void)
364 {
365   const gchar *retval;
366   AtkUtilClass *klass = g_type_class_ref (ATK_TYPE_UTIL);
367   if (klass->get_toolkit_name)
368     {
369       retval = klass->get_toolkit_name ();
370     }
371   else
372     {
373       retval = NULL;
374     }
375   g_type_class_unref (klass);
376
377   return retval;
378 }
379
380 /**
381  * atk_get_toolkit_version:
382  *
383  * Gets version string for the GUI toolkit implementing ATK for this application.
384  *
385  * Returns: version string for the GUI toolkit implementing ATK for this application
386  **/
387 const gchar*
388 atk_get_toolkit_version (void)
389 {
390   const gchar *retval;
391   AtkUtilClass *klass = g_type_class_ref (ATK_TYPE_UTIL);
392   if (klass->get_toolkit_version)
393     {
394       retval = klass->get_toolkit_version ();
395     }
396   else
397     {
398       retval = NULL;
399     }
400   g_type_class_unref (klass);
401
402   return retval;
403 }
404
405 /**
406  * atk_get_version:
407  *
408  * Gets the current version for ATK.
409  *
410  * Returns: version string for ATK
411  *
412  * Since: 1.20
413  */
414 const gchar *
415 atk_get_version (void)
416 {
417   return VERSION;
418 }
419