Changed atk_util_add_global_event_listener to ensure that
[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 GType
26 atk_util_get_type (void)
27 {
28   static GType type = 0;
29
30   if (!type)
31     {
32       static const GTypeInfo typeInfo =
33       {
34         sizeof (AtkUtilClass),
35         (GBaseInitFunc) NULL,
36         (GBaseFinalizeFunc) NULL,
37         (GClassInitFunc) atk_util_class_init,
38         (GClassFinalizeFunc) NULL,
39         NULL,
40         sizeof (AtkUtil),
41         0,
42         (GInstanceInitFunc) NULL,
43       } ;
44       type = g_type_register_static (G_TYPE_OBJECT, "AtkUtil", &typeInfo, 0) ;
45     }
46   return type;
47 }
48
49 static void
50 atk_util_class_init (AtkUtilClass *klass)
51 {
52   klass->add_global_event_listener = NULL;
53   klass->remove_global_event_listener = NULL;
54   klass->get_root = NULL;
55   klass->get_toolkit_name = NULL;
56   klass->get_toolkit_version = NULL;
57 }
58
59 /*
60  * This file supports the addition and removal of multiple focus handlers
61  * as long as they are all called in the same thread.
62  */
63 static AtkEventListenerInit  focus_tracker_init = (AtkEventListenerInit) NULL;
64
65 static gboolean init_done = FALSE;
66
67 /*
68  * Array of FocusTracker structs
69  */
70 static GArray *trackers = NULL;
71 static guint  index = 0;
72
73 typedef struct _FocusTracker FocusTracker;
74
75 struct _FocusTracker {
76   guint index;
77   AtkEventListener func;
78 };
79
80 /**
81  * atk_focus_tracker_init:
82  * @add_function: Function to be called for focus tracker initialization
83  *
84  * Specifies the function to be called for focus tracker initialization.
85  * This function should be called by an implementation of the
86  * ATK interface if any specific work needs to be done to enable
87  * focus tracking.
88  **/
89 void
90 atk_focus_tracker_init (AtkEventListenerInit    init)
91 {
92   if (!focus_tracker_init)
93     focus_tracker_init = init;
94 }
95
96 /**
97  * atk_add_focus_tracker:
98  * @focus_tracker: Function to be added to the list of functions to be called
99  * when an object receives focus.
100  *
101  * Adds the specified function to the list of functions to be called
102  * when an object receives focus.
103  *
104  * Returns: added focus tracker id, or 0 on failure.
105  **/
106 guint
107 atk_add_focus_tracker (AtkEventListener   focus_tracker)
108 {
109   g_return_val_if_fail (focus_tracker, 0);
110
111   if (!init_done)
112   {
113     if (focus_tracker_init)
114     {
115       focus_tracker_init ();
116     }
117     trackers = g_array_sized_new (FALSE, TRUE, sizeof (FocusTracker), 0);
118     init_done = TRUE;
119   }
120   if (init_done)
121   {
122     FocusTracker item;
123
124     item.index = ++index;
125     item.func = focus_tracker;
126     trackers = g_array_append_val (trackers, item);
127     return index;
128   }
129   else
130   {
131     return 0;
132   }
133 }
134
135 /**
136  * atk_remove_focus_tracker:
137  * @tracker_id: the id of the focus tracker to remove
138  *
139  * Removes the specified focus tracker from the list of functions
140  * to be called when any object receives focus.
141  **/
142 void
143 atk_remove_focus_tracker (guint            tracker_id)
144 {
145   FocusTracker *item;
146   guint i;
147
148   if (trackers == NULL)
149     return;
150
151   if (tracker_id == 0)
152     return;
153
154   for (i = 0; i < trackers->len; i++)
155   {
156     item = &g_array_index (trackers, FocusTracker, i);
157     if (item->index == tracker_id)
158     {
159       trackers = g_array_remove_index (trackers, i);
160       break;
161     }
162   }
163 }
164
165 /**
166  * atk_focus_tracker_notify:
167  * @object: an #AtkObject
168  *
169  * Cause the focus tracker functions which have been specified to be
170  * executed for the object.
171  **/
172 void
173 atk_focus_tracker_notify (AtkObject       *object)
174 {
175   FocusTracker *item;
176   guint i;
177
178   if (trackers == NULL)
179     return;
180
181   for (i = 0; i < trackers->len; i++)
182   {
183     item = &g_array_index (trackers, FocusTracker, i);
184     g_return_if_fail (item != NULL);
185     item->func (object);
186   }
187 }
188
189 /**
190  * atk_add_global_event_listener:
191  * @listener: the listener to notify
192  * @event_type: the type of event for which notification is requested
193  *
194  * Adds the specified function to the list of functions to be called
195  * when an event of type event_type occurs.
196  *
197  * Returns: added event listener id, or 0 on failure.
198  **/
199 guint
200 atk_add_global_event_listener (GSignalEmissionHook listener, gchar* event_type)
201 {
202   guint retval;
203   AtkUtilClass *klass = g_type_class_ref (ATK_TYPE_UTIL);
204   if (klass->add_global_event_listener)
205     {
206       retval = klass->add_global_event_listener (listener, event_type);
207     }
208   else
209     {
210       retval = -1;
211     }
212   g_type_class_unref (klass);
213
214   return retval;
215 }
216
217 /**
218  * atk_remove_global_event_listener:
219  * @listener_id: the id of the event listener to remove
220  *
221  * Removes the specified event listener
222  **/
223 void
224 atk_remove_global_event_listener (guint listener_id)
225 {
226   AtkUtilClass *klass = g_type_class_peek (ATK_TYPE_UTIL);
227
228   if (klass->remove_global_event_listener)
229     klass->remove_global_event_listener (listener_id);
230 }
231
232 /**
233  * atk_get_root:
234  *
235  * Gets the root accessible container for the current application.
236  *
237  * Returns: the root accessible container for the current application
238  **/
239 AtkObject*
240 atk_get_root(void)
241 {
242   AtkUtilClass *klass = g_type_class_peek (ATK_TYPE_UTIL);
243   if (klass->get_root)
244     {
245       return klass->get_root ();
246     }
247   else
248     {
249       return NULL;
250     }
251 }
252
253 /**
254  * atk_get_toolkit_name:
255  *
256  * Gets name string for the GUI toolkit implementing ATK for this application.
257  *
258  * Returns: name string for the GUI toolkit implementing ATK for this application
259  **/
260 gchar* atk_get_toolkit_name(void)
261 {
262   AtkUtilClass *klass = g_type_class_peek (ATK_TYPE_UTIL);
263   if (klass->get_toolkit_name)
264     {
265       return klass->get_toolkit_name ();
266     }
267   else
268     {
269       return NULL;
270     }
271 }
272
273 /**
274  * atk_get_toolkit_version:
275  *
276  * Gets version string for the GUI toolkit implementing ATK for this application.
277  *
278  * Returns: version string for the GUI toolkit implementing ATK for this application
279  **/
280 gchar*
281 atk_get_toolkit_version(void)
282 {
283   AtkUtilClass *klass = g_type_class_peek (ATK_TYPE_UTIL);
284   if (klass->get_toolkit_version)
285     {
286       return klass->get_toolkit_version ();
287     }
288   else
289     {
290       return NULL;
291     }
292 }