Changes to introspection generation to remove DOCTYPE and XML
[platform/core/uifw/at-spi2-atk.git] / cspi / bonobo / cspi-bonobo-listener.c
1 /*
2  * AT-SPI - Assistive Technology Service Provider Interface
3  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
4  *
5  * Copyright 2002 Ximian Inc.
6  * Copyright 2002 Sun Microsystems, Inc.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 #include <libbonobo.h>
25 #include "../spi-private.h"
26 #include "cspi-bonobo-listener.h"
27
28 typedef struct
29 {
30   union
31     {
32       AccessibleEventListenerCB     event;
33       AccessibleDeviceListenerCB    device_event;
34       gpointer                      method;
35     } cb;
36   gpointer user_data;
37 } EventHandler;
38
39 GObjectClass *event_parent_class;
40 GObjectClass *device_parent_class;
41
42 static guint32 _e_id = 0;
43
44 /*
45  * Misc. helpers.
46  */
47
48 static EventHandler *
49 cspi_event_handler_new (gpointer method, gpointer user_data)
50 {
51   EventHandler *eh = g_new0 (EventHandler, 1);
52
53   eh->cb.method = method;
54   eh->user_data = user_data;
55
56   return eh;
57 }
58
59 static void
60 cspi_event_handler_free (EventHandler *handler)
61 {
62   g_free (handler);
63 }
64
65 static GList *
66 cspi_event_list_remove_by_cb (GList *list, gpointer callback)
67 {
68   GList *l, *next;
69         
70   for (l = list; l; l = next)
71     {
72       EventHandler *eh = l->data;
73       next = l->next;
74
75       if (eh->cb.method == callback)
76       {
77         list = g_list_delete_link (list, l);
78         cspi_event_handler_free (eh);
79       }
80     }
81
82   return list;
83 }
84
85 /*
86  * Standard event dispatcher
87  */
88
89 BONOBO_CLASS_BOILERPLATE (CSpiEventListener, cspi_event_listener,
90                           GObject, spi_event_listener_get_type ())
91
92 static void
93 cspi_event (SpiEventListener    *listener,
94             Accessibility_Event *event)
95 {
96   GList *l;
97   CSpiEventListener *clistener = (CSpiEventListener *) listener;
98   InternalEvent     *ievent;
99   AccessibleEvent   *aevent;
100   Accessible        *source = cspi_object_borrow (event->source);
101   
102   ievent = g_new0(InternalEvent, 1);
103   ievent->event.type    = g_strdup (event->type);
104   ievent->event.source  = source;
105   ievent->event.detail1 = event->detail1;
106   ievent->event.detail2 = event->detail2;
107   ievent->id            = _e_id++;
108   ievent->magic         = SPI_INTERNAL_EVENT_MAGIC;
109   ievent->ref_count     = 0;
110   ievent->data          = CORBA_any__alloc ();
111   CORBA_any__copy (ievent->data, &event->any_data);
112   aevent = (AccessibleEvent *)ievent;
113   Accessible_ref (source);
114   AccessibleEvent_ref (aevent);
115
116   /* FIXME: re-enterancy hazard on this list */
117   for (l = clistener->callbacks; l; l = l->next)
118     {
119       EventHandler *eh = l->data;
120       /* cast hides our private stuff from client handlers */
121       eh->cb.event (aevent, eh->user_data);
122     }
123
124   AccessibleEvent_unref (aevent);
125   cspi_object_return (source);
126 }
127
128 static void
129 cspi_event_listener_instance_init (CSpiEventListener *listener)
130 {
131 }
132
133 static void
134 cspi_event_listener_finalize (GObject *object)
135 {
136   CSpiEventListener *listener = (CSpiEventListener *) object;
137   GList *l;
138   
139   for (l = listener->callbacks; l; l = l->next)
140     {
141       cspi_event_handler_free (l->data);
142     }
143   
144   g_list_free (listener->callbacks);
145
146   event_parent_class->finalize (object);
147 }
148
149 static void
150 cspi_event_listener_class_init (CSpiEventListenerClass *klass)
151 {
152   GObjectClass *object_class = (GObjectClass *) klass;
153
154   event_parent_class = g_type_class_peek_parent (klass);
155   object_class->finalize = cspi_event_listener_finalize;
156
157   klass->event = cspi_event;
158 }
159
160 gpointer
161 cspi_event_listener_new (void)
162 {
163   CSpiEventListener *listener;
164
165   listener = g_object_new (cspi_event_listener_get_type (), NULL);
166
167   return listener;
168 }
169
170 void
171 cspi_event_listener_add_cb (AccessibleEventListener  *al,
172                             AccessibleEventListenerCB callback,
173                             void                     *user_data)
174 {
175   CSpiEventListener *listener = al;
176
177   g_return_if_fail (CSPI_IS_EVENT_LISTENER (listener));
178
179   listener->callbacks = g_list_prepend (listener->callbacks,
180                                         cspi_event_handler_new ((void *) callback, user_data));
181 }
182
183 void
184 cspi_event_listener_remove_cb (AccessibleEventListener  *al,
185                                AccessibleEventListenerCB callback)
186 {
187   CSpiEventListener *listener = al;
188
189   g_return_if_fail (CSPI_IS_EVENT_LISTENER (listener));
190
191   listener->callbacks = cspi_event_list_remove_by_cb (listener->callbacks, (void *) callback);
192 }
193
194 /* 
195  * Device event handler
196  */
197 static gboolean
198 cspi_device_event (SpiDeviceListener               *listener,
199                    const Accessibility_DeviceEvent *event)
200 {
201   GList *l;
202   CSpiDeviceListener *clistener = (CSpiDeviceListener *) listener;
203   AccessibleDeviceEvent anevent;
204   gboolean handled = FALSE;
205
206   switch (event->type)
207     {
208       case Accessibility_KEY_PRESSED_EVENT:
209         anevent.type = SPI_KEY_PRESSED;
210         break;
211       case Accessibility_KEY_RELEASED_EVENT:
212         anevent.type = SPI_KEY_RELEASED;
213         break;
214       case Accessibility_BUTTON_PRESSED_EVENT:
215         anevent.type = SPI_BUTTON_PRESSED;
216         break;
217       case Accessibility_BUTTON_RELEASED_EVENT:
218         anevent.type = SPI_BUTTON_RELEASED;
219         break;
220       default:
221         anevent.type = 0;
222         break;
223     }
224   anevent.keyID     = event->id;
225   anevent.keycode   = event->hw_code;
226   anevent.timestamp = event->timestamp;
227   anevent.keystring = g_strdup (event->event_string);
228   anevent.modifiers = event->modifiers;
229   anevent.is_text = event->is_text;
230
231   /* FIXME: re-enterancy hazard on this list */
232   for (l = clistener->callbacks; l; l = l->next)
233     {
234       EventHandler *eh = l->data;
235
236       if ((handled = eh->cb.device_event (&anevent, eh->user_data)))
237         {
238           break;
239         }
240     }
241   g_free (anevent.keystring);
242
243   return handled;
244 }
245
246 static void
247 cspi_device_listener_init (CSpiDeviceListener *listener)
248 {
249 }
250
251 static void
252 cspi_device_listener_finalize (GObject *object)
253 {
254   CSpiDeviceListener *listener = (CSpiDeviceListener *) object;
255   GList *l;
256   
257   for (l = listener->callbacks; l; l = l->next)
258     {
259       cspi_event_handler_free (l->data);
260     }
261   
262   g_list_free (listener->callbacks);
263
264   device_parent_class->finalize (object);
265 }
266
267 static void
268 cspi_device_listener_class_init (CSpiDeviceListenerClass *klass)
269 {
270   GObjectClass *object_class = (GObjectClass *) klass;
271
272   device_parent_class = g_type_class_peek_parent (klass);
273   object_class->finalize = cspi_device_listener_finalize;
274
275   klass->device_event = cspi_device_event;
276 }
277
278 BONOBO_TYPE_FUNC (CSpiDeviceListener, 
279                   spi_device_listener_get_type (),
280                   cspi_device_listener)
281
282 gpointer
283 cspi_device_listener_new (void)
284 {
285   CSpiEventListener *listener = g_object_new (cspi_device_listener_get_type (), NULL);
286
287   return listener;
288 }
289
290 void
291 cspi_device_listener_add_cb (AccessibleDeviceListener  *al,
292                              AccessibleDeviceListenerCB callback,
293                              void                      *user_data)
294 {
295   CSpiDeviceListener *listener = al;
296
297   g_return_if_fail (CSPI_IS_DEVICE_LISTENER (listener));
298
299   listener->callbacks = g_list_prepend (listener->callbacks,
300                                         cspi_event_handler_new ((void *)callback, user_data));
301 }
302
303 void
304 cspi_device_listener_remove_cb (AccessibleDeviceListener  *al,
305                                 AccessibleDeviceListenerCB callback)
306 {
307   CSpiDeviceListener *listener = al;
308
309   g_return_if_fail (CSPI_IS_DEVICE_LISTENER (listener));
310
311   listener->callbacks = cspi_event_list_remove_by_cb (listener->callbacks, (void *) callback);
312 }
313
314 void
315 cspi_event_listener_unref (AccessibleEventListener *listener)
316 {
317   bonobo_object_unref (BONOBO_OBJECT (listener));
318 }
319
320 void
321 cspi_device_listener_unref (AccessibleDeviceListener *listener)
322 {
323   bonobo_object_unref (BONOBO_OBJECT (listener));
324 }
325
326
327 CORBA_Object
328 cspi_event_listener_get_corba (AccessibleEventListener *listener)
329 {
330   return BONOBO_OBJREF (listener);
331 }
332
333 CORBA_Object
334 cspi_device_listener_get_corba (AccessibleDeviceListener *listener)
335 {
336   return BONOBO_OBJREF (listener);
337 }
338