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