fdd759dd6ad60e7c98b3eb599e37e53d49ee07f3
[platform/core/uifw/at-spi2-atk.git] / cspi / bonobo / cspi-bonobo-listener.c
1 #include <libbonobo.h>
2 #include "../spi-private.h"
3 #include "cspi-bonobo-listener.h"
4
5 typedef struct
6 {
7   union
8     {
9       AccessibleEventListenerCB     event;
10       AccessibleKeystrokeListenerCB key_event;
11       gpointer                      method;
12     } cb;
13   gpointer user_data;
14 } EventHandler;
15
16 GObjectClass *event_parent_class;
17 GObjectClass *keystroke_parent_class;
18
19 /*
20  * Misc. helpers.
21  */
22
23 static EventHandler *
24 cspi_event_handler_new (gpointer method, gpointer user_data)
25 {
26   EventHandler *eh = g_new0 (EventHandler, 1);
27
28   eh->cb.method = method;
29   eh->user_data = user_data;
30
31   return eh;
32 }
33
34 static void
35 cspi_event_handler_free (EventHandler *handler)
36 {
37   g_free (handler);
38 }
39
40 static GList *
41 cspi_event_list_remove_by_cb (GList *list, gpointer callback)
42 {
43   GList *l, *next;
44         
45   for (l = list; l; l = next)
46     {
47       EventHandler *eh = l->data;
48       next = l->next;
49       
50       list = g_list_delete_link (list, l);
51       
52       cspi_event_handler_free (eh);
53     }
54
55   return list;
56 }
57
58 /*
59  * Standard event dispatcher
60  */
61
62 BONOBO_CLASS_BOILERPLATE (CSpiEventListener, cspi_event_listener,
63                           GObject, spi_event_listener_get_type ())
64
65 static void
66 cspi_event (SpiEventListener    *listener,
67             Accessibility_Event *event)
68 {
69   GList *l;
70   CSpiEventListener *clistener = (CSpiEventListener *) listener;
71   AccessibleEvent    aevent;
72   Accessible        *source;
73
74   source = cspi_object_add (bonobo_object_dup_ref (event->source, cspi_ev ()));
75
76   aevent.type    = event->type;
77   aevent.source  = source;
78   aevent.detail1 = event->detail1;
79   aevent.detail2 = event->detail2;
80
81   /* FIXME: re-enterancy hazard on this list */
82   for (l = clistener->callbacks; l; l = l->next)
83     {
84       EventHandler *eh = l->data;
85
86       eh->cb.event (&aevent, eh->user_data);
87     }
88
89   cspi_object_unref (source);
90 }
91
92 static void
93 cspi_event_listener_instance_init (CSpiEventListener *listener)
94 {
95 }
96
97 static void
98 cspi_event_listener_finalize (GObject *object)
99 {
100   CSpiEventListener *listener = (CSpiEventListener *) object;
101   GList *l;
102   
103   for (l = listener->callbacks; l; l = l->next)
104     {
105       cspi_event_handler_free (l->data);
106     }
107   
108   g_list_free (listener->callbacks);
109
110   event_parent_class->finalize (object);
111 }
112
113 static void
114 cspi_event_listener_class_init (CSpiEventListenerClass *klass)
115 {
116   GObjectClass *object_class = (GObjectClass *) klass;
117
118   event_parent_class = g_type_class_peek_parent (klass);
119   object_class->finalize = cspi_event_listener_finalize;
120
121   klass->event = cspi_event;
122 }
123
124 gpointer
125 cspi_event_listener_new (void)
126 {
127   CSpiEventListener *listener;
128
129   listener = g_object_new (cspi_event_listener_get_type (), NULL);
130
131   return listener;
132 }
133
134 void
135 cspi_event_listener_add_cb (AccessibleEventListener  *al,
136                             AccessibleEventListenerCB callback,
137                             void                     *user_data)
138 {
139   CSpiEventListener *listener = al;
140
141   g_return_if_fail (CSPI_IS_EVENT_LISTENER (listener));
142
143   listener->callbacks = g_list_prepend (listener->callbacks,
144                                         cspi_event_handler_new (callback, user_data));
145 }
146
147 void
148 cspi_event_listener_remove_cb (AccessibleEventListener  *al,
149                                AccessibleEventListenerCB callback)
150 {
151   CSpiEventListener *listener = al;
152
153   g_return_if_fail (CSPI_IS_EVENT_LISTENER (listener));
154
155   listener->callbacks = cspi_event_list_remove_by_cb (listener->callbacks, callback);
156 }
157
158 /*
159  * Key event dispatcher
160  */
161 static gboolean
162 cspi_key_event (SpiKeystrokeListener            *listener,
163                 const Accessibility_DeviceEvent *keystroke)
164 {
165   GList *l;
166   CSpiKeystrokeListener *clistener = (CSpiKeystrokeListener *) listener;
167   AccessibleKeystroke akeystroke;
168   gboolean handled = FALSE;
169
170 #ifdef SPI_KEYEVENT_DEBUG
171   fprintf (stderr, "%s%c",
172            (keystroke->modifiers & SPI_KEYMASK_ALT)?"Alt-":"",
173            ((keystroke->modifiers & SPI_KEYMASK_SHIFT)^(keystroke->modifiers & SPI_KEYMASK_SHIFTLOCK))?
174            (char) toupper((int) keystroke->keyID) : (char) tolower((int) keystroke->keyID));
175   
176   fprintf (stderr, "Key:\tsym %ld\n\tmods %x\n\tcode %d\n\ttime %ld\n",
177            (long) keystroke->keyID,
178            (unsigned int) keystroke->modifiers,
179            (int) keystroke->keycode,
180            (long int) keystroke->timestamp);
181 #endif
182
183   switch (keystroke->type)
184     {
185       case Accessibility_KEY_PRESSED:
186         akeystroke.type = SPI_KEY_PRESSED;
187         break;
188       case Accessibility_KEY_RELEASED:
189         akeystroke.type = SPI_KEY_RELEASED;
190         break;
191       default:
192         akeystroke.type = 0;
193         break;
194     }
195   akeystroke.keyID     = keystroke->id;
196   akeystroke.keycode   = keystroke->hw_code;
197   akeystroke.timestamp = keystroke->timestamp;
198   akeystroke.modifiers = keystroke->modifiers;
199
200   /* FIXME: re-enterancy hazard on this list */
201   for (l = clistener->callbacks; l; l = l->next)
202     {
203       EventHandler *eh = l->data;
204
205       if ((handled = eh->cb.key_event (&akeystroke, eh->user_data)))
206         {
207           break;
208         }
209     }
210   
211   return handled;
212 }
213
214 static void
215 cspi_keystroke_listener_init (CSpiKeystrokeListener *listener)
216 {
217 }
218
219
220 static void
221 cspi_keystroke_listener_finalize (GObject *object)
222 {
223   CSpiKeystrokeListener *listener = (CSpiKeystrokeListener *) object;
224   GList *l;
225   
226   for (l = listener->callbacks; l; l = l->next)
227     {
228       cspi_event_handler_free (l->data);
229     }
230   
231   g_list_free (listener->callbacks);
232
233   keystroke_parent_class->finalize (object);
234 }
235
236 static void
237 cspi_keystroke_listener_class_init (CSpiKeystrokeListenerClass *klass)
238 {
239   GObjectClass *object_class = (GObjectClass *) klass;
240
241   keystroke_parent_class = g_type_class_peek_parent (klass);
242   object_class->finalize = cspi_keystroke_listener_finalize;
243
244   klass->key_event = cspi_key_event;
245 }
246
247 BONOBO_TYPE_FUNC (CSpiKeystrokeListener, 
248                   spi_keystroke_listener_get_type (),
249                   cspi_keystroke_listener);
250
251 gpointer
252 cspi_keystroke_listener_new (void)
253 {
254   CSpiEventListener *listener;
255
256   listener = g_object_new (cspi_keystroke_listener_get_type (), NULL);
257
258   return listener;
259 }
260
261 void
262 cspi_keystroke_listener_add_cb (AccessibleKeystrokeListener  *al,
263                                 AccessibleKeystrokeListenerCB callback,
264                                 void                         *user_data)
265 {
266   CSpiKeystrokeListener *listener = al;
267
268   g_return_if_fail (CSPI_IS_KEYSTROKE_LISTENER (listener));
269
270   listener->callbacks = g_list_prepend (listener->callbacks,
271                                         cspi_event_handler_new (callback, user_data));
272 }
273
274 void
275 cspi_keystroke_listener_remove_cb (AccessibleKeystrokeListener  *al,
276                                    AccessibleKeystrokeListenerCB callback)
277 {
278   CSpiKeystrokeListener *listener = al;
279
280   g_return_if_fail (CSPI_IS_KEYSTROKE_LISTENER (listener));
281
282   listener->callbacks = cspi_event_list_remove_by_cb (listener->callbacks, callback);
283 }
284
285 void
286 cspi_event_listener_unref (AccessibleEventListener *listener)
287 {
288   bonobo_object_unref (BONOBO_OBJECT (listener));
289 }
290
291 void
292 cspi_keystroke_listener_unref (AccessibleKeystrokeListener *listener)
293 {
294   bonobo_object_unref (BONOBO_OBJECT (listener));
295 }
296
297
298 CORBA_Object
299 cspi_event_listener_get_corba (AccessibleEventListener *listener)
300 {
301   return BONOBO_OBJREF (listener);
302 }
303
304 CORBA_Object
305 cspi_keystroke_listener_get_corba (AccessibleKeystrokeListener *listener)
306 {
307   return BONOBO_OBJREF (listener);
308 }
309