1946cb89a2675817be79125b16d3f84e7f2a7ba5
[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.keystring = g_strdup (keystroke->event_string);
199   akeystroke.modifiers = keystroke->modifiers;
200
201   /* FIXME: re-enterancy hazard on this list */
202   for (l = clistener->callbacks; l; l = l->next)
203     {
204       EventHandler *eh = l->data;
205
206       if ((handled = eh->cb.key_event (&akeystroke, eh->user_data)))
207         {
208           break;
209         }
210     }
211   
212   return handled;
213 }
214
215 static void
216 cspi_keystroke_listener_init (CSpiKeystrokeListener *listener)
217 {
218 }
219
220
221 static void
222 cspi_keystroke_listener_finalize (GObject *object)
223 {
224   CSpiKeystrokeListener *listener = (CSpiKeystrokeListener *) object;
225   GList *l;
226   
227   for (l = listener->callbacks; l; l = l->next)
228     {
229       cspi_event_handler_free (l->data);
230     }
231   
232   g_list_free (listener->callbacks);
233
234   keystroke_parent_class->finalize (object);
235 }
236
237 static void
238 cspi_keystroke_listener_class_init (CSpiKeystrokeListenerClass *klass)
239 {
240   GObjectClass *object_class = (GObjectClass *) klass;
241
242   keystroke_parent_class = g_type_class_peek_parent (klass);
243   object_class->finalize = cspi_keystroke_listener_finalize;
244
245   klass->key_event = cspi_key_event;
246 }
247
248 BONOBO_TYPE_FUNC (CSpiKeystrokeListener, 
249                   spi_keystroke_listener_get_type (),
250                   cspi_keystroke_listener);
251
252 gpointer
253 cspi_keystroke_listener_new (void)
254 {
255   CSpiEventListener *listener;
256
257   listener = g_object_new (cspi_keystroke_listener_get_type (), NULL);
258
259   return listener;
260 }
261
262 void
263 cspi_keystroke_listener_add_cb (AccessibleKeystrokeListener  *al,
264                                 AccessibleKeystrokeListenerCB callback,
265                                 void                         *user_data)
266 {
267   CSpiKeystrokeListener *listener = al;
268
269   g_return_if_fail (CSPI_IS_KEYSTROKE_LISTENER (listener));
270
271   listener->callbacks = g_list_prepend (listener->callbacks,
272                                         cspi_event_handler_new (callback, user_data));
273 }
274
275 void
276 cspi_keystroke_listener_remove_cb (AccessibleKeystrokeListener  *al,
277                                    AccessibleKeystrokeListenerCB callback)
278 {
279   CSpiKeystrokeListener *listener = al;
280
281   g_return_if_fail (CSPI_IS_KEYSTROKE_LISTENER (listener));
282
283   listener->callbacks = cspi_event_list_remove_by_cb (listener->callbacks, callback);
284 }
285
286 void
287 cspi_event_listener_unref (AccessibleEventListener *listener)
288 {
289   bonobo_object_unref (BONOBO_OBJECT (listener));
290 }
291
292 void
293 cspi_keystroke_listener_unref (AccessibleKeystrokeListener *listener)
294 {
295   bonobo_object_unref (BONOBO_OBJECT (listener));
296 }
297
298
299 CORBA_Object
300 cspi_event_listener_get_corba (AccessibleEventListener *listener)
301 {
302   return BONOBO_OBJREF (listener);
303 }
304
305 CORBA_Object
306 cspi_keystroke_listener_get_corba (AccessibleKeystrokeListener *listener)
307 {
308   return BONOBO_OBJREF (listener);
309 }
310