Bug #460851. A new API to get the current version of ATK.
[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 event of type event_type occurs.
214  *
215  * Returns: added event listener id, or 0 on failure.
216  **/
217 guint
218 atk_add_global_event_listener (GSignalEmissionHook listener,
219                                const gchar        *event_type)
220 {
221   guint retval;
222   AtkUtilClass *klass = g_type_class_ref (ATK_TYPE_UTIL);
223
224   if (klass->add_global_event_listener)
225     {
226       retval = klass->add_global_event_listener (listener, event_type);
227     }
228   else
229     {
230       retval = -1;
231     }
232   g_type_class_unref (klass);
233
234   return retval;
235 }
236
237 /**
238  * atk_remove_global_event_listener:
239  * @listener_id: the id of the event listener to remove
240  *
241  * Removes the specified event listener
242  **/
243 void
244 atk_remove_global_event_listener (guint listener_id)
245 {
246   AtkUtilClass *klass = g_type_class_peek (ATK_TYPE_UTIL);
247
248   if (klass && klass->remove_global_event_listener)
249     klass->remove_global_event_listener (listener_id);
250 }
251
252 /**
253  * atk_add_key_event_listener:
254  * @listener: the listener to notify
255  * @data: a #gpointer that points to a block of data that should be sent to the registered listeners,
256  *        along with the event notification, when it occurs.  
257  *
258  * Adds the specified function to the list of functions to be called
259  *        when a key event occurs.  The @data element will be passed to the
260  *        #AtkKeySnoopFunc (@listener) as the @func_data param, on notification.
261  *
262  * Returns: added event listener id, or 0 on failure.
263  **/
264 guint
265 atk_add_key_event_listener (AtkKeySnoopFunc listener, gpointer data)
266 {
267   guint retval;
268   AtkUtilClass *klass = g_type_class_peek (ATK_TYPE_UTIL);
269   if (klass && klass->add_key_event_listener)
270     {
271       retval = klass->add_key_event_listener (listener, data);
272     }
273   else
274     {
275       retval = -1;
276     }
277
278   return retval;
279 }
280
281 /**
282  * atk_remove_key_event_listener:
283  * @listener_id: the id of the event listener to remove
284  *
285  * Removes the specified event listener
286  **/
287 void
288 atk_remove_key_event_listener (guint listener_id)
289 {
290   AtkUtilClass *klass = g_type_class_peek (ATK_TYPE_UTIL);
291
292   if (klass->remove_key_event_listener)
293     klass->remove_key_event_listener (listener_id);
294 }
295
296 /**
297  * atk_get_root:
298  *
299  * Gets the root accessible container for the current application.
300  *
301  * Returns: the root accessible container for the current application
302  **/
303 AtkObject*
304 atk_get_root (void)
305 {
306   AtkUtilClass *klass = g_type_class_ref (ATK_TYPE_UTIL);
307   AtkObject    *retval;
308   if (klass->get_root)
309     {
310       retval = klass->get_root ();
311     }
312   else
313     {
314       retval = NULL;
315     }
316   g_type_class_unref (klass);
317
318   return retval;
319 }
320
321 /**
322  * atk_get_focus_object:
323  *
324  * Gets the currently focused object.
325  * 
326  * Since: ATK 1.6
327  *
328  * Returns: the currently focused object for the current application
329  **/
330 AtkObject*
331 atk_get_focus_object (void)
332 {
333   return previous_focus_object;
334 }
335
336 /**
337  * atk_get_toolkit_name:
338  *
339  * Gets name string for the GUI toolkit implementing ATK for this application.
340  *
341  * Returns: name string for the GUI toolkit implementing ATK for this application
342  **/
343 G_CONST_RETURN gchar*
344 atk_get_toolkit_name (void)
345 {
346   const gchar *retval;
347   AtkUtilClass *klass = g_type_class_ref (ATK_TYPE_UTIL);
348   if (klass->get_toolkit_name)
349     {
350       retval = klass->get_toolkit_name ();
351     }
352   else
353     {
354       retval = NULL;
355     }
356   g_type_class_unref (klass);
357
358   return retval;
359 }
360
361 /**
362  * atk_get_toolkit_version:
363  *
364  * Gets version string for the GUI toolkit implementing ATK for this application.
365  *
366  * Returns: version string for the GUI toolkit implementing ATK for this application
367  **/
368 G_CONST_RETURN gchar*
369 atk_get_toolkit_version (void)
370 {
371   const gchar *retval;
372   AtkUtilClass *klass = g_type_class_ref (ATK_TYPE_UTIL);
373   if (klass->get_toolkit_version)
374     {
375       retval = klass->get_toolkit_version ();
376     }
377   else
378     {
379       retval = NULL;
380     }
381   g_type_class_unref (klass);
382
383   return retval;
384 }
385
386 /**
387  * atk_get_version:
388  *
389  * Gets the current version for ATK.
390  *
391  * Returns: version string for ATK
392  **/
393
394 G_CONST_RETURN gchar *
395 atk_get_version (void)
396 {
397   return VERSION;
398 }
399