Allow building without X11
[platform/upstream/at-spi2-core.git] / registryd / deviceeventcontroller.c
1 /* AT-SPI - Assistive Technology Service Provider Interface
2  *
3  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
4  *
5  * Copyright 2001, 2003 Sun Microsystems Inc.,
6  * Copyright 2001, 2002 Ximian, 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 /* deviceeventcontroller.c: implement the DeviceEventController interface */
25
26 #include <config.h>
27
28 #undef  SPI_XKB_DEBUG
29 #undef  SPI_DEBUG
30 #undef  SPI_KEYEVENT_DEBUG
31
32 #include <string.h>
33 #include <ctype.h>
34 #include <stdio.h>
35 #include <sys/time.h>
36
37 #include <glib.h>
38
39 #include <dbus/dbus.h>
40
41 #include "paths.h"
42 #include "keymasks.h"
43 #include "de-types.h"
44 #include "de-marshaller.h"
45 #include "display.h"
46 #include "event-source.h"
47
48 #include "deviceeventcontroller.h"
49 #include "reentrant-list.h"
50
51 #include "introspection.h"
52
53 long ucs2keysym (long ucs);
54 long keysym2ucs(long keysym); 
55
56 #define CHECK_RELEASE_DELAY 20
57 #define BIT(c, x)       (c[x/8]&(1<<(x%8)))
58 static SpiDEController *saved_controller;
59
60 /* Our parent Gtk object type */
61 #define PARENT_TYPE G_TYPE_OBJECT
62
63 /* A pointer to our parent object class */
64 static int spi_error_code = 0;
65 struct _SpiPoint {
66     gint x;
67     gint y;
68 };
69 typedef struct _SpiPoint SpiPoint;
70 static unsigned int mouse_mask_state = 0;
71 static unsigned int key_modifier_mask =
72   Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask | ShiftMask | LockMask | ControlMask | SPI_KEYMASK_NUMLOCK;
73 static unsigned int _numlock_physical_mask = Mod2Mask; /* a guess, will be reset */
74
75 static gboolean have_mouse_listener = FALSE;
76 static gboolean have_mouse_event_listener = FALSE;
77
78
79 typedef struct {
80   guint                             ref_count : 30;
81   guint                             pending_add : 1;
82   guint                             pending_remove : 1;
83
84   Accessibility_ControllerEventMask mod_mask;
85   dbus_uint32_t               key_val;  /* KeyCode */
86 } DEControllerGrabMask;
87
88
89 gboolean spi_controller_update_key_grabs               (SpiDEController           *controller,
90                                                                Accessibility_DeviceEvent *recv);
91
92 static gboolean eventtype_seq_contains_event (dbus_uint32_t types,
93                                               const Accessibility_DeviceEvent *event);
94 static gboolean spi_dec_poll_mouse_moving (gpointer data);
95 static gboolean spi_dec_poll_mouse_idle (gpointer data);
96
97 G_DEFINE_TYPE(SpiDEController, spi_device_event_controller, G_TYPE_OBJECT)
98
99 static gint
100 spi_dec_plat_get_keycode (SpiDEController *controller,
101                           gint keysym,
102                           gchar *key_str,
103                           gboolean fix,
104                           guint *modmask)
105 {
106   SpiDEControllerClass *klass;
107   klass = SPI_DEVICE_EVENT_CONTROLLER_GET_CLASS (controller);
108   if (klass->plat.get_keycode)
109     return klass->plat.get_keycode (controller, keysym, key_str, fix, modmask);
110   else
111     return keysym;
112 }
113
114 static guint
115 spi_dec_plat_mouse_check (SpiDEController *controller, 
116                      int *x, int *y, gboolean *moved)
117 {
118   SpiDEControllerClass *klass;
119   klass = SPI_DEVICE_EVENT_CONTROLLER_GET_CLASS (controller);
120   if (klass->plat.mouse_check)
121     return klass->plat.mouse_check (controller, x, y, moved);
122   else
123     return 0;
124 }
125
126 static gboolean
127 spi_dec_plat_grab_key (SpiDEController *controller, guint key_val, Accessibility_ControllerEventMask mod_mask)
128 {
129   SpiDEControllerClass *klass;
130   klass = SPI_DEVICE_EVENT_CONTROLLER_GET_CLASS (controller);
131   if (klass->plat.grab_key)
132     return klass->plat.grab_key (controller, key_val, mod_mask);
133   else
134     return FALSE;
135 }
136
137 static void
138 spi_dec_plat_ungrab_key (SpiDEController *controller, guint key_val, Accessibility_ControllerEventMask mod_mask)
139 {
140   SpiDEControllerClass *klass;
141   klass = SPI_DEVICE_EVENT_CONTROLLER_GET_CLASS (controller);
142   if (klass->plat.ungrab_key)
143     klass->plat.ungrab_key (controller, key_val, mod_mask);
144 }
145
146 static gboolean
147 spi_dec_plat_synth_keycode_press (SpiDEController *controller,
148                          unsigned int keycode)
149 {
150   SpiDEControllerClass *klass;
151   klass = SPI_DEVICE_EVENT_CONTROLLER_GET_CLASS (controller);
152   if (klass->plat.synth_keycode_press)
153     return klass->plat.synth_keycode_press (controller, keycode);
154   else
155     return FALSE;
156 }
157
158 static gboolean
159 spi_dec_plat_synth_keycode_release (SpiDEController *controller,
160                            unsigned int keycode)
161 {
162   SpiDEControllerClass *klass;
163   klass = SPI_DEVICE_EVENT_CONTROLLER_GET_CLASS (controller);
164   if (klass->plat.synth_keycode_release)
165     return klass->plat.synth_keycode_release (controller, keycode);
166   else
167     return FALSE;
168 }
169
170 static gboolean
171 spi_dec_plat_lock_modifiers (SpiDEController *controller, unsigned modifiers)
172 {
173   SpiDEControllerClass *klass;
174   klass = SPI_DEVICE_EVENT_CONTROLLER_GET_CLASS (controller);
175   if (klass->plat.lock_modifiers)
176     return klass->plat.lock_modifiers (controller, modifiers);
177   else
178     return FALSE;
179 }
180
181 static gboolean
182 spi_dec_plat_unlock_modifiers (SpiDEController *controller, unsigned modifiers)
183 {
184   SpiDEControllerClass *klass;
185   klass = SPI_DEVICE_EVENT_CONTROLLER_GET_CLASS (controller);
186   if (klass->plat.unlock_modifiers)
187     return klass->plat.unlock_modifiers (controller, modifiers);
188   else
189     return FALSE;
190 }
191
192 static gboolean
193 spi_dec_plat_synth_keystring (SpiDEController *controller, guint synth_type, gint keycode, const char *keystring)
194 {
195   SpiDEControllerClass *klass;
196   klass = SPI_DEVICE_EVENT_CONTROLLER_GET_CLASS (controller);
197   if (klass->plat.synth_keystring)
198     return klass->plat.synth_keystring (controller, synth_type, keycode, keystring);
199   else
200     return FALSE;
201 }
202
203 static void
204 spi_dec_plat_emit_modifier_event (SpiDEController *controller, guint prev_mask, 
205                              guint current_mask)
206 {
207   SpiDEControllerClass *klass;
208   klass = SPI_DEVICE_EVENT_CONTROLLER_GET_CLASS (controller);
209   if (klass->plat.emit_modifier_event)
210     return klass->plat.emit_modifier_event (controller, prev_mask, current_mask);
211 }
212
213 static void
214 spi_dec_plat_generate_mouse_event (SpiDEController *controller,
215                                    gint x,
216                                    gint y,
217                                    const char *eventName)
218 {
219   SpiDEControllerClass *klass;
220   klass = SPI_DEVICE_EVENT_CONTROLLER_GET_CLASS (controller);
221   if (klass->plat.generate_mouse_event)
222     return klass->plat.generate_mouse_event (controller, x, y, eventName);
223 }
224
225 DBusMessage *
226 invalid_arguments_error (DBusMessage *message)
227 {
228     DBusMessage *reply;
229     gchar       *errmsg;
230
231     errmsg= g_strdup_printf (
232             "Method \"%s\" with signature \"%s\" on interface \"%s\" was supplied with invalid arguments\n",
233             dbus_message_get_member (message),
234             dbus_message_get_signature (message),
235             dbus_message_get_interface (message));
236     reply = dbus_message_new_error (message,
237                                     DBUS_ERROR_INVALID_ARGS,
238                                     errmsg);
239     g_free (errmsg);
240     return reply;
241 }
242
243 /* Private methods */
244 static dbus_bool_t
245 spi_dbus_add_disconnect_match (DBusConnection *bus, const char *name)
246 {
247   char *match = g_strdup_printf ("interface=%s,member=NameOwnerChanged,arg0=%s", DBUS_INTERFACE_DBUS, name);
248   if (match)
249   {
250     DBusError error;
251     dbus_error_init (&error);
252     dbus_bus_add_match (bus, match, &error);
253     g_free (match);
254     if (dbus_error_is_set (&error))
255       {
256         dbus_error_free (&error);
257         return FALSE;
258       }
259     else
260       {
261         return TRUE;
262       }
263   }
264   else return FALSE;
265 }
266
267 static dbus_bool_t
268 spi_dbus_remove_disconnect_match (DBusConnection *bus, const char *name)
269 {
270   char *match = g_strdup_printf ("interface=%s,member=NameOwnerChanged,arg0=%s", DBUS_INTERFACE_DBUS, name);
271   if (match)
272   {
273     DBusError error;
274     dbus_error_init (&error);
275     dbus_bus_remove_match (bus, match, &error);
276     g_free (match);
277     if (dbus_error_is_set (&error))
278       {
279         dbus_error_free (&error);
280         return FALSE;
281       }
282     else
283       {
284         return TRUE;
285       }
286   }
287   else return FALSE;
288 }
289
290 static DEControllerGrabMask *
291 spi_grab_mask_clone (DEControllerGrabMask *grab_mask)
292 {
293   DEControllerGrabMask *clone = g_new (DEControllerGrabMask, 1);
294
295   memcpy (clone, grab_mask, sizeof (DEControllerGrabMask));
296
297   clone->ref_count = 1;
298   clone->pending_add = TRUE;
299   clone->pending_remove = FALSE;
300
301   return clone;
302 }
303
304 static void
305 spi_grab_mask_free (DEControllerGrabMask *grab_mask)
306 {
307   g_free (grab_mask);
308 }
309
310 static gint
311 spi_grab_mask_compare_values (gconstpointer p1, gconstpointer p2)
312 {
313   DEControllerGrabMask *l1 = (DEControllerGrabMask *) p1;
314   DEControllerGrabMask *l2 = (DEControllerGrabMask *) p2;
315
316   if (p1 == p2)
317     {
318       return 0;
319     }
320   else
321     { 
322       return ((l1->mod_mask != l2->mod_mask) || (l1->key_val != l2->key_val));
323     }
324 }
325
326 void
327 spi_dec_dbus_emit (SpiDEController *controller, const char *interface,
328                    const char *name, const char *minor, int a1, int a2)
329 {
330   DBusMessage *signal = NULL;
331   DBusMessageIter iter, iter_struct, iter_variant;
332   int nil = 0;
333   const char *path = SPI_DBUS_PATH_ROOT;
334   const char *bus_name = dbus_bus_get_unique_name (controller->bus);
335
336   signal = dbus_message_new_signal (path, interface, name);
337
338   dbus_message_iter_init_append (signal, &iter);
339
340   dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &minor);
341   dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &a1);
342   dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &a2);
343   dbus_message_iter_open_container (&iter, DBUS_TYPE_VARIANT, "i", &iter_variant);
344       dbus_message_iter_append_basic (&iter_variant, DBUS_TYPE_INT32, &nil);
345   dbus_message_iter_close_container (&iter, &iter_variant);
346
347   dbus_message_iter_open_container (&iter, DBUS_TYPE_STRUCT, NULL,
348                                     &iter_struct);
349   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &bus_name);
350   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path);
351   dbus_message_iter_close_container (&iter, &iter_struct);
352
353   dbus_connection_send (controller->bus, signal, NULL);
354   dbus_message_unref (signal);
355 }
356
357 static gboolean
358 spi_dec_poll_mouse_moved (gpointer data)
359 {
360   SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER(data);
361   int x, y;
362   gboolean moved;
363   guint mask_return;
364
365   mask_return = spi_dec_plat_mouse_check (controller, &x, &y, &moved);
366
367   if ((mask_return & key_modifier_mask) !=
368       (mouse_mask_state & key_modifier_mask)) 
369     {
370       spi_dec_plat_emit_modifier_event (controller, mouse_mask_state, mask_return);
371       mouse_mask_state = mask_return;
372     }
373
374   return moved;
375 }
376
377 static gboolean
378 spi_dec_poll_mouse_idle (gpointer data)
379 {
380   if (!have_mouse_event_listener && !have_mouse_listener)
381     return FALSE;
382   else if (!spi_dec_poll_mouse_moved (data))
383     return TRUE;
384   else
385     {
386       g_timeout_add (20, spi_dec_poll_mouse_moving, data);          
387       return FALSE;         
388     }
389 }
390
391 static gboolean
392 spi_dec_poll_mouse_moving (gpointer data)
393 {
394   if (!have_mouse_event_listener && !have_mouse_listener)
395     return FALSE;
396   else if (spi_dec_poll_mouse_moved (data))
397     return TRUE;
398   else
399     {
400       g_timeout_add (100, spi_dec_poll_mouse_idle, data);           
401       return FALSE;
402     }
403 }
404
405 /**
406  * Eventually we can use this to make the marshalling of mask types
407  * more sane, but for now we just use this to detect 
408  * the use of 'virtual' masks such as numlock and convert them to
409  * system-specific mask values (i.e. ModMask).
410  * 
411  **/
412 static Accessibility_ControllerEventMask
413 spi_dec_translate_mask (Accessibility_ControllerEventMask mask)
414 {
415   Accessibility_ControllerEventMask tmp_mask;
416   gboolean has_numlock;
417
418   has_numlock = (mask & SPI_KEYMASK_NUMLOCK);
419   tmp_mask = mask;
420   if (has_numlock)
421     {
422       tmp_mask = mask ^ SPI_KEYMASK_NUMLOCK;
423       tmp_mask |= _numlock_physical_mask;
424     }
425  
426   return tmp_mask;
427 }
428
429 static DEControllerKeyListener *
430 spi_dec_key_listener_new (const char *bus_name,
431                           const char *path,
432                           GSList *keys,
433                           const Accessibility_ControllerEventMask mask,
434                           const dbus_uint32_t types,
435                           const Accessibility_EventListenerMode  *mode)
436 {
437   DEControllerKeyListener *key_listener = g_new0 (DEControllerKeyListener, 1);
438   key_listener->listener.bus_name = g_strdup(bus_name);
439   key_listener->listener.path = g_strdup(path);
440   key_listener->listener.type = SPI_DEVICE_TYPE_KBD;
441   key_listener->keys = keys;
442   key_listener->mask = spi_dec_translate_mask (mask);
443   key_listener->listener.types = types;
444   if (mode)
445   {
446     key_listener->mode = (Accessibility_EventListenerMode *) g_malloc(sizeof(Accessibility_EventListenerMode));
447     memcpy(key_listener->mode, mode, sizeof(*mode));
448   }
449   else
450     key_listener->mode = NULL;
451
452 #ifdef SPI_DEBUG
453   g_print ("new listener, with mask %x, is_global %d, keys %p (%d)\n",
454            (unsigned int) key_listener->mask,
455            (int) (mode ? mode->global : 0),
456            (void *) key_listener->keys,
457            (int) (key_listener->keys ? g_slist_length(key_listener->keys) : 0));
458 #endif
459
460   return key_listener;  
461 }
462
463 static DEControllerListener *
464 spi_dec_listener_new (const char *bus_name,
465                       const char *path,
466                       dbus_uint32_t types)
467 {
468   DEControllerListener *listener = g_new0 (DEControllerListener, 1);
469   listener->bus_name = g_strdup(bus_name);
470   listener->path = g_strdup(path);
471   listener->type = SPI_DEVICE_TYPE_MOUSE;
472   listener->types = types;
473   return listener;      
474 }
475
476 static DEControllerListener *
477 spi_listener_clone (DEControllerListener *listener)
478 {
479   DEControllerListener *clone = g_new0 (DEControllerListener, 1);
480   clone->bus_name = g_strdup (listener->bus_name);
481   clone->path = g_strdup (listener->path);
482   clone->type = listener->type;
483   clone->types = listener->types;
484   return clone;
485 }
486
487 static GSList *keylist_clone (GSList *s)
488 {
489   GSList *d = NULL;
490   GSList *l;
491
492   for (l = s; l; l = g_slist_next(l))
493   {
494     Accessibility_KeyDefinition *kd = (Accessibility_KeyDefinition *)g_malloc(sizeof(Accessibility_KeyDefinition));
495     if (kd)
496     {
497       Accessibility_KeyDefinition *kds = (Accessibility_KeyDefinition *)l->data;
498       kd->keycode = kds->keycode;
499       kd->keysym = kds->keysym;
500       kd->keystring = g_strdup(kds->keystring);
501       d = g_slist_append(d, kd);
502     }
503   }
504   return d;
505 }
506
507 static DEControllerKeyListener *
508 spi_key_listener_clone (DEControllerKeyListener *key_listener)
509 {
510   DEControllerKeyListener *clone = g_new0 (DEControllerKeyListener, 1);
511   clone->listener.bus_name = g_strdup (key_listener->listener.bus_name);
512   clone->listener.path = g_strdup (key_listener->listener.path);
513   clone->listener.type = SPI_DEVICE_TYPE_KBD;
514   clone->keys = keylist_clone (key_listener->keys);
515   clone->mask = key_listener->mask;
516   clone->listener.types = key_listener->listener.types;
517   if (key_listener->mode)
518   {
519     clone->mode = (Accessibility_EventListenerMode *)g_malloc(sizeof(Accessibility_EventListenerMode));
520     if (clone->mode) memcpy(clone->mode, key_listener->mode, sizeof(Accessibility_EventListenerMode));
521   }
522   else
523     clone->mode = NULL;
524   return clone;
525 }
526
527 static void keylist_free(GSList *keys)
528 {
529   GSList *l;
530
531   for (l = keys; l; l = g_slist_next(l))
532   {
533     Accessibility_KeyDefinition *kd = (Accessibility_KeyDefinition *)l->data;
534     g_free(kd->keystring);
535     g_free(kd);
536   }
537   g_slist_free (keys);
538 }
539
540 static void
541 spi_key_listener_data_free (DEControllerKeyListener *key_listener)
542 {
543   keylist_free(key_listener->keys);
544   if (key_listener->mode) g_free(key_listener->mode);
545   g_free (key_listener->listener.bus_name);
546   g_free (key_listener->listener.path);
547   g_free (key_listener);
548 }
549
550 static void
551 spi_key_listener_clone_free (DEControllerKeyListener *clone)
552 {
553   spi_key_listener_data_free (clone);
554 }
555
556 static void
557 spi_listener_clone_free (DEControllerListener *clone)
558 {
559   g_free (clone->path);
560   g_free (clone->bus_name);
561   g_free (clone);
562 }
563
564 static void
565 spi_dec_listener_free (DEControllerListener    *listener)
566 {
567   if (listener->type == SPI_DEVICE_TYPE_KBD) 
568     spi_key_listener_data_free ((DEControllerKeyListener *) listener);
569   else
570   {
571     g_free (listener->bus_name);
572     g_free (listener->path);
573   }
574 }
575
576 static void
577 _register_keygrab (SpiDEController      *controller,
578                    DEControllerGrabMask *grab_mask)
579 {
580   GList *l;
581
582   l = g_list_find_custom (controller->keygrabs_list, grab_mask,
583                           spi_grab_mask_compare_values);
584   if (l)
585     {
586       DEControllerGrabMask *cur_mask = l->data;
587
588       cur_mask->ref_count++;
589       if (cur_mask->pending_remove)
590         {
591           cur_mask->pending_remove = FALSE;
592         }
593     }
594   else
595     {
596       controller->keygrabs_list =
597         g_list_prepend (controller->keygrabs_list,
598                         spi_grab_mask_clone (grab_mask));
599     }
600 }
601
602 static void
603 _deregister_keygrab (SpiDEController      *controller,
604                      DEControllerGrabMask *grab_mask)
605 {
606   GList *l;
607
608   l = g_list_find_custom (controller->keygrabs_list, grab_mask,
609                           spi_grab_mask_compare_values);
610
611   if (l)
612     {
613       DEControllerGrabMask *cur_mask = l->data;
614
615       cur_mask->ref_count--;
616       if (cur_mask->ref_count <= 0)
617         {
618           cur_mask->pending_remove = TRUE;
619         }
620     }
621 }
622
623 static void
624 handle_keygrab (SpiDEController         *controller,
625                 DEControllerKeyListener *key_listener,
626                 void                   (*process_cb) (SpiDEController *controller,
627                                                       DEControllerGrabMask *grab_mask))
628 {
629   DEControllerGrabMask grab_mask = { 0 };
630
631   grab_mask.mod_mask = key_listener->mask;
632   if (g_slist_length (key_listener->keys) == 0) /* special case means AnyKey/AllKeys */
633     {
634       grab_mask.key_val = AnyKey;
635 #ifdef SPI_DEBUG
636       fprintf (stderr, "AnyKey grab!");
637 #endif
638       process_cb (controller, &grab_mask);
639     }
640   else
641     {
642       GSList *l;
643
644       for (l = key_listener->keys; l; l = g_slist_next(l))
645         {
646           Accessibility_KeyDefinition *keydef = l->data;
647           long key_val;
648           key_val = spi_dec_plat_get_keycode (controller, keydef->keysym, keydef->keystring, FALSE, NULL);
649           if (!key_val)
650             key_val = keydef->keycode;
651           grab_mask.key_val = key_val;
652           process_cb (controller, &grab_mask);
653         }
654     }
655 }
656
657 static gboolean
658 spi_controller_register_global_keygrabs (SpiDEController         *controller,
659                                          DEControllerKeyListener *key_listener)
660 {
661   handle_keygrab (controller, key_listener, _register_keygrab);
662   return spi_controller_update_key_grabs (controller, NULL);
663 }
664
665 static void
666 spi_controller_deregister_global_keygrabs (SpiDEController         *controller,
667                                            DEControllerKeyListener *key_listener)
668 {
669   handle_keygrab (controller, key_listener, _deregister_keygrab);
670   spi_controller_update_key_grabs (controller, NULL);
671 }
672
673 static void
674 append_keystroke_listener (DBusMessageIter *iter, DEControllerKeyListener *listener)
675 {
676   dbus_uint32_t d_uint;
677   DBusMessageIter iter_struct, iter_subarray, iter_substruct;
678   GSList *kl;
679
680   if (!dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT, NULL,
681                                          &iter_struct))
682     return;
683
684   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING,
685                                   &listener->listener.bus_name);
686   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH,
687                                   &listener->listener.path);
688   d_uint = listener->listener.type;
689   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_UINT32, &d_uint);
690   d_uint = listener->listener.types;
691   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_UINT32, &d_uint);
692   if (!dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY,
693                                          "(iisi)", &iter_subarray))
694   {
695     dbus_message_iter_close_container (iter, &iter_struct);
696     return;
697   }
698   for (kl = listener->keys; kl; kl = kl->next)
699   {
700     Accessibility_KeyDefinition *kd = kl->data;
701     if (!dbus_message_iter_open_container (&iter_subarray, DBUS_TYPE_STRUCT,
702                                          NULL, &iter_substruct))
703       break;
704     dbus_message_iter_append_basic (&iter_substruct, DBUS_TYPE_INT32, &kd->keycode);
705     dbus_message_iter_append_basic (&iter_substruct, DBUS_TYPE_INT32, &kd->keysym);
706     dbus_message_iter_append_basic (&iter_substruct, DBUS_TYPE_STRING, &kd->keystring);
707     dbus_message_iter_append_basic (&iter_substruct, DBUS_TYPE_INT32, &kd->unused);
708     dbus_message_iter_close_container (&iter_subarray, &iter_substruct);
709   }
710   dbus_message_iter_close_container (&iter_struct, &iter_subarray);
711   d_uint = listener->mask;
712   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_UINT32, &d_uint);
713   if (dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_STRUCT,
714                                          NULL, &iter_substruct))
715   {
716     if (listener->mode)
717     {
718       dbus_message_iter_append_basic (&iter_substruct, DBUS_TYPE_BOOLEAN,
719                                       &listener->mode->synchronous);
720       dbus_message_iter_append_basic (&iter_substruct, DBUS_TYPE_BOOLEAN,
721                                       &listener->mode->preemptive);
722       dbus_message_iter_append_basic (&iter_substruct, DBUS_TYPE_BOOLEAN,
723                                       &listener->mode->global);
724     }
725     else
726     {
727       dbus_bool_t dummy_val = FALSE;
728       dbus_message_iter_append_basic (&iter_substruct, DBUS_TYPE_BOOLEAN,
729                                       &dummy_val);
730       dbus_message_iter_append_basic (&iter_substruct, DBUS_TYPE_BOOLEAN,
731                                       &dummy_val);
732       dbus_message_iter_append_basic (&iter_substruct, DBUS_TYPE_BOOLEAN,
733                                       &dummy_val);
734     }
735     dbus_message_iter_close_container (&iter_struct, &iter_substruct);
736   }
737   dbus_message_iter_close_container (iter, &iter_struct);
738 }
739
740 static void
741 notify_keystroke_listener (SpiDEController *controller,
742                            DEControllerKeyListener *listener,
743                            gboolean enable)
744 {
745   const char *path = SPI_DBUS_PATH_DEC;
746   const char *interface = SPI_DBUS_INTERFACE_DEVICE_EVENT_LISTENER;
747   const char *name = (enable
748                       ? "KeystrokeListenerRegistered"
749                       : "KeystrokeListenerDeregistered");
750   DBusMessage *signal;
751   DBusMessageIter iter;
752
753   signal = dbus_message_new_signal (path, interface, name);
754   if (!signal)
755     return;
756   dbus_message_iter_init_append (signal, &iter);
757   append_keystroke_listener (&iter, listener);
758   dbus_connection_send (controller->bus, signal, NULL);
759   dbus_message_unref (signal);
760 }
761
762 static void
763 append_mouse_listener (DBusMessageIter *iter, DEControllerListener *listener)
764 {
765   DBusMessageIter iter_struct;
766   dbus_uint32_t d_uint;
767
768   if (!dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT, NULL,
769                                          &iter_struct))
770     return;
771   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING,
772                                   &listener->bus_name);
773   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH,
774                                   &listener->path);
775   d_uint = listener->types;
776   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_UINT32, &d_uint);
777   dbus_message_iter_close_container (iter, &iter_struct);
778 }
779
780 static void
781 notify_mouse_listener (SpiDEController *controller,
782                        DEControllerListener *listener,
783                        gboolean enable)
784 {
785   const char *path = SPI_DBUS_PATH_DEC;
786   const char *interface = SPI_DBUS_INTERFACE_DEVICE_EVENT_LISTENER;
787   const char *name = (enable
788                       ? "DeviceListenerRegistered"
789                       : "DeviceListenerDeregistered");
790   DBusMessage *signal;
791   DBusMessageIter iter;
792
793   signal = dbus_message_new_signal (path, interface, name);
794   if (!signal)
795     return;
796   dbus_message_iter_init_append (signal, &iter);
797   append_mouse_listener (&iter, listener);
798   dbus_connection_send (controller->bus, signal, NULL);
799   dbus_message_unref (signal);
800 }
801
802 static gboolean
803 spi_controller_register_device_listener (SpiDEController      *controller,
804                                          DEControllerListener *listener)
805 {
806   DEControllerKeyListener *key_listener;
807   gboolean retval;
808   
809   switch (listener->type) {
810   case SPI_DEVICE_TYPE_KBD:
811       key_listener = (DEControllerKeyListener *) listener;
812
813       controller->key_listeners = g_list_prepend (controller->key_listeners,
814                                                   key_listener);
815       spi_dbus_add_disconnect_match (controller->bus, key_listener->listener.bus_name);
816       if (key_listener->mode->global)
817         {
818           retval = spi_controller_register_global_keygrabs (controller, key_listener);
819         }
820       else
821           retval = TRUE;
822       if (retval)
823         notify_keystroke_listener (controller, key_listener, TRUE);
824       break;
825   case SPI_DEVICE_TYPE_MOUSE:
826       controller->mouse_listeners = g_list_prepend (controller->mouse_listeners, listener);
827       if (!have_mouse_listener)
828         {
829           have_mouse_listener = TRUE;
830           if (!have_mouse_event_listener)
831             g_timeout_add (100, spi_dec_poll_mouse_idle, controller);
832         }
833       spi_dbus_add_disconnect_match (controller->bus, listener->bus_name);
834       notify_mouse_listener (controller, listener, TRUE);
835       break;
836   default:
837       break;
838   }
839   return FALSE;
840 }
841
842 static void
843 set_reply (DBusPendingCall *pending, void *user_data)
844 {
845     void **replyptr = (void **)user_data;
846
847     *replyptr = dbus_pending_call_steal_reply (pending);
848 }
849
850 static GSList *hung_processes = NULL;
851
852 static void
853 reset_hung_process (DBusPendingCall *pending, void *data)
854 {
855   DBusMessage *message = data;
856   const char *dest = dbus_message_get_destination (message);
857   GSList *l;
858
859   /* At this point we don't care about the result */
860   dbus_pending_call_unref (pending);
861
862   for (l = hung_processes; l; l = l->next)
863   {
864     if (!strcmp (l->data, dest))
865     {
866       g_free (l->data);
867       hung_processes = g_slist_remove (hung_processes, l->data);
868       break;
869     }
870   }
871 }
872
873 static gint
874 time_elapsed (struct timeval *origin)
875 {
876   struct timeval tv;
877
878   gettimeofday (&tv, NULL);
879   return (tv.tv_sec - origin->tv_sec) * 1000 + (tv.tv_usec - origin->tv_usec) / 1000;
880 }
881
882 static void
883 reset_hung_process_from_ping (DBusPendingCall *pending, void *data)
884 {
885   GSList *l;
886
887   for (l = hung_processes; l; l = l->next)
888   {
889     if (!strcmp (l->data, data))
890     {
891       g_free (l->data);
892       hung_processes = g_slist_remove (hung_processes, l->data);
893       break;
894     }
895   }
896   g_free (data);
897   dbus_pending_call_unref (pending);
898 }
899
900 static DBusMessage *
901 send_and_allow_reentry (DBusConnection *bus, DBusMessage *message, int timeout, DBusError *error)
902 {
903     DBusPendingCall *pending;
904     DBusMessage *reply = NULL;
905   struct timeval tv;
906
907     if (!dbus_connection_send_with_reply (bus, message, &pending, -1))
908     {
909         return NULL;
910     }
911     dbus_pending_call_set_notify (pending, set_reply, (void *)&reply, NULL);
912     gettimeofday (&tv, NULL);
913     while (!reply)
914     {
915       if (!dbus_connection_read_write_dispatch (bus, timeout) ||
916           time_elapsed (&tv) > timeout)
917       {
918         const char *dest = dbus_message_get_destination (message);
919         GSList *l;
920         gchar *bus_name_dup;
921         dbus_message_ref (message);
922         dbus_pending_call_set_notify (pending, reset_hung_process, message,
923                                       (DBusFreeFunction) dbus_message_unref);
924         message = dbus_message_new_method_call (dest, "/",
925                                                 "org.freedesktop.DBus.Peer",
926                                                 "Ping");
927         if (!message)
928           return NULL;
929         dbus_connection_send_with_reply (bus, message, &pending, -1);
930         dbus_message_unref (message);
931         if (!pending)
932           return NULL;
933         bus_name_dup = g_strdup (dest);
934         dbus_pending_call_set_notify (pending, reset_hung_process_from_ping,
935                                       bus_name_dup, NULL);
936         for (l = hung_processes; l; l = l->next)
937           if (!strcmp (l->data, dest))
938             return NULL;
939         hung_processes = g_slist_prepend (hung_processes, g_strdup (dest));
940         return NULL;
941       }
942     }
943     dbus_pending_call_unref (pending);
944     return reply;
945 }
946 static gboolean
947 Accessibility_DeviceEventListener_NotifyEvent(SpiDEController *controller,
948                                               SpiRegistry *registry,
949                                               DEControllerListener *listener,
950                                               const Accessibility_DeviceEvent *key_event)
951 {
952   DBusMessage *message = dbus_message_new_method_call(listener->bus_name,
953                                                       listener->path,
954                                                       SPI_DBUS_INTERFACE_DEVICE_EVENT_LISTENER,
955                                                       "NotifyEvent");
956   dbus_bool_t consumed = FALSE;
957   GSList *l;
958   gboolean hung = FALSE;
959
960   for (l = hung_processes; l; l = l->next)
961   {
962     if (!strcmp (l->data, listener->bus_name))
963     {
964       dbus_message_set_no_reply (message, TRUE);
965       hung = TRUE;
966       break;
967     }
968   }
969
970   if (spi_dbus_marshal_deviceEvent(message, key_event))
971   {
972     DBusMessage *reply;
973
974     if (hung)
975     {
976       dbus_connection_send (controller->bus, message, NULL);
977       dbus_message_unref (message);
978       return FALSE;
979     }
980
981     reply = send_and_allow_reentry (controller->bus, message, 3000, NULL);
982     if (reply)
983     {
984       dbus_message_get_args(reply, NULL, DBUS_TYPE_BOOLEAN, &consumed, DBUS_TYPE_INVALID);
985       dbus_message_unref(reply);
986     }
987   }
988   dbus_message_unref(message);
989   return consumed;
990 }
991
992 gboolean
993 spi_controller_notify_mouselisteners (SpiDEController                 *controller,
994                                       const Accessibility_DeviceEvent *event)
995 {
996   GList   *l;
997   GSList  *notify = NULL, *l2;
998   GList  **listeners = &controller->mouse_listeners;
999   gboolean is_consumed;
1000 #ifdef SPI_KEYEVENT_DEBUG
1001   gboolean found = FALSE;
1002 #endif
1003   if (!listeners)
1004     {
1005       return FALSE;
1006     }
1007
1008   for (l = *listeners; l; l = l->next)
1009     {
1010        DEControllerListener *listener = l->data;
1011
1012        if (eventtype_seq_contains_event (listener->types, event))
1013          {
1014            /* we clone (don't dup) the listener, to avoid refcount inc. */
1015            notify = g_slist_prepend (notify,
1016                                      spi_listener_clone (listener));
1017 #ifdef SPI_KEYEVENT_DEBUG
1018            found = TRUE;
1019 #endif
1020          }
1021     }
1022
1023 #ifdef SPI_KEYEVENT_DEBUG
1024   if (!found)
1025     {
1026       g_print ("no match for event\n");
1027     }
1028 #endif
1029
1030   is_consumed = FALSE;
1031   for (l2 = notify; l2 && !is_consumed; l2 = l2->next)
1032     {
1033       DEControllerListener *listener = l2->data;
1034
1035       is_consumed = Accessibility_DeviceEventListener_NotifyEvent (controller, controller->registry, listener, event);
1036
1037       spi_listener_clone_free ((DEControllerListener *) l2->data);
1038     }
1039
1040   for (; l2; l2 = l2->next)
1041     {
1042       DEControllerListener *listener = l2->data;
1043       spi_listener_clone_free (listener);
1044       /* clone doesn't have its own ref, so don't use spi_device_listener_free */
1045     }
1046
1047   g_slist_free (notify);
1048
1049 #ifdef SPI_DEBUG
1050   if (is_consumed) g_message ("consumed\n");
1051 #endif
1052   return is_consumed;
1053 }
1054
1055 static gboolean
1056 key_set_contains_key (GSList                          *key_set,
1057                           const Accessibility_DeviceEvent *key_event)
1058 {
1059   gint i;
1060   gint len;
1061   GSList *l;
1062
1063   if (!key_set)
1064     {
1065 #ifdef SPI_DEBUG
1066       g_print ("null key set!\n");
1067 #endif
1068       return TRUE;
1069     }
1070
1071   len = g_slist_length (key_set);
1072   
1073   if (len == 0) /* special case, means "all keys/any key" */
1074     {
1075 #ifdef SPI_DEBUG
1076       g_print ("anykey\n");         
1077 #endif
1078       return TRUE;
1079     }
1080
1081   for (l = key_set,i = 0; l; l = g_slist_next(l),i++)
1082     {
1083       Accessibility_KeyDefinition *kd = l->data;
1084 #ifdef SPI_KEYEVENT_DEBUG           
1085       g_print ("key_set[%d] event = %d, code = %d; key_event %d, code %d, string %s\n",
1086                 i,
1087                 (int) kd->keysym,
1088                 (int) kd->keycode,
1089                 (int) key_event->id,
1090                 (int) key_event->hw_code,
1091                 key_event->event_string); 
1092 #endif
1093       if (kd->keysym == (dbus_uint32_t) key_event->id)
1094         {
1095           return TRUE;
1096         }
1097       if (kd->keycode == (dbus_uint32_t) key_event->hw_code)
1098         {
1099           return TRUE;
1100         }
1101       if (key_event->event_string && key_event->event_string[0] &&
1102           !strcmp (kd->keystring, key_event->event_string))
1103         {
1104           return TRUE;
1105         }
1106     }
1107
1108   return FALSE;
1109 }
1110
1111 static gboolean
1112 eventtype_seq_contains_event (dbus_uint32_t types,
1113                                   const Accessibility_DeviceEvent *event)
1114 {
1115   if (types == 0) /* special case, means "all events/any event" */
1116     {
1117       return TRUE;
1118     }
1119
1120   return (types & (1 << event->type));
1121 }
1122
1123 static gboolean
1124 spi_key_event_matches_listener (const Accessibility_DeviceEvent *key_event,
1125                                 DEControllerKeyListener         *listener,
1126                                 dbus_bool_t                    is_system_global)
1127 {
1128   if (((key_event->modifiers & 0xFF) == (dbus_uint16_t) (listener->mask & 0xFF)) &&
1129        key_set_contains_key (listener->keys, key_event) &&
1130        eventtype_seq_contains_event (listener->listener.types, key_event) && 
1131       (is_system_global == listener->mode->global))
1132     {
1133       return TRUE;
1134     }
1135   else
1136     {
1137       return FALSE;
1138     }
1139 }
1140
1141 gboolean
1142 spi_controller_notify_keylisteners (SpiDEController                 *controller,
1143                                     Accessibility_DeviceEvent       *key_event,
1144                                     dbus_bool_t                    is_system_global)
1145 {
1146   GList   *l;
1147   GSList  *notify = NULL, *l2;
1148   GList  **key_listeners = &controller->key_listeners;
1149   gboolean is_consumed;
1150
1151   if (!key_listeners)
1152     {
1153       return FALSE;
1154     }
1155
1156   /* set the NUMLOCK event mask bit if appropriate: see bug #143702 */
1157   if (key_event->modifiers & _numlock_physical_mask)
1158       key_event->modifiers |= SPI_KEYMASK_NUMLOCK;
1159
1160   for (l = *key_listeners; l; l = l->next)
1161     {
1162        DEControllerKeyListener *key_listener = l->data;
1163
1164        if (spi_key_event_matches_listener (key_event, key_listener, is_system_global))
1165          {
1166            /* we clone (don't dup) the listener, to avoid refcount inc. */
1167            notify = g_slist_prepend (notify,
1168                                      spi_key_listener_clone (key_listener));
1169          }
1170     }
1171
1172 #ifdef SPI_KEYEVENT_DEBUG
1173   if (!notify)
1174     {
1175       g_print ("no match for event\n");
1176     }
1177 #endif
1178
1179   is_consumed = FALSE;
1180   for (l2 = notify; l2 && !is_consumed; l2 = l2->next)
1181     {
1182       DEControllerKeyListener *key_listener = l2->data;     
1183
1184       is_consumed = Accessibility_DeviceEventListener_NotifyEvent (controller, controller->registry, &key_listener->listener, key_event) &&
1185                     key_listener->mode->preemptive;
1186
1187       spi_key_listener_clone_free (key_listener);
1188     }
1189
1190   for (; l2; l2 = l2->next)
1191     {
1192       DEControllerKeyListener *key_listener = l2->data;     
1193       spi_key_listener_clone_free (key_listener);
1194       /* clone doesn't have its own ref, so don't use spi_dec_listener_free */
1195     }
1196
1197   g_slist_free (notify);
1198
1199 #ifdef SPI_DEBUG
1200   if (is_consumed) g_message ("consumed\n");
1201 #endif
1202   return is_consumed;
1203 }
1204
1205 gboolean
1206 spi_clear_error_state (void)
1207 {
1208         gboolean retval = spi_error_code != 0;
1209         spi_error_code = 0;
1210         return retval;
1211 }
1212
1213 gboolean
1214 spi_controller_update_key_grabs (SpiDEController           *controller,
1215                                  Accessibility_DeviceEvent *recv)
1216 {
1217   GList *l, *next;
1218   gboolean   update_failed = FALSE;
1219   long keycode = 0;
1220   
1221   g_return_val_if_fail (controller != NULL, FALSE);
1222
1223   /*
1224    * masks known to work with default RH 7.1+:
1225    * 0 (no mods), LockMask, Mod1Mask, Mod2Mask, ShiftMask,
1226    * ShiftMask|LockMask, Mod1Mask|LockMask, Mod2Mask|LockMask,
1227    * ShiftMask|Mod1Mask, ShiftMask|Mod2Mask, Mod1Mask|Mod2Mask,
1228    * ShiftMask|LockMask|Mod1Mask, ShiftMask|LockMask|Mod2Mask,
1229    *
1230    * ControlMask grabs are broken, must be in use already
1231    */
1232   if (recv)
1233     keycode = spi_dec_plat_get_keycode (controller, recv->id, NULL, TRUE, NULL);
1234   for (l = controller->keygrabs_list; l; l = next)
1235     {
1236       gboolean do_remove;
1237       gboolean re_issue_grab;
1238       DEControllerGrabMask *grab_mask = l->data;
1239
1240       next = l->next;
1241
1242       re_issue_grab = recv &&
1243               (recv->modifiers & grab_mask->mod_mask) &&
1244               (grab_mask->key_val == keycode);
1245
1246 #ifdef SPI_DEBUG
1247       fprintf (stderr, "mask=%lx %lx (%c%c) %s\n",
1248                (long int) grab_mask->key_val,
1249                (long int) grab_mask->mod_mask,
1250                grab_mask->pending_add ? '+' : '.',
1251                grab_mask->pending_remove ? '-' : '.',
1252                re_issue_grab ? "re-issue": "");
1253 #endif
1254
1255       do_remove = FALSE;
1256
1257       if (grab_mask->pending_add && grab_mask->pending_remove)
1258         {
1259           do_remove = TRUE;
1260         }
1261       else if (grab_mask->pending_remove)
1262         {
1263 #ifdef SPI_DEBUG
1264       fprintf (stderr, "ungrabbing, mask=%x\n", grab_mask->mod_mask);
1265 #endif
1266           spi_dec_plat_ungrab_key (controller,
1267                                grab_mask->key_val,
1268                                grab_mask->mod_mask);
1269
1270           do_remove = TRUE;
1271         }
1272       else if (grab_mask->pending_add || re_issue_grab)
1273         {
1274
1275 #ifdef SPI_DEBUG
1276           fprintf (stderr, "grab %d with mask %x\n", grab_mask->key_val, grab_mask->mod_mask);
1277 #endif
1278           update_failed = spi_dec_plat_grab_key (controller,
1279                                                grab_mask->key_val,
1280                                                grab_mask->mod_mask);
1281           if (update_failed) {
1282                   while (grab_mask->ref_count > 0) --grab_mask->ref_count;
1283                   do_remove = TRUE;
1284           }
1285         }
1286
1287       grab_mask->pending_add = FALSE;
1288       grab_mask->pending_remove = FALSE;
1289
1290       if (do_remove)
1291         {
1292           g_assert (grab_mask->ref_count <= 0);
1293
1294           controller->keygrabs_list = g_list_delete_link (
1295             controller->keygrabs_list, l);
1296
1297           spi_grab_mask_free (grab_mask);
1298         }
1299
1300     } 
1301
1302   return ! update_failed;
1303 }
1304
1305 /*
1306  * Implemented GObject::finalize
1307  */
1308 static void
1309 spi_device_event_controller_object_finalize (GObject *object)
1310 {
1311   SpiDEController *controller;
1312   GObjectClass *parent_class = G_OBJECT_CLASS(spi_device_event_controller_parent_class);
1313   SpiDEControllerClass *klass;
1314
1315   controller = SPI_DEVICE_EVENT_CONTROLLER (object);
1316   klass = SPI_DEVICE_EVENT_CONTROLLER_GET_CLASS (controller);
1317 #ifdef SPI_DEBUG
1318   fprintf(stderr, "spi_device_event_controller_object_finalize called\n");
1319 #endif
1320   if (klass->plat.finalize)
1321     klass->plat.finalize (controller);
1322
1323   parent_class->finalize (object);
1324 }
1325
1326 /*
1327  * DBus Accessibility::DEController::RegisterKeystrokeListener
1328  *     method implementation
1329  */
1330 static DBusMessage *
1331 impl_register_keystroke_listener (DBusConnection *bus,
1332                                   DBusMessage *message,
1333                                   void *user_data)
1334 {
1335   SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER(user_data);
1336   DEControllerKeyListener *dec_listener;
1337   DBusMessageIter iter, iter_array;
1338   const char *path;
1339   GSList *keys = NULL;
1340   dbus_int32_t mask, type;
1341   Accessibility_EventListenerMode *mode;
1342  dbus_bool_t ret;
1343   DBusMessage *reply = NULL;
1344   char *keystring;
1345
1346   if (strcmp (dbus_message_get_signature (message), "oa(iisi)uu(bbb)") != 0)
1347     return invalid_arguments_error (message);
1348
1349   dbus_message_iter_init(message, &iter);
1350   dbus_message_iter_get_basic(&iter, &path);
1351   dbus_message_iter_next(&iter);
1352   dbus_message_iter_recurse(&iter, &iter_array);
1353   while (dbus_message_iter_get_arg_type(&iter_array) != DBUS_TYPE_INVALID)
1354   {
1355     Accessibility_KeyDefinition *kd = (Accessibility_KeyDefinition *)g_malloc(sizeof(Accessibility_KeyDefinition));
1356     if (!spi_dbus_message_iter_get_struct(&iter_array, DBUS_TYPE_INT32, &kd->keycode, DBUS_TYPE_INT32, &kd->keysym, DBUS_TYPE_STRING, &keystring, DBUS_TYPE_INVALID))
1357     {
1358       break;
1359     }
1360     kd->keystring = g_strdup (keystring);
1361     keys = g_slist_append(keys, kd);
1362   }
1363   dbus_message_iter_next(&iter);
1364   dbus_message_iter_get_basic(&iter, &mask);
1365   dbus_message_iter_next(&iter);
1366   dbus_message_iter_get_basic(&iter, &type);
1367   dbus_message_iter_next(&iter);
1368   mode = (Accessibility_EventListenerMode *)g_malloc(sizeof(Accessibility_EventListenerMode));
1369   if (mode)
1370   {
1371     spi_dbus_message_iter_get_struct(&iter, DBUS_TYPE_BOOLEAN, &mode->synchronous, DBUS_TYPE_BOOLEAN, &mode->preemptive, DBUS_TYPE_BOOLEAN, &mode->global, DBUS_TYPE_INVALID);
1372   }
1373 #ifdef SPI_DEBUG
1374   fprintf (stderr, "registering keystroke listener %s:%s with maskVal %lu\n",
1375            dbus_message_get_sender(message), path, (unsigned long) mask);
1376 #endif
1377   dec_listener = spi_dec_key_listener_new (dbus_message_get_sender(message), path, keys, mask, type, mode);
1378   g_free (mode);
1379   ret = spi_controller_register_device_listener (
1380           controller, (DEControllerListener *) dec_listener);
1381   reply = dbus_message_new_method_return (message);
1382   if (reply)
1383   {
1384     dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret, DBUS_TYPE_INVALID);
1385   }
1386   return reply;
1387 }
1388
1389 /*
1390  * DBus Accessibility::DEController::RegisterDeviceEventListener
1391  *     method implementation
1392  */
1393 static DBusMessage *
1394 impl_register_device_event_listener (DBusConnection *bus,
1395                                   DBusMessage *message,
1396                                   void *user_data)
1397 {
1398   SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER(user_data);
1399   DEControllerListener *dec_listener;
1400   const char *path;
1401   dbus_int32_t event_types;
1402   dbus_bool_t ret;
1403   DBusMessage *reply = NULL;
1404
1405   if (!dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_UINT32, &event_types, DBUS_TYPE_INVALID))
1406   {
1407     return invalid_arguments_error (message);
1408   }
1409   dec_listener = spi_dec_listener_new (dbus_message_get_sender(message), path, event_types);
1410   ret =  spi_controller_register_device_listener (
1411           controller, (DEControllerListener *) dec_listener);
1412   reply = dbus_message_new_method_return (message);
1413   if (reply)
1414   {
1415     dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret, DBUS_TYPE_INVALID);
1416   }
1417   return reply;
1418 }
1419
1420 typedef struct {
1421         DBusConnection *bus;
1422         DEControllerListener    *listener;
1423 } RemoveListenerClosure;
1424
1425 static SpiReEntrantContinue
1426 remove_listener_cb (GList * const *list,
1427                     gpointer       user_data)
1428 {
1429   DEControllerListener  *listener = (*list)->data;
1430   RemoveListenerClosure *ctx = user_data;
1431
1432   if (!strcmp(ctx->listener->bus_name, listener->bus_name) &&
1433       !strcmp(ctx->listener->path, listener->path))
1434     {
1435       spi_re_entrant_list_delete_link (list);
1436       spi_dbus_remove_disconnect_match (ctx->bus, listener->bus_name);
1437       spi_dec_listener_free (listener);
1438     }
1439
1440   return SPI_RE_ENTRANT_CONTINUE;
1441 }
1442
1443 static SpiReEntrantContinue
1444 copy_key_listener_cb (GList * const *list,
1445                       gpointer       user_data)
1446 {
1447   DEControllerKeyListener  *key_listener = (*list)->data;
1448   RemoveListenerClosure    *ctx = user_data;
1449
1450   if (!strcmp(ctx->listener->bus_name, key_listener->listener.bus_name) &&
1451       !strcmp(ctx->listener->path, key_listener->listener.path))
1452     {
1453       /* TODO: FIXME aggregate keys in case the listener is registered twice */
1454       DEControllerKeyListener *ctx_key_listener = 
1455         (DEControllerKeyListener *) ctx->listener; 
1456       keylist_free (ctx_key_listener->keys);        
1457       ctx_key_listener->keys = keylist_clone(key_listener->keys);
1458     }
1459
1460   return SPI_RE_ENTRANT_CONTINUE;
1461 }
1462
1463 static void
1464 spi_controller_deregister_device_listener (SpiDEController            *controller,
1465                                            DEControllerListener *listener)
1466 {
1467   RemoveListenerClosure  ctx;
1468
1469   ctx.bus = controller->bus;
1470   ctx.listener = listener;
1471
1472   notify_mouse_listener (controller, listener, FALSE);
1473
1474   spi_re_entrant_list_foreach (&controller->mouse_listeners,
1475                                remove_listener_cb, &ctx);
1476   if (!controller->mouse_listeners)
1477     have_mouse_listener = FALSE;
1478 }
1479
1480 static void
1481 spi_deregister_controller_key_listener (SpiDEController            *controller,
1482                                         DEControllerKeyListener    *key_listener)
1483 {
1484   RemoveListenerClosure  ctx;
1485
1486   ctx.bus = controller->bus;
1487   ctx.listener = (DEControllerListener *) spi_key_listener_clone (key_listener);
1488
1489   notify_keystroke_listener (controller, key_listener, FALSE);
1490
1491   /* special case, copy keyset from existing controller list entry */
1492   if (g_slist_length(key_listener->keys) == 0)
1493     {
1494       spi_re_entrant_list_foreach (&controller->key_listeners,
1495                                   copy_key_listener_cb, &ctx);
1496     }
1497
1498   spi_controller_deregister_global_keygrabs (controller, key_listener);
1499
1500   spi_re_entrant_list_foreach (&controller->key_listeners,
1501                                 remove_listener_cb, &ctx);
1502
1503   spi_key_listener_clone_free ((DEControllerKeyListener *) ctx.listener);
1504 }
1505
1506 void
1507 spi_remove_device_listeners (SpiDEController *controller, const char *bus_name)
1508 {
1509   GList *l, *tmp;
1510
1511   for (l = controller->mouse_listeners; l; l = tmp)
1512   {
1513     DEControllerListener *listener = l->data;
1514     tmp = l->next;
1515     if (!strcmp (listener->bus_name, bus_name))
1516     {
1517       spi_controller_deregister_device_listener (controller, listener);
1518       tmp = controller->mouse_listeners;
1519     }
1520   }
1521   for (l = controller->key_listeners; l; l = tmp)
1522   {
1523     DEControllerKeyListener *key_listener = l->data;
1524     tmp = l->next;
1525     if (!strcmp (key_listener->listener.bus_name, bus_name))
1526     {
1527       /* TODO: untangle the below line(s) */
1528       spi_deregister_controller_key_listener (controller, key_listener);
1529       tmp = controller->key_listeners;
1530     }
1531   }
1532 }
1533
1534 /*
1535  * DBus Accessibility::DEController::DeregisterKeystrokeListener
1536  *     method implementation
1537  */
1538 static DBusMessage *
1539 impl_deregister_keystroke_listener (DBusConnection *bus,
1540                                   DBusMessage *message,
1541                                   void *user_data)
1542 {
1543   SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER(user_data);
1544   DEControllerKeyListener *key_listener;
1545   DBusMessageIter iter, iter_array;
1546   const char *path;
1547   GSList *keys = NULL;
1548   dbus_int32_t mask, type;
1549   DBusMessage *reply = NULL;
1550
1551   dbus_message_iter_init(message, &iter);
1552   if (strcmp (dbus_message_get_signature (message), "oa(iisi)uu") != 0)
1553   {
1554     g_warning ("Received DeregisterKeystrokeListener with strange signature '%s'", dbus_message_get_signature (message));
1555     return invalid_arguments_error (message);
1556   }
1557
1558   dbus_message_iter_get_basic(&iter, &path);
1559   dbus_message_iter_next(&iter);
1560   dbus_message_iter_recurse(&iter, &iter_array);
1561   while (dbus_message_iter_get_arg_type(&iter_array) != DBUS_TYPE_INVALID)
1562   {
1563     Accessibility_KeyDefinition *kd = (Accessibility_KeyDefinition *)g_malloc(sizeof(Accessibility_KeyDefinition));
1564   char *keystring;
1565
1566     if (!spi_dbus_message_iter_get_struct(&iter_array, DBUS_TYPE_INT32, &kd->keycode, DBUS_TYPE_INT32, &kd->keysym, DBUS_TYPE_STRING, &keystring, DBUS_TYPE_INVALID))
1567     {
1568       break;
1569     }
1570     kd->keystring = g_strdup (keystring);
1571     keys = g_slist_append(keys, kd);
1572   }
1573   dbus_message_iter_next(&iter);
1574   dbus_message_iter_get_basic(&iter, &mask);
1575   dbus_message_iter_next(&iter);
1576   dbus_message_iter_get_basic(&iter, &type);
1577   dbus_message_iter_next(&iter);
1578   key_listener = spi_dec_key_listener_new (dbus_message_get_sender(message), path, keys, mask, type, NULL);
1579 #ifdef SPI_DEREGISTER_DEBUG
1580   fprintf (stderr, "deregistering keystroke listener %p with maskVal %lu\n",
1581            (void *) l, (unsigned long) mask->value);
1582 #endif
1583
1584   spi_deregister_controller_key_listener (controller, key_listener);
1585
1586   spi_dec_listener_free ((DEControllerListener *) key_listener);
1587   reply = dbus_message_new_method_return (message);
1588   return reply;
1589 }
1590
1591 /*
1592  * DBus Accessibility::DEController::DeregisterDeviceEventListener
1593  *     method implementation
1594  */
1595 static DBusMessage *
1596 impl_deregister_device_event_listener (DBusConnection *bus,
1597                                   DBusMessage *message,
1598                                   void *user_data)
1599 {
1600   SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER(user_data);
1601   DEControllerListener *listener;
1602   const char *path;
1603   dbus_int32_t event_types;
1604   DBusMessage *reply = NULL;
1605
1606   if (!dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_UINT32, &event_types, DBUS_TYPE_INVALID))
1607   {
1608     return invalid_arguments_error (message);
1609   }
1610   listener = spi_dec_listener_new (dbus_message_get_sender(message), path, event_types);
1611   spi_controller_deregister_device_listener (
1612           controller, listener);
1613   reply = dbus_message_new_method_return (message);
1614   return reply;
1615 }
1616
1617 static DBusMessage *
1618 impl_get_keystroke_listeners (DBusConnection *bus,
1619                                   DBusMessage *message,
1620                                   void *user_data)
1621 {
1622   SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER(user_data);
1623   DBusMessageIter iter, iter_array;
1624   DBusMessage *reply = dbus_message_new_method_return (message);
1625   GList *l;
1626
1627   if (!reply)
1628     return NULL;
1629
1630   dbus_message_iter_init_append (reply, &iter);
1631   dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
1632                                     "(souua(iisi)u(bbb))", &iter_array);
1633   for (l = controller->key_listeners; l; l = l->next)
1634   {
1635     append_keystroke_listener (&iter_array, l->data);
1636   }
1637   dbus_message_iter_close_container (&iter, &iter_array);
1638   return reply;
1639 }
1640
1641 static DBusMessage *
1642 impl_get_device_event_listeners (DBusConnection *bus,
1643                                   DBusMessage *message,
1644                                   void *user_data)
1645 {
1646   SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER(user_data);
1647   DBusMessageIter iter, iter_array;
1648   GList *l;
1649   DBusMessage *reply = dbus_message_new_method_return (message);
1650
1651   if (!reply)
1652     return NULL;
1653
1654   dbus_message_iter_init_append (reply, &iter);
1655   dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
1656                                     "(sou)", &iter_array);
1657   for (l = controller->key_listeners; l; l = l->next)
1658   {
1659     append_mouse_listener (&iter_array, l->data);
1660   }
1661   dbus_message_iter_close_container (&iter, &iter_array);
1662   return reply;
1663 }
1664
1665 static unsigned
1666 get_modifier_state (SpiDEController *controller)
1667 {
1668         return mouse_mask_state;
1669 }
1670
1671 gboolean
1672 spi_dec_synth_keysym (SpiDEController *controller, long keysym)
1673 {
1674         long key_synth_code;
1675         unsigned int modifiers, synth_mods, lock_mods;
1676
1677         key_synth_code = spi_dec_plat_get_keycode (controller, keysym, NULL, TRUE, &synth_mods);
1678
1679         if ((key_synth_code == 0) || (synth_mods == 0xFF)) return FALSE;
1680
1681         /* TODO: set the modifiers accordingly! */
1682         modifiers = get_modifier_state (controller);
1683         /* side-effect; we may unset mousebutton modifiers here! */
1684
1685         lock_mods = 0;
1686         if (synth_mods != modifiers) {
1687                 lock_mods = synth_mods & ~modifiers;
1688                 spi_dec_plat_lock_modifiers (controller, lock_mods);
1689         }
1690         spi_dec_plat_synth_keycode_press (controller, key_synth_code);
1691         spi_dec_plat_synth_keycode_release (controller, key_synth_code);
1692
1693         if (synth_mods != modifiers) 
1694                 spi_dec_plat_unlock_modifiers (controller, lock_mods);
1695         return TRUE;
1696 }
1697
1698
1699
1700 /*
1701  * DBus Accessibility::DEController::RegisterKeystrokeListener
1702  *     method implementation
1703  */
1704 static DBusMessage *
1705 impl_generate_keyboard_event (DBusConnection *bus, DBusMessage *message, void *user_data)
1706 {
1707   SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER(user_data);
1708   dbus_int32_t keycode;
1709   char *keystring;
1710   dbus_uint32_t synth_type;
1711   DBusMessage *reply = NULL;
1712
1713   if (!dbus_message_get_args(message, NULL, DBUS_TYPE_INT32, &keycode, DBUS_TYPE_STRING, &keystring, DBUS_TYPE_UINT32, &synth_type, DBUS_TYPE_INVALID))
1714   {
1715     return invalid_arguments_error (message);
1716   }
1717
1718 #ifdef SPI_DEBUG
1719         fprintf (stderr, "synthesizing keystroke %ld, type %d\n",
1720                  (long) keycode, (int) synth_type);
1721 #endif
1722   /* TODO: hide/wrap/remove X dependency */
1723
1724   /*
1725    * TODO: when initializing, query for XTest extension before using,
1726    * and fall back to XSendEvent() if XTest is not available.
1727    */
1728   
1729   switch (synth_type)
1730     {
1731       case Accessibility_KEY_PRESS:
1732               spi_dec_plat_synth_keycode_press (controller, keycode);
1733               break;
1734       case Accessibility_KEY_PRESSRELEASE:
1735               spi_dec_plat_synth_keycode_press (controller, keycode);
1736       case Accessibility_KEY_RELEASE:
1737               spi_dec_plat_synth_keycode_release (controller, keycode);
1738               break;
1739       case Accessibility_KEY_SYM:
1740 #ifdef SPI_XKB_DEBUG          
1741               fprintf (stderr, "KeySym synthesis\n");
1742 #endif
1743               /* 
1744                * note: we are using long for 'keycode'
1745                * in our arg list; it can contain either
1746                * a keycode or a keysym.
1747                */
1748               spi_dec_synth_keysym (controller, (KeySym) keycode);
1749               break;
1750       case Accessibility_KEY_STRING:
1751               if (!spi_dec_plat_synth_keystring (controller, synth_type, keycode, keystring))
1752                       fprintf (stderr, "Keystring synthesis failure, string=%s\n",
1753                                keystring);
1754               break;
1755     }
1756   reply = dbus_message_new_method_return (message);
1757   return reply;
1758 }
1759
1760 /* Accessibility::DEController::GenerateMouseEvent */
1761 static DBusMessage *
1762 impl_generate_mouse_event (DBusConnection *bus, DBusMessage *message, void *user_data)
1763 {
1764   dbus_int32_t       x;
1765   dbus_int32_t       y;
1766   char *eventName;
1767   DBusMessage *reply = NULL;
1768
1769   if (!dbus_message_get_args(message, NULL, DBUS_TYPE_INT32, &x, DBUS_TYPE_INT32, &y, DBUS_TYPE_STRING, &eventName, DBUS_TYPE_INVALID))
1770   {
1771     return invalid_arguments_error (message);
1772   }
1773
1774 #ifdef SPI_DEBUG
1775   fprintf (stderr, "generating mouse %s event at %ld, %ld\n",
1776            eventName, (long int) x, (long int) y);
1777 #endif
1778   spi_dec_plat_generate_mouse_event (saved_controller, x, y, eventName);
1779   reply = dbus_message_new_method_return (message);
1780   return reply;
1781 }
1782
1783 /* Accessibility::DEController::NotifyListenersSync */
1784 static DBusMessage *
1785 impl_notify_listeners_sync (DBusConnection *bus, DBusMessage *message, void *user_data)
1786 {
1787   SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER(user_data);
1788   Accessibility_DeviceEvent event;
1789   dbus_bool_t ret;
1790   DBusMessage *reply = NULL;
1791
1792   if (!spi_dbus_demarshal_deviceEvent(message, &event))
1793   {
1794     return invalid_arguments_error (message);
1795   }
1796 #ifdef SPI_DEBUG
1797   g_print ("notifylistening listeners synchronously: controller %p, event id %d\n",
1798            controller, (int) event.id);
1799 #endif
1800   ret = spi_controller_notify_keylisteners (controller,
1801                                              (Accessibility_DeviceEvent *) 
1802                                              &event, FALSE) ?
1803           TRUE : FALSE; 
1804   reply = dbus_message_new_method_return (message);
1805   if (reply)
1806   {
1807     dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret, DBUS_TYPE_INVALID);
1808   }
1809   return reply;
1810 }
1811
1812 static DBusMessage *
1813 impl_notify_listeners_async (DBusConnection *bus, DBusMessage *message, void *user_data)
1814 {
1815   SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER(user_data);
1816   Accessibility_DeviceEvent event;
1817   DBusMessage *reply = NULL;
1818
1819   if (!spi_dbus_demarshal_deviceEvent(message, &event))
1820   {
1821     return invalid_arguments_error (message);
1822   }
1823 #ifdef SPI_DEBUG
1824   g_print ("notifylistening listeners asynchronously: controller %p, event id %d\n",
1825            controller, (int) event.id);
1826 #endif
1827   spi_controller_notify_keylisteners (controller, (Accessibility_DeviceEvent *)
1828                                       &event, FALSE); 
1829   reply = dbus_message_new_method_return (message);
1830   return reply;
1831 }
1832
1833 static void
1834 spi_device_event_controller_class_init (SpiDEControllerClass *klass)
1835 {
1836   GObjectClass * object_class = (GObjectClass *) klass;
1837
1838   spi_device_event_controller_parent_class = g_type_class_peek_parent (klass);
1839
1840   object_class->finalize = spi_device_event_controller_object_finalize;
1841
1842 #ifdef HAVE_X11
1843   if (g_getenv ("DISPLAY"))
1844     spi_dec_setup_x11 (klass);
1845   else
1846 #endif
1847   g_type_class_add_private (object_class, sizeof (long)); /* dummy */
1848 }
1849
1850 static void
1851 spi_device_event_controller_init (SpiDEController *device_event_controller)
1852 {
1853   SpiDEControllerClass *klass;
1854   klass = SPI_DEVICE_EVENT_CONTROLLER_GET_CLASS (device_event_controller);
1855
1856   /* TODO: shouldn't be gpointer below */
1857   device_event_controller->priv = G_TYPE_INSTANCE_GET_PRIVATE (device_event_controller,
1858                                               SPI_DEVICE_EVENT_CONTROLLER_TYPE,
1859                                               gpointer);
1860   device_event_controller->message_queue = g_queue_new ();
1861   saved_controller = device_event_controller;
1862
1863   if (klass->plat.init)
1864     klass->plat.init (device_event_controller);
1865 }
1866
1867
1868 /*---------------------------------------------------------------------------*/
1869
1870 static const char *introspection_header =
1871 "<?xml version=\"1.0\"?>\n";
1872
1873 static const char *introspection_node_element =
1874 "<node name=\"%s\">\n";
1875
1876 static const char *introspection_footer =
1877 "</node>";
1878
1879 static DBusMessage *
1880 impl_Introspect (DBusConnection * bus,
1881                  DBusMessage * message, void *user_data)
1882 {
1883   GString *output;
1884   gchar *final;
1885
1886   const gchar *pathstr = SPI_DBUS_PATH_DEC;
1887
1888   DBusMessage *reply;
1889
1890   output = g_string_new(introspection_header);
1891
1892   g_string_append_printf(output, introspection_node_element, pathstr);
1893
1894   g_string_append (output, spi_org_a11y_atspi_DeviceEventController);
1895
1896   g_string_append(output, introspection_footer);
1897   final = g_string_free(output, FALSE);
1898
1899   reply = dbus_message_new_method_return (message);
1900   dbus_message_append_args(reply, DBUS_TYPE_STRING, &final, DBUS_TYPE_INVALID);
1901
1902   g_free(final);
1903   return reply;
1904 }
1905
1906 /*---------------------------------------------------------------------------*/
1907
1908 static void
1909 handle_dec_method_from_idle (DBusConnection *bus, DBusMessage *message, void *user_data)
1910 {
1911   const gchar *iface   = dbus_message_get_interface (message);
1912   const gchar *member  = dbus_message_get_member (message);
1913   DBusHandlerResult result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1914   DBusMessage *reply = NULL;
1915
1916   if (!strcmp (iface, SPI_DBUS_INTERFACE_DEC))
1917     {
1918       result = DBUS_HANDLER_RESULT_HANDLED;
1919       if      (!strcmp (member, "RegisterKeystrokeListener"))
1920           reply = impl_register_keystroke_listener (bus, message, user_data);
1921       else if (!strcmp (member, "RegisterDeviceEventListener"))
1922           reply = impl_register_device_event_listener (bus, message, user_data);
1923       else if (!strcmp (member, "DeregisterKeystrokeListener"))
1924           reply = impl_deregister_keystroke_listener (bus, message, user_data);
1925       else if (!strcmp (member, "DeregisterDeviceEventListener"))
1926           reply = impl_deregister_device_event_listener (bus, message, user_data);
1927       else if (!strcmp (member, "GetKeystrokeListeners"))
1928           reply = impl_get_keystroke_listeners (bus, message, user_data);
1929       else if (!strcmp (member, "GetDeviceEventListeners"))
1930           reply = impl_get_device_event_listeners (bus, message, user_data);
1931       else if (!strcmp (member, "GenerateKeyboardEvent"))
1932           reply = impl_generate_keyboard_event (bus, message, user_data);
1933       else if (!strcmp (member, "GenerateMouseEvent"))
1934           reply = impl_generate_mouse_event (bus, message, user_data);
1935       else if (!strcmp (member, "NotifyListenersSync"))
1936           reply = impl_notify_listeners_sync (bus, message, user_data);
1937       else if (!strcmp (member, "NotifyListenersAsync"))
1938           reply = impl_notify_listeners_async (bus, message, user_data);
1939       else
1940           result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1941     }
1942
1943   if (!strcmp (iface, "org.freedesktop.DBus.Introspectable"))
1944     {
1945       result = DBUS_HANDLER_RESULT_HANDLED;
1946       if      (!strcmp (member, "Introspect"))
1947           reply = impl_Introspect (bus, message, user_data);
1948       else
1949           result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1950     }
1951
1952   if (result == DBUS_HANDLER_RESULT_HANDLED)
1953     {
1954       if (!reply)
1955         {
1956           reply = dbus_message_new_method_return (message);
1957         }
1958
1959       dbus_connection_send (bus, reply, NULL);
1960       dbus_message_unref (reply);
1961     }
1962 }
1963
1964 static gboolean
1965 message_queue_dispatch (gpointer data)
1966 {
1967   saved_controller->message_queue_idle = 0;
1968   while (!g_queue_is_empty (saved_controller->message_queue))
1969     {
1970       DBusMessage *message = g_queue_pop_head (saved_controller->message_queue);
1971       data = g_queue_pop_head (saved_controller->message_queue);
1972       handle_dec_method_from_idle (saved_controller->bus, message, data);
1973       dbus_message_unref (message);
1974     }
1975   return FALSE;
1976 }
1977
1978 static DBusHandlerResult
1979 handle_dec_method (DBusConnection *bus, DBusMessage *message, void *user_data)
1980 {
1981   const gchar *iface   = dbus_message_get_interface (message);
1982   const gchar *member  = dbus_message_get_member (message);
1983   const gint   type    = dbus_message_get_type (message);
1984
1985   /* Check for basic reasons not to handle */
1986   if (type   != DBUS_MESSAGE_TYPE_METHOD_CALL ||
1987       member == NULL ||
1988       iface  == NULL)
1989       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1990
1991   dbus_message_ref (message);
1992   g_queue_push_tail (saved_controller->message_queue, message);
1993   g_queue_push_tail (saved_controller->message_queue, user_data);
1994   if (!saved_controller->message_queue_idle)
1995     saved_controller->message_queue_idle = g_idle_add (message_queue_dispatch, NULL);
1996   return DBUS_HANDLER_RESULT_HANDLED;
1997 }
1998
1999 static DBusObjectPathVTable dec_vtable =
2000 {
2001   NULL,
2002   &handle_dec_method,
2003   NULL, NULL, NULL, NULL
2004 };
2005
2006 SpiDEController *
2007 spi_registry_dec_new (SpiRegistry *reg, DBusConnection *bus)
2008 {
2009   SpiDEController *dec = g_object_new (SPI_DEVICE_EVENT_CONTROLLER_TYPE, NULL);
2010
2011   dec->registry = g_object_ref (reg);
2012   reg->dec = g_object_ref (dec);
2013   dec->bus = bus;
2014
2015   dbus_connection_register_object_path (bus, SPI_DBUS_PATH_DEC, &dec_vtable, dec);
2016
2017   return dec;
2018 }
2019
2020 void
2021 spi_device_event_controller_start_poll_mouse (SpiRegistry *registry)
2022 {
2023   if (!have_mouse_event_listener)
2024     {
2025       have_mouse_event_listener = TRUE;
2026       if (!have_mouse_listener)
2027       g_timeout_add (100, spi_dec_poll_mouse_idle, registry->dec);
2028     }
2029 }
2030
2031 void
2032 spi_device_event_controller_stop_poll_mouse (void)
2033 {
2034   have_mouse_event_listener = FALSE;
2035 }