2009-06-18 Li Yuan <liyuan@liyuan-desktop.(none)>
[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 <X11/Xlib.h>
38 #include <X11/extensions/XTest.h>
39 #include <X11/XKBlib.h>
40 #define XK_MISCELLANY
41 #define XK_LATIN1
42 #include <X11/keysymdef.h>
43
44 #ifdef HAVE_XEVIE
45 #include <X11/Xproto.h>
46 #include <X11/X.h>
47 #include <X11/extensions/Xevie.h>
48 #endif /* HAVE_XEVIE */
49
50 #include <glib.h>
51 #include <gdk/gdk.h>
52 #include <gdk/gdkx.h> /* TODO: hide dependency (wrap in single porting file) */
53 #include <gdk/gdkkeysyms.h>
54
55 #include <spi-common/keymasks.h>
56 #include <spi-common/spi-dbus.h>
57 #include <spi-common/spi-types.h>
58
59 #include <droute/droute.h>
60
61 #include "deviceeventcontroller.h"
62 #include "reentrant-list.h"
63
64 KeySym ucs2keysym (long ucs);
65 long keysym2ucs(KeySym keysym); 
66
67 #define CHECK_RELEASE_DELAY 20
68 #define BIT(c, x)       (c[x/8]&(1<<(x%8)))
69 static guint check_release_handler = 0;
70 static Accessibility_DeviceEvent pressed_event;
71 static SpiDEController *saved_controller; 
72 static void wait_for_release_event (XEvent *event, SpiDEController *controller);
73
74 /* Our parent Gtk object type */
75 #define PARENT_TYPE G_TYPE_OBJECT
76
77 /* A pointer to our parent object class */
78 static int spi_error_code = 0;
79 static GdkPoint last_mouse_pos_static = {0, 0}; 
80 static GdkPoint *last_mouse_pos = &last_mouse_pos_static;
81 static unsigned int mouse_mask_state = 0;
82 static unsigned int mouse_button_mask =
83   Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask;
84 static unsigned int key_modifier_mask =
85   Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask | ShiftMask | LockMask | ControlMask | SPI_KEYMASK_NUMLOCK;
86 static unsigned int _numlock_physical_mask = Mod2Mask; /* a guess, will be reset */
87
88 static GQuark spi_dec_private_quark = 0;
89 static XModifierKeymap* xmkeymap = NULL;
90
91 static gboolean have_mouse_listener = FALSE;
92 static gboolean have_mouse_event_listener = FALSE;
93
94 static int (*x_default_error_handler) (Display *display, XErrorEvent *error_event);
95
96 typedef enum {
97   SPI_DEVICE_TYPE_KBD,
98   SPI_DEVICE_TYPE_MOUSE,
99   SPI_DEVICE_TYPE_LAST_DEFINED
100 } SpiDeviceTypeCategory;
101
102 typedef struct {
103   guint                             ref_count : 30;
104   guint                             pending_add : 1;
105   guint                             pending_remove : 1;
106
107   Accessibility_ControllerEventMask mod_mask;
108   dbus_uint32_t               key_val;  /* KeyCode */
109 } DEControllerGrabMask;
110
111 typedef struct {
112   char *bus_name;
113   char *path;
114   SpiDeviceTypeCategory type;
115   gulong types;
116 } DEControllerListener;
117
118 typedef struct {
119   DEControllerListener listener;
120
121  GSList *keys;
122   Accessibility_ControllerEventMask mask;
123   Accessibility_EventListenerMode  *mode;       
124 } DEControllerKeyListener;
125
126 typedef struct {
127   unsigned int last_press_keycode;
128   unsigned int last_release_keycode;
129   struct timeval last_press_time;
130   struct timeval last_release_time;
131   int have_xkb;
132   int xkb_major_extension_opcode;
133   int xkb_base_event_code;
134   int xkb_base_error_code;
135   unsigned int xkb_latch_mask;
136   unsigned int pending_xkb_mod_relatch_mask;
137   XkbDescPtr xkb_desc;
138   KeyCode reserved_keycode;
139   KeySym reserved_keysym;
140   guint  reserved_reset_timeout;
141 } DEControllerPrivateData;
142
143 static void     spi_controller_register_with_devices          (SpiDEController           *controller);
144 static gboolean spi_controller_update_key_grabs               (SpiDEController           *controller,
145                                                                Accessibility_DeviceEvent *recv);
146 static gboolean spi_controller_register_device_listener       (SpiDEController           *controller,
147                                                                DEControllerListener      *l);
148 static gboolean spi_device_event_controller_forward_key_event (SpiDEController           *controller,
149                                                                const XEvent              *event);
150 static void     spi_controller_deregister_device_listener (SpiDEController            *controller,
151                                                            DEControllerListener *listener);
152 static void     spi_deregister_controller_key_listener (SpiDEController         *controller,
153                                                         DEControllerKeyListener *key_listener);
154 static gboolean spi_controller_notify_mouselisteners (SpiDEController                 *controller,
155                                                       const Accessibility_DeviceEvent *event);
156
157 static gboolean spi_eventtype_seq_contains_event (dbus_uint32_t types,
158                                                   const Accessibility_DeviceEvent *event);
159 static gboolean spi_clear_error_state (void);
160 static gboolean spi_dec_poll_mouse_moved (gpointer data);
161 static gboolean spi_dec_poll_mouse_moving (gpointer data);
162 static gboolean spi_dec_poll_mouse_idle (gpointer data);
163
164 #define spi_get_display() GDK_DISPLAY()
165
166 G_DEFINE_TYPE(SpiDEController, spi_device_event_controller, G_TYPE_OBJECT)
167
168 /* Private methods */
169 static dbus_bool_t
170 spi_dbus_add_disconnect_match (DBusConnection *bus, const char *name)
171 {
172   char *match = g_strdup_printf ("interface=%s,member=NameOwnerChanged,arg0=%s", DBUS_INTERFACE_DBUS, name);
173   if (match)
174   {
175     DBusError error;
176     dbus_error_init (&error);
177     dbus_bus_add_match (bus, match, &error);
178     g_free (match);
179     return !dbus_error_is_set (&error);
180   }
181   else return FALSE;
182 }
183
184 static dbus_bool_t
185 spi_dbus_remove_disconnect_match (DBusConnection *bus, const char *name)
186 {
187   char *match = g_strdup_printf ("interface=%s,member=NameOwnerChanged,arg0=%s", DBUS_INTERFACE_DBUS, name);
188   if (match)
189   {
190     DBusError error;
191     dbus_error_init (&error);
192     dbus_bus_remove_match (bus, match, &error);
193     g_free (match);
194     return !dbus_error_is_set (&error);
195   }
196   else return FALSE;
197 }
198
199 static unsigned int
200 keysym_mod_mask (KeySym keysym, KeyCode keycode)
201 {
202         /* we really should use XKB and look directly at the keymap */
203         /* this is very inelegant */
204         Display *display = spi_get_display ();
205         unsigned int mods_rtn = 0;
206         unsigned int retval = 0;
207         KeySym sym_rtn;
208
209         if (XkbLookupKeySym (display, keycode, 0, &mods_rtn, &sym_rtn) &&
210             (sym_rtn == keysym)) {
211                 retval = 0;
212         }
213         else if (XkbLookupKeySym (display, keycode, ShiftMask, &mods_rtn, &sym_rtn) &&
214                  (sym_rtn == keysym)) {
215                 retval = ShiftMask;
216         }
217         else if (XkbLookupKeySym (display, keycode, Mod2Mask, &mods_rtn, &sym_rtn) &&
218                  (sym_rtn == keysym)) {
219                 retval = Mod2Mask;
220         }
221         else if (XkbLookupKeySym (display, keycode, Mod3Mask, &mods_rtn, &sym_rtn) &&
222                  (sym_rtn == keysym)) {
223                 retval = Mod3Mask;
224         }
225         else if (XkbLookupKeySym (display, keycode, 
226                                   ShiftMask | Mod2Mask, &mods_rtn, &sym_rtn) &&
227                  (sym_rtn == keysym)) {
228                 retval = (Mod2Mask | ShiftMask);
229         }
230         else if (XkbLookupKeySym (display, keycode, 
231                                   ShiftMask | Mod3Mask, &mods_rtn, &sym_rtn) &&
232                  (sym_rtn == keysym)) {
233                 retval = (Mod3Mask | ShiftMask);
234         }
235         else if (XkbLookupKeySym (display, keycode, 
236                                   ShiftMask | Mod4Mask, &mods_rtn, &sym_rtn) &&
237                  (sym_rtn == keysym)) {
238                 retval = (Mod4Mask | ShiftMask);
239         }
240         else
241                 retval = 0xFFFF;
242         return retval;
243 }
244
245 static gboolean
246 spi_dec_replace_map_keysym (DEControllerPrivateData *priv, KeyCode keycode, KeySym keysym)
247 {
248 #ifdef HAVE_XKB
249   Display *dpy = spi_get_display ();
250   XkbDescPtr desc;
251   if (!(desc = XkbGetMap (dpy, XkbAllMapComponentsMask, XkbUseCoreKbd)))
252     {
253       fprintf (stderr, "ERROR getting map\n");
254     }
255   XFlush (dpy);
256   XSync (dpy, False);
257   if (desc && desc->map)
258     {
259       gint offset = desc->map->key_sym_map[keycode].offset;
260       desc->map->syms[offset] = keysym; 
261     }
262   else
263     {
264       fprintf (stderr, "Error changing key map: empty server structure\n");
265     }           
266   XkbSetMap (dpy, XkbAllMapComponentsMask, desc);
267   /**
268    *  FIXME: the use of XkbChangeMap, and the reuse of the priv->xkb_desc structure, 
269    * would be far preferable.
270    * HOWEVER it does not seem to work using XFree 4.3. 
271    **/
272   /*        XkbChangeMap (dpy, priv->xkb_desc, priv->changes); */
273   XFlush (dpy);
274   XSync (dpy, False);
275   XkbFreeKeyboard (desc, 0, TRUE);
276
277   return TRUE;
278 #else
279   return FALSE;
280 #endif
281 }
282
283 static gboolean
284 spi_dec_reset_reserved (gpointer data)
285 {
286   DEControllerPrivateData *priv = data;
287   spi_dec_replace_map_keysym (priv, priv->reserved_keycode, priv->reserved_keysym);
288   priv->reserved_reset_timeout = 0;
289   return FALSE;
290 }
291
292 static KeyCode
293 keycode_for_keysym (SpiDEController *controller, long keysym, unsigned int *modmask)
294 {
295         KeyCode keycode = 0;
296         keycode = XKeysymToKeycode (spi_get_display (), (KeySym) keysym);
297         if (!keycode) 
298         {
299                 DEControllerPrivateData *priv = (DEControllerPrivateData *)
300                         g_object_get_qdata (G_OBJECT (controller), spi_dec_private_quark);
301                 /* if there's no keycode available, fix it */
302                 if (spi_dec_replace_map_keysym (priv, priv->reserved_keycode, keysym))
303                 {
304                         keycode = priv->reserved_keycode;
305                         /* 
306                          * queue a timer to restore the old keycode.  Ugly, but required 
307                          * due to races / asynchronous X delivery.   
308                          * Long-term fix is to extend the X keymap here instead of replace entries.
309                          */
310                         priv->reserved_reset_timeout = g_timeout_add (500, spi_dec_reset_reserved, priv);
311                 }               
312                 *modmask = 0;
313                 return keycode;
314         }
315         if (modmask) 
316                 *modmask = keysym_mod_mask (keysym, keycode);
317         return keycode;
318 }
319
320 static DEControllerGrabMask *
321 spi_grab_mask_clone (DEControllerGrabMask *grab_mask)
322 {
323   DEControllerGrabMask *clone = g_new (DEControllerGrabMask, 1);
324
325   memcpy (clone, grab_mask, sizeof (DEControllerGrabMask));
326
327   clone->ref_count = 1;
328   clone->pending_add = TRUE;
329   clone->pending_remove = FALSE;
330
331   return clone;
332 }
333
334 static void
335 spi_grab_mask_free (DEControllerGrabMask *grab_mask)
336 {
337   g_free (grab_mask);
338 }
339
340 static gint
341 spi_grab_mask_compare_values (gconstpointer p1, gconstpointer p2)
342 {
343   DEControllerGrabMask *l1 = (DEControllerGrabMask *) p1;
344   DEControllerGrabMask *l2 = (DEControllerGrabMask *) p2;
345
346   if (p1 == p2)
347     {
348       return 0;
349     }
350   else
351     { 
352       return ((l1->mod_mask != l2->mod_mask) || (l1->key_val != l2->key_val));
353     }
354 }
355
356 static void
357 spi_dec_set_unlatch_pending (SpiDEController *controller, unsigned mask)
358 {
359   DEControllerPrivateData *priv = 
360     g_object_get_qdata (G_OBJECT (controller), spi_dec_private_quark);
361 #ifdef SPI_XKB_DEBUG
362   if (priv->xkb_latch_mask) fprintf (stderr, "unlatch pending! %x\n", 
363                                      priv->xkb_latch_mask);
364 #endif
365   priv->pending_xkb_mod_relatch_mask |= priv->xkb_latch_mask; 
366 }
367  
368 static void
369 spi_dec_clear_unlatch_pending (SpiDEController *controller)
370 {
371   DEControllerPrivateData *priv = 
372     g_object_get_qdata (G_OBJECT (controller), spi_dec_private_quark);
373   priv->xkb_latch_mask = 0;
374 }
375
376 static void emit(SpiDEController *controller, const char *interface, const char *name, int a1, int a2)
377 {
378   DBusMessage *signal = NULL;
379   DBusMessageIter iter, iter_variant;
380   int nil = 0;
381   const char *minor = "";
382   const char *path = SPI_DBUS_PATH_DESKTOP;
383
384   signal = dbus_message_new_signal (path, interface, name);
385
386   dbus_message_iter_init_append (signal, &iter);
387
388   dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &minor);
389   dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &a1);
390   dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &a2);
391   dbus_message_iter_open_container (&iter, DBUS_TYPE_VARIANT, "i", &iter_variant);
392       dbus_message_iter_append_basic (&iter_variant, DBUS_TYPE_INT32, &nil);
393   dbus_message_iter_close_container (&iter, &iter_variant);
394
395   dbus_connection_send (controller->bus, signal, NULL);
396 }
397
398 static gboolean
399 spi_dec_button_update_and_emit (SpiDEController *controller,
400                                 guint mask_return)
401 {
402   Accessibility_DeviceEvent mouse_e;
403   gchar event_detail[24];
404   gboolean is_consumed = FALSE;
405
406   if ((mask_return & mouse_button_mask) !=
407       (mouse_mask_state & mouse_button_mask)) 
408     {
409       int button_number = 0;
410       gboolean is_down = False;
411       
412       if (!(mask_return & Button1Mask) &&
413           (mouse_mask_state & Button1Mask)) 
414         {
415           mouse_mask_state &= ~Button1Mask;
416           button_number = 1;
417         } 
418       else if ((mask_return & Button1Mask) &&
419                !(mouse_mask_state & Button1Mask)) 
420         {
421           mouse_mask_state |= Button1Mask;
422           button_number = 1;
423           is_down = True;
424         } 
425       else if (!(mask_return & Button2Mask) &&
426                (mouse_mask_state & Button2Mask)) 
427         {
428           mouse_mask_state &= ~Button2Mask;
429           button_number = 2;
430         } 
431       else if ((mask_return & Button2Mask) &&
432                !(mouse_mask_state & Button2Mask)) 
433         {
434           mouse_mask_state |= Button2Mask;
435           button_number = 2;
436           is_down = True;
437         } 
438       else if (!(mask_return & Button3Mask) &&
439                (mouse_mask_state & Button3Mask)) 
440         {
441           mouse_mask_state &= ~Button3Mask;
442           button_number = 3;
443         } 
444       else if ((mask_return & Button3Mask) &&
445                !(mouse_mask_state & Button3Mask)) 
446         {
447           mouse_mask_state |= Button3Mask;
448           button_number = 3;
449           is_down = True;
450         } 
451       else if (!(mask_return & Button4Mask) &&
452                (mouse_mask_state & Button4Mask)) 
453         {
454           mouse_mask_state &= ~Button4Mask;
455           button_number = 4;
456         } 
457       else if ((mask_return & Button4Mask) &&
458                !(mouse_mask_state & Button4Mask)) 
459         {
460           mouse_mask_state |= Button4Mask;
461           button_number = 4;
462           is_down = True;
463         } 
464       else if (!(mask_return & Button5Mask) &&
465                (mouse_mask_state & Button5Mask)) 
466         {
467           mouse_mask_state &= ~Button5Mask;
468           button_number = 5;
469         }
470       else if ((mask_return & Button5Mask) &&
471                !(mouse_mask_state & Button5Mask)) 
472         {
473           mouse_mask_state |= Button5Mask;
474           button_number = 5;
475           is_down = True;
476         }
477       if (button_number) {
478 #ifdef SPI_DEBUG                  
479         fprintf (stderr, "Button %d %s\n",
480                  button_number, (is_down) ? "Pressed" : "Released");
481 #endif
482         snprintf (event_detail, 22, "%d%c", button_number,
483                   (is_down) ? 'p' : 'r');
484         /* TODO: FIXME distinguish between physical and 
485          * logical buttons 
486          */
487         mouse_e.type      = (is_down) ? 
488           Accessibility_BUTTON_PRESSED_EVENT :
489           Accessibility_BUTTON_RELEASED_EVENT;
490         mouse_e.id        = button_number;
491         mouse_e.hw_code   = button_number;
492         mouse_e.modifiers = (dbus_uint16_t) mouse_mask_state; 
493         mouse_e.timestamp = 0;
494         mouse_e.event_string = "";
495         mouse_e.is_text   = FALSE;
496         is_consumed = 
497           spi_controller_notify_mouselisteners (controller, 
498                                                 &mouse_e);
499         if (!is_consumed)
500           {
501             dbus_uint32_t x = last_mouse_pos->x, y = last_mouse_pos->y;
502             emit(controller, SPI_DBUS_INTERFACE_EVENT_MOUSE, "button", x, y);
503           }
504         else
505           spi_dec_set_unlatch_pending (controller, mask_return);
506       }
507       return TRUE;
508     }
509   else
510     {
511       return FALSE;
512     }
513 }
514
515
516 static guint
517 spi_dec_mouse_check (SpiDEController *controller, 
518                      int *x, int *y, gboolean *moved)
519 {
520   int win_x_return,win_y_return;
521   unsigned int mask_return;
522   Window root_return, child_return;
523   Display *display = spi_get_display ();
524
525   if (display != NULL)
526     XQueryPointer(display, DefaultRootWindow (display),
527                   &root_return, &child_return,
528                   x, y,
529                   &win_x_return, &win_y_return, &mask_return);
530   /* 
531    * Since many clients grab the pointer, and X goes an automatic
532    * pointer grab on mouse-down, we often must detect mouse button events
533    * by polling rather than via a button grab. 
534    * The while loop (rather than if) is used since it's possible that 
535    * multiple buttons have changed state since we last checked.
536    */
537   if (mask_return != mouse_mask_state) 
538     {
539       while (spi_dec_button_update_and_emit (controller, mask_return));
540     }
541
542   if (*x != last_mouse_pos->x || *y != last_mouse_pos->y) 
543     {
544       // TODO: combine these two signals?
545       dbus_uint32_t ix = *x, iy = *y;
546       emit(controller, SPI_DBUS_INTERFACE_EVENT_MOUSE, "abs", ix, iy);
547       ix -= last_mouse_pos->x;
548       iy -= last_mouse_pos->y;
549       emit(controller, SPI_DBUS_INTERFACE_EVENT_MOUSE, "rel", ix, iy);
550       last_mouse_pos->x = *x;
551       last_mouse_pos->y = *y;
552       *moved = True;
553     }
554   else
555     {
556       *moved = False;
557     }
558
559   return mask_return;
560 }
561
562 static void
563 spi_dec_emit_modifier_event (SpiDEController *controller, guint prev_mask, 
564                              guint current_mask)
565 {
566   dbus_uint32_t d1, d2;
567
568 #ifdef SPI_XKB_DEBUG
569   fprintf (stderr, "MODIFIER CHANGE EVENT! %x to %x\n", 
570            prev_mask, current_mask);
571 #endif
572
573   /* set bits for the virtual modifiers like NUMLOCK */
574   if (prev_mask & _numlock_physical_mask) 
575     prev_mask |= SPI_KEYMASK_NUMLOCK;
576   if (current_mask & _numlock_physical_mask) 
577     current_mask |= SPI_KEYMASK_NUMLOCK;
578
579   d1 = prev_mask & key_modifier_mask;
580   d2 = current_mask & key_modifier_mask;
581       emit(controller, SPI_DBUS_INTERFACE_EVENT_KEYBOARD, "modifiers", d1, d2);
582 }
583
584 static gboolean
585 spi_dec_poll_mouse_moved (gpointer data)
586 {
587   SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER(data);
588   int x, y;
589   gboolean moved;
590   guint mask_return;
591
592   mask_return = spi_dec_mouse_check (controller, &x, &y, &moved);
593
594   if ((mask_return & key_modifier_mask) !=
595       (mouse_mask_state & key_modifier_mask)) 
596     {
597       spi_dec_emit_modifier_event (controller, mouse_mask_state, mask_return);
598       mouse_mask_state = mask_return;
599     }
600
601   return moved;
602 }
603
604 static gboolean
605 spi_dec_poll_mouse_idle (gpointer data)
606 {
607   if (!have_mouse_event_listener && !have_mouse_listener)
608     return FALSE;
609   else if (!spi_dec_poll_mouse_moved (data))
610     return TRUE;
611   else
612     {
613       g_timeout_add (20, spi_dec_poll_mouse_moving, data);          
614       return FALSE;         
615     }
616 }
617
618 static gboolean
619 spi_dec_poll_mouse_moving (gpointer data)
620 {
621   if (!have_mouse_event_listener && !have_mouse_listener)
622     return FALSE;
623   else if (spi_dec_poll_mouse_moved (data))
624     return TRUE;
625   else
626     {
627       g_timeout_add (100, spi_dec_poll_mouse_idle, data);           
628       return FALSE;
629     }
630 }
631
632 #ifdef WE_NEED_UGRAB_MOUSE
633 static int
634 spi_dec_ungrab_mouse (gpointer data)
635 {
636         Display *display = spi_get_display ();
637         if (display)
638           {
639             XUngrabButton (spi_get_display (), AnyButton, AnyModifier,
640                            XDefaultRootWindow (spi_get_display ()));
641           }
642         return FALSE;
643 }
644 #endif
645
646 static void
647 spi_dec_init_mouse_listener (SpiDEController *dec)
648 {
649 #ifdef GRAB_BUTTON
650   Display *display = spi_get_display ();
651
652   if (display)
653     {
654       if (XGrabButton (display, AnyButton, AnyModifier,
655                        gdk_x11_get_default_root_xwindow (),
656                        True, ButtonPressMask | ButtonReleaseMask,
657                        GrabModeSync, GrabModeAsync, None, None) != Success) {
658 #ifdef SPI_DEBUG
659         fprintf (stderr, "WARNING: could not grab mouse buttons!\n");
660 #endif
661         ;
662       }
663       XSync (display, False);
664 #ifdef SPI_DEBUG
665       fprintf (stderr, "mouse buttons grabbed\n");
666 #endif
667     }
668 #endif
669 }
670
671 /**
672  * Eventually we can use this to make the marshalling of mask types
673  * more sane, but for now we just use this to detect 
674  * the use of 'virtual' masks such as numlock and convert them to
675  * system-specific mask values (i.e. ModMask).
676  * 
677  **/
678 static Accessibility_ControllerEventMask
679 spi_dec_translate_mask (Accessibility_ControllerEventMask mask)
680 {
681   Accessibility_ControllerEventMask tmp_mask;
682   gboolean has_numlock;
683
684   has_numlock = (mask & SPI_KEYMASK_NUMLOCK);
685   tmp_mask = mask;
686   if (has_numlock)
687     {
688       tmp_mask = mask ^ SPI_KEYMASK_NUMLOCK;
689       tmp_mask |= _numlock_physical_mask;
690     }
691  
692   return tmp_mask;
693 }
694
695 static DEControllerKeyListener *
696 spi_dec_key_listener_new (const char *bus_name,
697                           const char *path,
698                           GSList *keys,
699                           const Accessibility_ControllerEventMask mask,
700                           const dbus_uint32_t types,
701                           const Accessibility_EventListenerMode  *mode)
702 {
703   DEControllerKeyListener *key_listener = g_new0 (DEControllerKeyListener, 1);
704   key_listener->listener.bus_name = g_strdup(bus_name);
705   key_listener->listener.path = g_strdup(path);
706   key_listener->listener.type = SPI_DEVICE_TYPE_KBD;
707   key_listener->keys = keys;
708   key_listener->mask = spi_dec_translate_mask (mask);
709   key_listener->listener.types = types;
710   if (mode)
711   {
712     key_listener->mode = (Accessibility_EventListenerMode *) g_malloc(sizeof(Accessibility_EventListenerMode));
713     memcpy(key_listener->mode, mode, sizeof(*mode));
714   }
715   else
716     key_listener->mode = NULL;
717
718 #ifdef SPI_DEBUG
719   g_print ("new listener, with mask %x, is_global %d, keys %p (%d)\n",
720            (unsigned int) key_listener->mask,
721            (int) (mode ? mode->global : 0),
722            (void *) key_listener->keys,
723            (int) (key_listener->keys ? g_slist_length(key_listener->keys) : 0));
724 #endif
725
726   return key_listener;  
727 }
728
729 static DEControllerListener *
730 spi_dec_listener_new (const char *bus_name,
731                       const char *path,
732                       dbus_uint32_t types)
733 {
734   DEControllerListener *listener = g_new0 (DEControllerListener, 1);
735   listener->bus_name = g_strdup(bus_name);
736   listener->path = g_strdup(path);
737   listener->type = SPI_DEVICE_TYPE_MOUSE;
738   listener->types = types;
739   return listener;      
740 }
741
742 static DEControllerListener *
743 spi_listener_clone (DEControllerListener *listener)
744 {
745   DEControllerListener *clone = g_new0 (DEControllerListener, 1);
746   clone->bus_name = g_strdup (listener->bus_name);
747   clone->path = g_strdup (listener->path);
748   clone->type = listener->type;
749   clone->types = listener->types;
750   return clone;
751 }
752
753 static GSList *keylist_clone (GSList *s)
754 {
755   GSList *d = NULL;
756   GSList *l;
757
758   for (l = s; l; l = g_slist_next(l))
759   {
760     Accessibility_KeyDefinition *kd = (Accessibility_KeyDefinition *)g_malloc(sizeof(Accessibility_KeyDefinition));
761     if (kd)
762     {
763       Accessibility_KeyDefinition *kds = (Accessibility_KeyDefinition *)l->data;
764       kd->keycode = kds->keycode;
765       kd->keysym = kds->keysym;
766       kd->keystring = g_strdup(kds->keystring);
767       d = g_slist_append(d, kd);
768     }
769   }
770   return d;
771 }
772
773 static DEControllerKeyListener *
774 spi_key_listener_clone (DEControllerKeyListener *key_listener)
775 {
776   DEControllerKeyListener *clone = g_new0 (DEControllerKeyListener, 1);
777   clone->listener.bus_name = g_strdup (key_listener->listener.bus_name);
778   clone->listener.path = g_strdup (key_listener->listener.path);
779   clone->listener.type = SPI_DEVICE_TYPE_KBD;
780   clone->keys = keylist_clone (key_listener->keys);
781   clone->mask = key_listener->mask;
782   clone->listener.types = key_listener->listener.types;
783   if (key_listener->mode)
784   {
785     clone->mode = (Accessibility_EventListenerMode *)g_malloc(sizeof(Accessibility_EventListenerMode));
786     if (clone->mode) memcpy(clone->mode, key_listener->mode, sizeof(Accessibility_EventListenerMode));
787   }
788   else
789     clone->mode = NULL;
790   return clone;
791 }
792
793 static void keylist_free(GSList *keys)
794 {
795   GSList *l;
796
797   for (l = keys; l; l = g_slist_next(l))
798   {
799     Accessibility_KeyDefinition *kd = (Accessibility_KeyDefinition *)l->data;
800     g_free(kd->keystring);
801     g_free(kd);
802   }
803   g_slist_free (keys);
804 }
805
806 static void
807 spi_key_listener_data_free (DEControllerKeyListener *key_listener)
808 {
809   keylist_free(key_listener->keys);
810   if (key_listener->mode) g_free(key_listener->mode);
811   g_free (key_listener);
812 }
813
814 static void
815 spi_key_listener_clone_free (DEControllerKeyListener *clone)
816 {
817   spi_key_listener_data_free (clone);
818 }
819
820 static void
821 spi_listener_clone_free (DEControllerListener *clone)
822 {
823   g_free (clone->path);
824   g_free (clone->bus_name);
825   g_free (clone);
826 }
827
828 static void
829 spi_dec_listener_free (DEControllerListener    *listener)
830 {
831   g_free (listener->bus_name);
832   g_free (listener->path);
833   if (listener->type == SPI_DEVICE_TYPE_KBD) 
834     spi_key_listener_data_free ((DEControllerKeyListener *) listener);
835 }
836
837 static void
838 _register_keygrab (SpiDEController      *controller,
839                    DEControllerGrabMask *grab_mask)
840 {
841   GList *l;
842
843   l = g_list_find_custom (controller->keygrabs_list, grab_mask,
844                           spi_grab_mask_compare_values);
845   if (l)
846     {
847       DEControllerGrabMask *cur_mask = l->data;
848
849       cur_mask->ref_count++;
850       if (cur_mask->pending_remove)
851         {
852           cur_mask->pending_remove = FALSE;
853         }
854     }
855   else
856     {
857       controller->keygrabs_list =
858         g_list_prepend (controller->keygrabs_list,
859                         spi_grab_mask_clone (grab_mask));
860     }
861 }
862
863 static void
864 _deregister_keygrab (SpiDEController      *controller,
865                      DEControllerGrabMask *grab_mask)
866 {
867   GList *l;
868
869   l = g_list_find_custom (controller->keygrabs_list, grab_mask,
870                           spi_grab_mask_compare_values);
871
872   if (l)
873     {
874       DEControllerGrabMask *cur_mask = l->data;
875
876       cur_mask->ref_count--;
877       if (cur_mask->ref_count <= 0)
878         {
879           cur_mask->pending_remove = TRUE;
880         }
881     }
882 }
883
884 static void
885 handle_keygrab (SpiDEController         *controller,
886                 DEControllerKeyListener *key_listener,
887                 void                   (*process_cb) (SpiDEController *controller,
888                                                       DEControllerGrabMask *grab_mask))
889 {
890   DEControllerGrabMask grab_mask = { 0 };
891
892   grab_mask.mod_mask = key_listener->mask;
893   if (g_slist_length (key_listener->keys) == 0) /* special case means AnyKey/AllKeys */
894     {
895       grab_mask.key_val = AnyKey;
896 #ifdef SPI_DEBUG
897       fprintf (stderr, "AnyKey grab!");
898 #endif
899       process_cb (controller, &grab_mask);
900     }
901   else
902     {
903       GSList *l;
904
905       for (l = key_listener->keys; l; l = g_slist_next(l))
906         {
907           Accessibility_KeyDefinition *keydef = l->data;
908           long int key_val = keydef->keysym;
909           /* X Grabs require keycodes, not keysyms */
910           if (keydef->keystring && keydef->keystring[0])
911             {
912               key_val = XStringToKeysym(keydef->keystring);                 
913             }
914           if (key_val > 0)
915             {
916               key_val = XKeysymToKeycode (spi_get_display (), (KeySym) key_val);
917             }
918           else
919             {
920               key_val = keydef->keycode;
921             }
922           grab_mask.key_val = key_val;
923           process_cb (controller, &grab_mask);
924         }
925     }
926 }
927
928 static gboolean
929 spi_controller_register_global_keygrabs (SpiDEController         *controller,
930                                          DEControllerKeyListener *key_listener)
931 {
932   handle_keygrab (controller, key_listener, _register_keygrab);
933   if (controller->xevie_display == NULL)
934     return spi_controller_update_key_grabs (controller, NULL);
935   else
936     return TRUE;
937 }
938
939 static void
940 spi_controller_deregister_global_keygrabs (SpiDEController         *controller,
941                                            DEControllerKeyListener *key_listener)
942 {
943   handle_keygrab (controller, key_listener, _deregister_keygrab);
944   if (controller->xevie_display == NULL)
945     spi_controller_update_key_grabs (controller, NULL);
946 }
947
948 static gboolean
949 spi_controller_register_device_listener (SpiDEController      *controller,
950                                          DEControllerListener *listener)
951 {
952   DEControllerKeyListener *key_listener;
953   
954   switch (listener->type) {
955   case SPI_DEVICE_TYPE_KBD:
956       key_listener = (DEControllerKeyListener *) listener;
957
958       controller->key_listeners = g_list_prepend (controller->key_listeners,
959                                                   key_listener);
960       spi_dbus_add_disconnect_match (controller->bus, key_listener->listener.bus_name);
961       if (key_listener->mode->global)
962         {
963           return spi_controller_register_global_keygrabs (controller, key_listener);    
964         }
965       else
966               return TRUE;
967       break;
968   case SPI_DEVICE_TYPE_MOUSE:
969       controller->mouse_listeners = g_list_prepend (controller->mouse_listeners, listener);
970       if (!have_mouse_listener)
971         {
972           have_mouse_listener = TRUE;
973           if (!have_mouse_event_listener)
974             g_timeout_add (100, spi_dec_poll_mouse_idle, controller->registry);
975         }
976       spi_dbus_add_disconnect_match (controller->bus, listener->bus_name);
977       break;
978   default:
979       break;
980   }
981   return FALSE;
982 }
983
984 static gboolean
985 Accessibility_DeviceEventListener_notifyEvent(SpiDEController *controller,
986                                               SpiRegistry *registry,
987                                               DEControllerListener *listener,
988                                               const Accessibility_DeviceEvent *key_event)
989 {
990   DBusMessage *message = dbus_message_new_method_call(listener->bus_name,
991                                                       listener->path,
992                                                       SPI_DBUS_INTERFACE_DEVICE_EVENT_LISTENER,
993                                                       "notifyEvent");
994   DBusError error;
995   dbus_bool_t consumed = FALSE;
996
997   dbus_error_init(&error);
998   if (spi_dbus_marshal_deviceEvent(message, key_event))
999   {
1000     // TODO: Evaluate performance: perhaps rework this whole architecture
1001     // to avoid blocking calls
1002     DBusMessage *reply = dbus_connection_send_with_reply_and_block(controller->bus, message, 1000, &error);
1003     if (reply)
1004     {
1005       DBusError error;
1006       dbus_error_init(&error);
1007       dbus_message_get_args(reply, &error, DBUS_TYPE_BOOLEAN, &consumed, DBUS_TYPE_INVALID);
1008       dbus_message_unref(reply);
1009     }
1010   }
1011   dbus_message_unref(message);
1012   return consumed;
1013 }
1014
1015 static gboolean
1016 spi_controller_notify_mouselisteners (SpiDEController                 *controller,
1017                                       const Accessibility_DeviceEvent *event)
1018 {
1019   GList   *l;
1020   GSList  *notify = NULL, *l2;
1021   GList  **listeners = &controller->mouse_listeners;
1022   gboolean is_consumed;
1023 #ifdef SPI_KEYEVENT_DEBUG
1024   gboolean found = FALSE;
1025 #endif
1026   if (!listeners)
1027     {
1028       return FALSE;
1029     }
1030
1031   for (l = *listeners; l; l = l->next)
1032     {
1033        DEControllerListener *listener = l->data;
1034
1035        if (spi_eventtype_seq_contains_event (listener->types, event))
1036          {
1037            /* we clone (don't dup) the listener, to avoid refcount inc. */
1038            notify = g_slist_prepend (notify,
1039                                      spi_listener_clone (listener));
1040 #ifdef SPI_KEYEVENT_DEBUG
1041            found = TRUE;
1042 #endif
1043          }
1044     }
1045
1046 #ifdef SPI_KEYEVENT_DEBUG
1047   if (!found)
1048     {
1049       g_print ("no match for event\n");
1050     }
1051 #endif
1052
1053   is_consumed = FALSE;
1054   for (l2 = notify; l2 && !is_consumed; l2 = l2->next)
1055     {
1056       DEControllerListener *listener = l2->data;
1057
1058       is_consumed = Accessibility_DeviceEventListener_notifyEvent (controller, controller->registry, listener, event);
1059
1060       spi_listener_clone_free ((DEControllerListener *) l2->data);
1061     }
1062
1063   for (; l2; l2 = l2->next)
1064     {
1065       DEControllerListener *listener = l2->data;
1066       spi_listener_clone_free (listener);
1067       /* clone doesn't have its own ref, so don't use spi_device_listener_free */
1068     }
1069
1070   g_slist_free (notify);
1071
1072 #ifdef SPI_DEBUG
1073   if (is_consumed) g_message ("consumed\n");
1074 #endif
1075   return is_consumed;
1076 }
1077
1078 static void
1079 spi_device_event_controller_forward_mouse_event (SpiDEController *controller,
1080                                                  XEvent *xevent)
1081 {
1082   Accessibility_DeviceEvent mouse_e;
1083   gchar event_detail[24];
1084   gboolean is_consumed = FALSE;
1085   gboolean xkb_mod_unlatch_occurred;
1086   XButtonEvent *xbutton_event = (XButtonEvent *) xevent;
1087   dbus_uint32_t ix, iy;
1088
1089   int button = xbutton_event->button;
1090   
1091   unsigned int mouse_button_state = xbutton_event->state;
1092
1093   switch (button)
1094     {
1095     case 1:
1096             mouse_button_state |= Button1Mask;
1097             break;
1098     case 2:
1099             mouse_button_state |= Button2Mask;
1100             break;
1101     case 3:
1102             mouse_button_state |= Button3Mask;
1103             break;
1104     case 4:
1105             mouse_button_state |= Button4Mask;
1106             break;
1107     case 5:
1108             mouse_button_state |= Button5Mask;
1109             break;
1110     }
1111
1112   last_mouse_pos->x = ((XButtonEvent *) xevent)->x_root;
1113   last_mouse_pos->y = ((XButtonEvent *) xevent)->y_root;
1114
1115 #ifdef SPI_DEBUG  
1116   fprintf (stderr, "mouse button %d %s (%x)\n",
1117            xbutton_event->button, 
1118            (xevent->type == ButtonPress) ? "Press" : "Release",
1119            mouse_button_state);
1120 #endif
1121   snprintf (event_detail, 22, "%d%c", button,
1122             (xevent->type == ButtonPress) ? 'p' : 'r');
1123
1124   /* TODO: FIXME distinguish between physical and logical buttons */
1125   mouse_e.type      = (xevent->type == ButtonPress) ? 
1126                       Accessibility_BUTTON_PRESSED_EVENT :
1127                       Accessibility_BUTTON_RELEASED_EVENT;
1128   mouse_e.id        = button;
1129   mouse_e.hw_code   = button;
1130   mouse_e.modifiers = (dbus_uint16_t) xbutton_event->state;
1131   mouse_e.timestamp = (dbus_uint32_t) xbutton_event->time;
1132   mouse_e.event_string = "";
1133   mouse_e.is_text   = FALSE;
1134   if ((mouse_button_state & mouse_button_mask) != 
1135        (mouse_mask_state & mouse_button_mask))
1136     { 
1137       if ((mouse_mask_state & key_modifier_mask) !=
1138           (mouse_button_state & key_modifier_mask))
1139         spi_dec_emit_modifier_event (controller, 
1140                                      mouse_mask_state, mouse_button_state);
1141       mouse_mask_state = mouse_button_state;
1142       is_consumed = 
1143         spi_controller_notify_mouselisteners (controller, &mouse_e);
1144       ix = last_mouse_pos->x;
1145       iy = last_mouse_pos->y;
1146       /* TODO - Work out which part of the spec this emit is fulfilling */
1147       //emit(controller, SPI_DBUS_INTERFACE_EVENT_MOUSE, "button", event_detail, ix, iy);
1148     }
1149
1150   xkb_mod_unlatch_occurred = (xevent->type == ButtonPress ||
1151                               xevent->type == ButtonRelease);
1152   
1153   /* if client wants to consume this event, and XKB latch state was
1154    *   unset by this button event, we reset it
1155    */
1156   if (is_consumed && xkb_mod_unlatch_occurred)
1157     spi_dec_set_unlatch_pending (controller, mouse_mask_state);
1158   
1159   XAllowEvents (spi_get_display (),
1160                 (is_consumed) ? SyncPointer : ReplayPointer,
1161                 CurrentTime);
1162 }
1163
1164 static GdkFilterReturn
1165 global_filter_fn (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
1166 {
1167   XEvent *xevent = gdk_xevent;
1168   SpiDEController *controller;
1169   DEControllerPrivateData *priv;
1170   Display *display = spi_get_display ();
1171   controller = SPI_DEVICE_EVENT_CONTROLLER (data);
1172   priv = (DEControllerPrivateData *)
1173           g_object_get_qdata (G_OBJECT (controller), spi_dec_private_quark);  
1174
1175   if (xevent->type == MappingNotify)
1176     xmkeymap = NULL;
1177
1178   if (xevent->type == KeyPress || xevent->type == KeyRelease)
1179     {
1180       if (controller->xevie_display == NULL)
1181         {
1182           gboolean is_consumed;
1183
1184           is_consumed =
1185             spi_device_event_controller_forward_key_event (controller, xevent);
1186
1187           if (is_consumed)
1188             {
1189               int n_events;
1190               int i;
1191               XEvent next_event;
1192               n_events = XPending (display);
1193
1194 #ifdef SPI_KEYEVENT_DEBUG
1195               g_print ("Number of events pending: %d\n", n_events);
1196 #endif
1197               for (i = 0; i < n_events; i++)
1198                 {
1199                   XNextEvent (display, &next_event);
1200                   if (next_event.type != KeyPress &&
1201                       next_event.type != KeyRelease)
1202                         g_warning ("Unexpected event type %d in queue", next_event.type);
1203                  }
1204
1205               XAllowEvents (display, AsyncKeyboard, CurrentTime);
1206               if (n_events)
1207                 XUngrabKeyboard (display, CurrentTime);
1208             }
1209           else
1210             {
1211               if (xevent->type == KeyPress)
1212                 wait_for_release_event (xevent, controller);
1213               XAllowEvents (display, ReplayKeyboard, CurrentTime);
1214             }
1215         }
1216
1217       return GDK_FILTER_CONTINUE;
1218     }
1219   if (xevent->type == ButtonPress || xevent->type == ButtonRelease)
1220     {
1221       spi_device_event_controller_forward_mouse_event (controller, xevent);
1222     }
1223   if (xevent->type == priv->xkb_base_event_code)
1224     {
1225       XkbAnyEvent * xkb_ev = (XkbAnyEvent *) xevent;
1226       /* ugly but probably necessary...*/
1227       XSynchronize (display, TRUE);
1228
1229       if (xkb_ev->xkb_type == XkbStateNotify)
1230         {
1231           XkbStateNotifyEvent *xkb_snev =
1232                   (XkbStateNotifyEvent *) xkb_ev;
1233           /* check the mouse, to catch mouse events grabbed by
1234            * another client; in case we should revert this XKB delatch 
1235            */
1236           if (!priv->pending_xkb_mod_relatch_mask)
1237             {
1238               int x, y;
1239               gboolean moved;
1240               spi_dec_mouse_check (controller, &x, &y, &moved);
1241             }
1242           /* we check again, since the previous call may have 
1243              changed this flag */
1244           if (priv->pending_xkb_mod_relatch_mask)
1245             {
1246               unsigned int feedback_mask;
1247 #ifdef SPI_XKB_DEBUG
1248               fprintf (stderr, "relatching %x\n",
1249                        priv->pending_xkb_mod_relatch_mask);
1250 #endif
1251               /* temporarily turn off the latch bell, if it's on */
1252               XkbGetControls (display,
1253                               XkbAccessXFeedbackMask,
1254                               priv->xkb_desc);
1255               feedback_mask = priv->xkb_desc->ctrls->ax_options;
1256               if (feedback_mask & XkbAX_StickyKeysFBMask)
1257               {
1258                 XkbControlsChangesRec changes = {XkbAccessXFeedbackMask,
1259                                                  0, False};      
1260                 priv->xkb_desc->ctrls->ax_options
1261                               &= ~(XkbAX_StickyKeysFBMask);
1262                 XkbChangeControls (display, priv->xkb_desc, &changes);
1263               }
1264               /* TODO: account for lock as well as latch */
1265               XkbLatchModifiers (display,
1266                                  XkbUseCoreKbd,
1267                                  priv->pending_xkb_mod_relatch_mask,
1268                                  priv->pending_xkb_mod_relatch_mask);
1269               if (feedback_mask & XkbAX_StickyKeysFBMask)
1270               { 
1271                 XkbControlsChangesRec changes = {XkbAccessXFeedbackMask,
1272                                                  0, False};      
1273                 priv->xkb_desc->ctrls->ax_options = feedback_mask;
1274                 XkbChangeControls (display, priv->xkb_desc, &changes);
1275               }
1276 #ifdef SPI_XKB_DEBUG
1277               fprintf (stderr, "relatched %x\n",
1278                        priv->pending_xkb_mod_relatch_mask);
1279 #endif
1280               priv->pending_xkb_mod_relatch_mask = 0;
1281             }
1282           else
1283             {
1284               priv->xkb_latch_mask = xkb_snev->latched_mods;
1285             }
1286         }
1287       XSynchronize (display, FALSE);
1288     }
1289   
1290   return GDK_FILTER_CONTINUE;
1291 }
1292
1293 static int
1294 _spi_controller_device_error_handler (Display *display, XErrorEvent *error)
1295 {
1296   if (error->error_code == BadAccess) 
1297     {  
1298       g_message ("Could not complete key grab: grab already in use.\n");
1299       spi_error_code = BadAccess;
1300       return 0;
1301     }
1302   else 
1303     {
1304       return (*x_default_error_handler) (display, error);
1305     }
1306 }
1307
1308 static void
1309 spi_controller_register_with_devices (SpiDEController *controller)
1310 {
1311   DEControllerPrivateData *priv;
1312   int event_base, error_base, major_version, minor_version;
1313
1314   priv = (DEControllerPrivateData *) g_object_get_qdata (G_OBJECT (controller), spi_dec_private_quark);
1315   if (XTestQueryExtension (spi_get_display(), &event_base, &error_base, &major_version, &minor_version))
1316     {
1317       XTestGrabControl (spi_get_display (), True);
1318     }
1319
1320   /* calls to device-specific implementations and routines go here */
1321   /* register with: keyboard hardware code handler */
1322   /* register with: (translated) keystroke handler */
1323
1324   priv->have_xkb = XkbQueryExtension (spi_get_display (),
1325                                       &priv->xkb_major_extension_opcode,
1326                                       &priv->xkb_base_event_code,
1327                                       &priv->xkb_base_error_code, NULL, NULL);
1328   if (priv->have_xkb)
1329     {
1330       gint i;
1331       guint64 reserved = 0;
1332       priv->xkb_desc = XkbGetMap (spi_get_display (), XkbKeySymsMask, XkbUseCoreKbd);
1333       XkbSelectEvents (spi_get_display (),
1334                        XkbUseCoreKbd,
1335                        XkbStateNotifyMask, XkbStateNotifyMask);     
1336       _numlock_physical_mask = XkbKeysymToModifiers (spi_get_display (), 
1337                                                      XK_Num_Lock);
1338       for (i = priv->xkb_desc->max_key_code; i >= priv->xkb_desc->min_key_code; --i)
1339       {
1340           if (priv->xkb_desc->map->key_sym_map[i].kt_index[0] == XkbOneLevelIndex)
1341           { 
1342               if (XKeycodeToKeysym (spi_get_display (), i, 0) != 0)
1343               {
1344                   /* don't use this one if there's a grab client! */
1345                   gdk_error_trap_push ();
1346                   XGrabKey (spi_get_display (), i, 0, 
1347                             gdk_x11_get_default_root_xwindow (),
1348                             TRUE,
1349                             GrabModeSync, GrabModeSync);
1350                   XSync (spi_get_display (), TRUE);
1351                   XUngrabKey (spi_get_display (), i, 0, 
1352                               gdk_x11_get_default_root_xwindow ());
1353                   if (!gdk_error_trap_pop ())
1354                   {
1355                       reserved = i;
1356                       break;
1357                   }
1358               }
1359           }
1360       }
1361       if (reserved) 
1362       {
1363           priv->reserved_keycode = reserved;
1364           priv->reserved_keysym = XKeycodeToKeysym (spi_get_display (), reserved, 0);
1365       }
1366       else
1367       { 
1368           priv->reserved_keycode = XKeysymToKeycode (spi_get_display (), XK_numbersign);
1369           priv->reserved_keysym = XK_numbersign;
1370       }
1371 #ifdef SPI_RESERVED_DEBUG
1372       unsigned sym = 0;
1373       sym = XKeycodeToKeysym (spi_get_display (), reserved, 0);
1374       fprintf (stderr, "%x\n", sym);
1375       fprintf (stderr, "setting the reserved keycode to %d (%s)\n", 
1376                reserved, 
1377                XKeysymToString (XKeycodeToKeysym (spi_get_display (),
1378                                                             reserved, 0)));
1379 #endif
1380     }   
1381
1382   gdk_window_add_filter (NULL, global_filter_fn, controller);
1383
1384   gdk_window_set_events (gdk_get_default_root_window (),
1385                          GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
1386
1387   x_default_error_handler = XSetErrorHandler (_spi_controller_device_error_handler);
1388 }
1389
1390 static gboolean
1391 spi_key_set_contains_key (GSList                          *key_set,
1392                           const Accessibility_DeviceEvent *key_event)
1393 {
1394   gint i;
1395   gint len;
1396   GSList *l;
1397
1398   if (!key_set)
1399     {
1400 #ifdef SPI_DEBUG
1401       g_print ("null key set!\n");
1402 #endif
1403       return TRUE;
1404     }
1405
1406   len = g_slist_length (key_set);
1407   
1408   if (len == 0) /* special case, means "all keys/any key" */
1409     {
1410 #ifdef SPI_DEBUG
1411       g_print ("anykey\n");         
1412 #endif
1413       return TRUE;
1414     }
1415
1416   for (l = key_set,i = 0; l; l = g_slist_next(l),i++)
1417     {
1418       Accessibility_KeyDefinition *kd = l->data;
1419 #ifdef SPI_KEYEVENT_DEBUG           
1420       g_print ("key_set[%d] event = %d, code = %d; key_event %d, code %d, string %s\n",
1421                 i,
1422                 (int) kd->keysym,
1423                 (int) kd->keycode,
1424                 (int) key_event->id,
1425                 (int) key_event->hw_code,
1426                 key_event->event_string); 
1427 #endif
1428       if (kd->keysym == (dbus_uint32_t) key_event->id)
1429         {
1430           return TRUE;
1431         }
1432       if (kd->keycode == (dbus_uint32_t) key_event->hw_code)
1433         {
1434           return TRUE;
1435         }
1436       if (key_event->event_string && key_event->event_string[0] &&
1437           !strcmp (kd->keystring, key_event->event_string))
1438         {
1439           return TRUE;
1440         }
1441     }
1442
1443   return FALSE;
1444 }
1445
1446 static gboolean
1447 spi_eventtype_seq_contains_event (dbus_uint32_t types,
1448                                   const Accessibility_DeviceEvent *event)
1449 {
1450   if (types == 0) /* special case, means "all events/any event" */
1451     {
1452       return TRUE;
1453     }
1454
1455   return (types & (1 << event->type));
1456 }
1457
1458 static gboolean
1459 spi_key_event_matches_listener (const Accessibility_DeviceEvent *key_event,
1460                                 DEControllerKeyListener         *listener,
1461                                 dbus_bool_t                    is_system_global)
1462 {
1463   if (((key_event->modifiers & 0xFF) == (dbus_uint16_t) (listener->mask & 0xFF)) &&
1464        spi_key_set_contains_key (listener->keys, key_event) &&
1465        spi_eventtype_seq_contains_event (listener->listener.types, key_event) && 
1466       (is_system_global == listener->mode->global))
1467     {
1468       return TRUE;
1469     }
1470   else
1471     {
1472       return FALSE;
1473     }
1474 }
1475
1476 static gboolean
1477 spi_controller_notify_keylisteners (SpiDEController                 *controller,
1478                                     Accessibility_DeviceEvent       *key_event,
1479                                     dbus_bool_t                    is_system_global)
1480 {
1481   GList   *l;
1482   GSList  *notify = NULL, *l2;
1483   GList  **key_listeners = &controller->key_listeners;
1484   gboolean is_consumed;
1485
1486   if (!key_listeners)
1487     {
1488       return FALSE;
1489     }
1490
1491   /* set the NUMLOCK event mask bit if appropriate: see bug #143702 */
1492   if (key_event->modifiers & _numlock_physical_mask)
1493       key_event->modifiers |= SPI_KEYMASK_NUMLOCK;
1494
1495   for (l = *key_listeners; l; l = l->next)
1496     {
1497        DEControllerKeyListener *key_listener = l->data;
1498
1499        if (spi_key_event_matches_listener (key_event, key_listener, is_system_global))
1500          {
1501            /* we clone (don't dup) the listener, to avoid refcount inc. */
1502            notify = g_slist_prepend (notify,
1503                                      spi_key_listener_clone (key_listener));
1504          }
1505     }
1506
1507 #ifdef SPI_KEYEVENT_DEBUG
1508   if (!notify)
1509     {
1510       g_print ("no match for event\n");
1511     }
1512 #endif
1513
1514   is_consumed = FALSE;
1515   for (l2 = notify; l2 && !is_consumed; l2 = l2->next)
1516     {
1517       DEControllerKeyListener *key_listener = l2->data;     
1518
1519       is_consumed = Accessibility_DeviceEventListener_notifyEvent (controller, controller->registry, &key_listener->listener, key_event) &&
1520                     key_listener->mode->preemptive;
1521
1522       spi_key_listener_clone_free (key_listener);
1523     }
1524
1525   for (; l2; l2 = l2->next)
1526     {
1527       DEControllerKeyListener *key_listener = l2->data;     
1528       spi_key_listener_clone_free (key_listener);
1529       /* clone doesn't have its own ref, so don't use spi_dec_listener_free */
1530     }
1531
1532   g_slist_free (notify);
1533
1534 #ifdef SPI_DEBUG
1535   if (is_consumed) g_message ("consumed\n");
1536 #endif
1537   return is_consumed;
1538 }
1539
1540 static gboolean
1541 spi_clear_error_state (void)
1542 {
1543         gboolean retval = spi_error_code != 0;
1544         spi_error_code = 0;
1545         return retval;
1546 }
1547
1548 static Accessibility_DeviceEvent
1549 spi_keystroke_from_x_key_event (XKeyEvent *x_key_event)
1550 {
1551   Accessibility_DeviceEvent key_event;
1552   KeySym keysym;
1553   const int cbuf_bytes = 20;
1554   char cbuf [21];
1555   int nbytes;
1556
1557   nbytes = XLookupString (x_key_event, cbuf, cbuf_bytes, &keysym, NULL);  
1558   key_event.id = (dbus_int32_t)(keysym);
1559   key_event.hw_code = (dbus_int16_t) x_key_event->keycode;
1560   if (((XEvent *) x_key_event)->type == KeyPress)
1561     {
1562       key_event.type = Accessibility_KEY_PRESSED_EVENT;
1563     }
1564   else
1565     {
1566       key_event.type = Accessibility_KEY_RELEASED_EVENT;
1567     } 
1568   key_event.modifiers = (dbus_uint16_t)(x_key_event->state);
1569   key_event.is_text = FALSE;
1570   switch (keysym)
1571     {
1572       case ' ':
1573         key_event.event_string = g_strdup ("space");
1574         break;
1575       case XK_Tab:
1576         key_event.event_string = g_strdup ("Tab");
1577         break;
1578       case XK_BackSpace:
1579         key_event.event_string = g_strdup ("Backspace");
1580         break;
1581       case XK_Return:
1582         key_event.event_string = g_strdup ("Return");
1583         break;
1584       case XK_Home:
1585         key_event.event_string = g_strdup ("Home");
1586         break;
1587       case XK_Page_Down:
1588         key_event.event_string = g_strdup ("Page_Down");
1589         break;
1590       case XK_Page_Up:
1591         key_event.event_string = g_strdup ("Page_Up");
1592         break;
1593       case XK_F1:
1594         key_event.event_string = g_strdup ("F1");
1595         break;
1596       case XK_F2:
1597         key_event.event_string = g_strdup ("F2");
1598         break;
1599       case XK_F3:
1600         key_event.event_string = g_strdup ("F3");
1601         break;
1602       case XK_F4:
1603         key_event.event_string = g_strdup ("F4");
1604         break;
1605       case XK_F5:
1606         key_event.event_string = g_strdup ("F5");
1607         break;
1608       case XK_F6:
1609         key_event.event_string = g_strdup ("F6");
1610         break;
1611       case XK_F7:
1612         key_event.event_string = g_strdup ("F7");
1613         break;
1614       case XK_F8:
1615         key_event.event_string = g_strdup ("F8");
1616         break;
1617       case XK_F9:
1618         key_event.event_string = g_strdup ("F9");
1619         break;
1620       case XK_F10:
1621         key_event.event_string = g_strdup ("F10");
1622         break;
1623       case XK_F11:
1624         key_event.event_string = g_strdup ("F11");
1625         break;
1626       case XK_F12:
1627         key_event.event_string = g_strdup ("F12");
1628         break;
1629       case XK_End:
1630         key_event.event_string = g_strdup ("End");
1631         break;
1632       case XK_Escape:
1633         key_event.event_string = g_strdup ("Escape");
1634         break;
1635       case XK_Up:
1636         key_event.event_string = g_strdup ("Up");
1637         break;
1638       case XK_Down:
1639         key_event.event_string = g_strdup ("Down");
1640         break;
1641       case XK_Left:
1642         key_event.event_string = g_strdup ("Left");
1643         break;
1644       case XK_Right:
1645         key_event.event_string = g_strdup ("Right");
1646         break;
1647       default:
1648         if (nbytes > 0)
1649           {
1650             gunichar c;
1651             cbuf[nbytes] = '\0'; /* OK since length is cbuf_bytes+1 */
1652             key_event.event_string = g_strdup (cbuf);
1653             c = keysym2ucs (keysym);
1654             if (c > 0 && !g_unichar_iscntrl (c))
1655               {
1656                 key_event.is_text = TRUE; 
1657                 /* incorrect for some composed chars? */
1658               }
1659           }
1660         else
1661           {
1662             key_event.event_string = g_strdup ("");
1663           }
1664     }
1665
1666   key_event.timestamp = (dbus_uint32_t) x_key_event->time;
1667 #ifdef SPI_KEYEVENT_DEBUG
1668   {
1669     char *pressed_str  = "pressed";
1670     char *released_str = "released";
1671     char *state_ptr;
1672
1673     if (key_event.type == Accessibility_KEY_PRESSED_EVENT)
1674       state_ptr = pressed_str;
1675     else
1676       state_ptr = released_str;
1677  
1678     fprintf (stderr,
1679              "Key %lu %s (%c), modifiers %d; string=%s [%x] %s\n",
1680              (unsigned long) keysym,
1681              state_ptr,
1682              keysym ? (int) keysym : '*',
1683              (int) x_key_event->state,
1684              key_event.event_string,
1685              key_event.event_string[0],
1686              (key_event.is_text == TRUE) ? "(text)" : "(not text)");
1687   }
1688 #endif
1689 #ifdef SPI_DEBUG
1690   fprintf (stderr, "%s%c\n",
1691      (x_key_event->state & Mod1Mask)?"Alt-":"",
1692      ((x_key_event->state & ShiftMask)^(x_key_event->state & LockMask))?
1693      g_ascii_toupper (keysym) : g_ascii_tolower (keysym));
1694   fprintf (stderr, "serial: %x Time: %x\n", x_key_event->serial, x_key_event->time);
1695 #endif /* SPI_DEBUG */
1696   return key_event;     
1697 }
1698
1699 static gboolean
1700 spi_controller_update_key_grabs (SpiDEController           *controller,
1701                                  Accessibility_DeviceEvent *recv)
1702 {
1703   GList *l, *next;
1704   gboolean   update_failed = FALSE;
1705   KeyCode keycode = 0;
1706   
1707   g_return_val_if_fail (controller != NULL, FALSE);
1708
1709   /*
1710    * masks known to work with default RH 7.1+:
1711    * 0 (no mods), LockMask, Mod1Mask, Mod2Mask, ShiftMask,
1712    * ShiftMask|LockMask, Mod1Mask|LockMask, Mod2Mask|LockMask,
1713    * ShiftMask|Mod1Mask, ShiftMask|Mod2Mask, Mod1Mask|Mod2Mask,
1714    * ShiftMask|LockMask|Mod1Mask, ShiftMask|LockMask|Mod2Mask,
1715    *
1716    * ControlMask grabs are broken, must be in use already
1717    */
1718   if (recv)
1719     keycode = keycode_for_keysym (controller, recv->id, NULL);
1720   for (l = controller->keygrabs_list; l; l = next)
1721     {
1722       gboolean do_remove;
1723       gboolean re_issue_grab;
1724       DEControllerGrabMask *grab_mask = l->data;
1725
1726       next = l->next;
1727
1728       re_issue_grab = recv &&
1729               (recv->modifiers & grab_mask->mod_mask) &&
1730               (grab_mask->key_val == keycode);
1731
1732 #ifdef SPI_DEBUG
1733       fprintf (stderr, "mask=%lx %lx (%c%c) %s\n",
1734                (long int) grab_mask->key_val,
1735                (long int) grab_mask->mod_mask,
1736                grab_mask->pending_add ? '+' : '.',
1737                grab_mask->pending_remove ? '-' : '.',
1738                re_issue_grab ? "re-issue": "");
1739 #endif
1740
1741       do_remove = FALSE;
1742
1743       if (grab_mask->pending_add && grab_mask->pending_remove)
1744         {
1745           do_remove = TRUE;
1746         }
1747       else if (grab_mask->pending_remove)
1748         {
1749 #ifdef SPI_DEBUG
1750       fprintf (stderr, "ungrabbing, mask=%x\n", grab_mask->mod_mask);
1751 #endif
1752           XUngrabKey (spi_get_display (),
1753                       grab_mask->key_val,
1754                       grab_mask->mod_mask,
1755                       gdk_x11_get_default_root_xwindow ());
1756
1757           do_remove = TRUE;
1758         }
1759       else if (grab_mask->pending_add || re_issue_grab)
1760         {
1761
1762 #ifdef SPI_DEBUG
1763           fprintf (stderr, "grab %d with mask %x\n", grab_mask->key_val, grab_mask->mod_mask);
1764 #endif
1765           XGrabKey (spi_get_display (),
1766                     grab_mask->key_val,
1767                     grab_mask->mod_mask,
1768                     gdk_x11_get_default_root_xwindow (),
1769                     True,
1770                     GrabModeSync,
1771                     GrabModeSync);
1772           XSync (spi_get_display (), False);
1773           update_failed = spi_clear_error_state ();
1774           if (update_failed) {
1775                   while (grab_mask->ref_count > 0) --grab_mask->ref_count;
1776                   do_remove = TRUE;
1777           }
1778         }
1779
1780       grab_mask->pending_add = FALSE;
1781       grab_mask->pending_remove = FALSE;
1782
1783       if (do_remove)
1784         {
1785           g_assert (grab_mask->ref_count <= 0);
1786
1787           controller->keygrabs_list = g_list_delete_link (
1788             controller->keygrabs_list, l);
1789
1790           spi_grab_mask_free (grab_mask);
1791         }
1792
1793     } 
1794
1795   return ! update_failed;
1796 }
1797
1798 /*
1799  * Implemented GObject::finalize
1800  */
1801 static void
1802 spi_device_event_controller_object_finalize (GObject *object)
1803 {
1804   SpiDEController *controller;
1805   DEControllerPrivateData *private;
1806   controller = SPI_DEVICE_EVENT_CONTROLLER (object);
1807   GObjectClass *parent_class = G_OBJECT_CLASS(spi_device_event_controller_parent_class);
1808 #ifdef SPI_DEBUG
1809   fprintf(stderr, "spi_device_event_controller_object_finalize called\n");
1810 #endif
1811   /* disconnect any special listeners, get rid of outstanding keygrabs */
1812   XUngrabKey (spi_get_display (), AnyKey, AnyModifier, DefaultRootWindow (spi_get_display ()));
1813
1814 #ifdef HAVE_XEVIE
1815   if (controller->xevie_display != NULL)
1816     {
1817       XevieEnd(controller->xevie_display);
1818 #ifdef SPI_KEYEVENT_DEBUG
1819       printf("XevieEnd(dpy) finished \n");
1820 #endif
1821     }
1822 #endif
1823
1824   private = g_object_get_data (G_OBJECT (controller), "spi-dec-private");
1825   if (private->xkb_desc)
1826           XkbFreeKeyboard (private->xkb_desc, 0, True);
1827   g_free (private);
1828   parent_class->finalize (object);
1829 }
1830
1831 /*
1832  * DBus Accessibility::DEController::registerKeystrokeListener
1833  *     method implementation
1834  */
1835 static DBusMessage *
1836 impl_register_keystroke_listener (DBusConnection *bus,
1837                                   DBusMessage *message,
1838                                   void *user_data)
1839 {
1840   SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER(user_data);
1841   DEControllerKeyListener *dec_listener;
1842   DBusMessageIter iter, iter_array;
1843   const char *path;
1844   GSList *keys = NULL;
1845   dbus_int32_t mask, type;
1846   Accessibility_EventListenerMode *mode;
1847   dbus_bool_t ret;
1848   DBusMessage *reply = NULL;
1849   char *keystring;
1850
1851   dbus_message_iter_init(message, &iter);
1852   // TODO: verify type signature
1853   dbus_message_iter_get_basic(&iter, &path);
1854   dbus_message_iter_next(&iter);
1855   dbus_message_iter_recurse(&iter, &iter_array);
1856   while (dbus_message_iter_get_arg_type(&iter_array) != DBUS_TYPE_INVALID)
1857   {
1858     Accessibility_KeyDefinition *kd = (Accessibility_KeyDefinition *)g_malloc(sizeof(Accessibility_KeyDefinition));
1859     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))
1860     {
1861       break;
1862     }
1863     kd->keystring = g_strdup (keystring);
1864     keys = g_slist_append(keys, kd);
1865   }
1866   dbus_message_iter_next(&iter);
1867   dbus_message_iter_get_basic(&iter, &mask);
1868   dbus_message_iter_next(&iter);
1869   if (!strcmp (dbus_message_iter_get_signature (&iter), "u"))
1870     dbus_message_iter_get_basic(&iter, &type);
1871   else
1872   {
1873     dbus_message_iter_recurse(&iter, &iter_array);
1874     while (dbus_message_iter_get_arg_type(&iter_array) != DBUS_TYPE_INVALID)
1875     {
1876       dbus_uint32_t t;
1877       dbus_message_iter_get_basic (&iter_array, &t);
1878       type |= (1 << t);
1879       dbus_message_iter_next (&iter_array);
1880     }
1881     dbus_message_iter_next (&iter_array);
1882   }
1883   dbus_message_iter_next(&iter);
1884   mode = (Accessibility_EventListenerMode *)g_malloc(sizeof(Accessibility_EventListenerMode));
1885   if (mode)
1886   {
1887     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);
1888   }
1889 #ifdef SPI_DEBUG
1890   fprintf (stderr, "registering keystroke listener %s:%s with maskVal %lu\n",
1891            dbus_message_get_sender(message), path, (unsigned long) mask);
1892 #endif
1893   dec_listener = spi_dec_key_listener_new (dbus_message_get_sender(message), path, keys, mask, type, mode);
1894   ret = spi_controller_register_device_listener (
1895           controller, (DEControllerListener *) dec_listener);
1896   reply = dbus_message_new_method_return (message);
1897   if (reply)
1898   {
1899     dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret, DBUS_TYPE_INVALID);
1900   }
1901   return reply;
1902 }
1903
1904 /*
1905  * DBus Accessibility::DEController::registerDeviceEventListener
1906  *     method implementation
1907  */
1908 static DBusMessage *
1909 impl_register_device_event_listener (DBusConnection *bus,
1910                                   DBusMessage *message,
1911                                   void *user_data)
1912 {
1913   SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER(user_data);
1914   DEControllerListener *dec_listener;
1915   DBusError error;
1916   const char *path;
1917   dbus_int32_t event_types;
1918   dbus_bool_t ret;
1919   DBusMessage *reply = NULL;
1920
1921   dbus_error_init(&error);
1922   if (!dbus_message_get_args(message, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_UINT32, &event_types, DBUS_TYPE_INVALID))
1923   {
1924     return droute_invalid_arguments_error (message);
1925   }
1926   dec_listener = spi_dec_listener_new (dbus_message_get_sender(message), path, event_types);
1927   ret =  spi_controller_register_device_listener (
1928           controller, (DEControllerListener *) dec_listener);
1929   reply = dbus_message_new_method_return (message);
1930   if (reply)
1931   {
1932     dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret, DBUS_TYPE_INVALID);
1933   }
1934   return reply;
1935 }
1936
1937 typedef struct {
1938         DBusConnection *bus;
1939         DEControllerListener    *listener;
1940 } RemoveListenerClosure;
1941
1942 static SpiReEntrantContinue
1943 remove_listener_cb (GList * const *list,
1944                     gpointer       user_data)
1945 {
1946   DEControllerListener  *listener = (*list)->data;
1947   RemoveListenerClosure *ctx = user_data;
1948
1949   if (!strcmp(ctx->listener->bus_name, listener->bus_name) &&
1950       !strcmp(ctx->listener->path, listener->path))
1951     {
1952       spi_re_entrant_list_delete_link (list);
1953       spi_dbus_remove_disconnect_match (ctx->bus, listener->bus_name);
1954       spi_dec_listener_free (listener);
1955     }
1956
1957   return SPI_RE_ENTRANT_CONTINUE;
1958 }
1959
1960 static SpiReEntrantContinue
1961 copy_key_listener_cb (GList * const *list,
1962                       gpointer       user_data)
1963 {
1964   DEControllerKeyListener  *key_listener = (*list)->data;
1965   RemoveListenerClosure    *ctx = user_data;
1966
1967   if (!strcmp(ctx->listener->bus_name, key_listener->listener.bus_name) &&
1968       !strcmp(ctx->listener->path, key_listener->listener.path))
1969     {
1970       /* TODO: FIXME aggregate keys in case the listener is registered twice */
1971       DEControllerKeyListener *ctx_key_listener = 
1972         (DEControllerKeyListener *) ctx->listener; 
1973       keylist_free (ctx_key_listener->keys);        
1974       ctx_key_listener->keys = keylist_clone(key_listener->keys);
1975     }
1976
1977   return SPI_RE_ENTRANT_CONTINUE;
1978 }
1979
1980 static void
1981 spi_controller_deregister_device_listener (SpiDEController            *controller,
1982                                            DEControllerListener *listener)
1983 {
1984   RemoveListenerClosure  ctx;
1985
1986   ctx.bus = controller->bus;
1987   ctx.listener = listener;
1988
1989   spi_re_entrant_list_foreach (&controller->mouse_listeners,
1990                                remove_listener_cb, &ctx);
1991   if (!controller->mouse_listeners)
1992     have_mouse_listener = FALSE;
1993 }
1994
1995 static void
1996 spi_deregister_controller_key_listener (SpiDEController            *controller,
1997                                         DEControllerKeyListener    *key_listener)
1998 {
1999   RemoveListenerClosure  ctx;
2000
2001   ctx.bus = controller->bus;
2002   ctx.listener = (DEControllerListener *) key_listener;
2003
2004   /* special case, copy keyset from existing controller list entry */
2005   if (g_slist_length(key_listener->keys) == 0)
2006     {
2007       spi_re_entrant_list_foreach (&controller->key_listeners,
2008                                   copy_key_listener_cb, &ctx);
2009     }
2010
2011   spi_controller_deregister_global_keygrabs (controller, key_listener);
2012
2013   spi_re_entrant_list_foreach (&controller->key_listeners,
2014                                 remove_listener_cb, &ctx);
2015
2016 }
2017
2018 void
2019 spi_remove_device_listeners (SpiDEController *controller, const char *bus_name)
2020 {
2021   GList *l, *tmp;
2022
2023   for (l = controller->mouse_listeners; l; l = tmp)
2024   {
2025     DEControllerListener *listener = l->data;
2026     tmp = l->next;
2027     if (!strcmp (listener->bus_name, bus_name))
2028     {
2029       spi_controller_deregister_device_listener (controller, listener);
2030     }
2031   }
2032   for (l = controller->key_listeners; l; l = tmp)
2033   {
2034     DEControllerKeyListener *key_listener = l->data;
2035     tmp = l->next;
2036     if (!strcmp (key_listener->listener.bus_name, bus_name))
2037     {
2038       spi_deregister_controller_key_listener (controller, key_listener);
2039     }
2040   }
2041 }
2042
2043 /*
2044  * DBus Accessibility::DEController::deregisterKeystrokeListener
2045  *     method implementation
2046  */
2047 static DBusMessage *
2048 impl_deregister_keystroke_listener (DBusConnection *bus,
2049                                   DBusMessage *message,
2050                                   void *user_data)
2051 {
2052   SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER(user_data);
2053   DEControllerKeyListener *key_listener;
2054   DBusMessageIter iter, iter_array;
2055   const char *path;
2056   GSList *keys = NULL;
2057   dbus_int32_t mask, type;
2058   DBusMessage *reply = NULL;
2059
2060   dbus_message_iter_init(message, &iter);
2061   // TODO: verify type signature
2062   dbus_message_iter_get_basic(&iter, &path);
2063   dbus_message_iter_next(&iter);
2064   dbus_message_iter_recurse(&iter, &iter_array);
2065   while (dbus_message_iter_get_arg_type(&iter_array) != DBUS_TYPE_INVALID)
2066   {
2067     Accessibility_KeyDefinition *kd = (Accessibility_KeyDefinition *)g_malloc(sizeof(Accessibility_KeyDefinition));
2068   char *keystring;
2069
2070     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))
2071     {
2072       break;
2073     }
2074     kd->keystring = g_strdup (keystring);
2075     keys = g_slist_append(keys, kd);
2076   }
2077   dbus_message_iter_next(&iter);
2078   dbus_message_iter_get_basic(&iter, &mask);
2079   dbus_message_iter_next(&iter);
2080   dbus_message_iter_get_basic(&iter, &type);
2081   dbus_message_iter_next(&iter);
2082   key_listener = spi_dec_key_listener_new (dbus_message_get_sender(message), path, keys, mask, type, NULL);
2083 #ifdef SPI_DEREGISTER_DEBUG
2084   fprintf (stderr, "deregistering keystroke listener %p with maskVal %lu\n",
2085            (void *) l, (unsigned long) mask->value);
2086 #endif
2087
2088   spi_deregister_controller_key_listener (controller, key_listener);
2089
2090   spi_dec_listener_free ((DEControllerListener *) key_listener);
2091   reply = dbus_message_new_method_return (message);
2092   return reply;
2093 }
2094
2095 /*
2096  * DBus Accessibility::DEController::deregisterDeviceEventListener
2097  *     method implementation
2098  */
2099 static DBusMessage *
2100 impl_deregister_device_event_listener (DBusConnection *bus,
2101                                   DBusMessage *message,
2102                                   void *user_data)
2103 {
2104   SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER(user_data);
2105   DEControllerListener *listener;
2106   DBusError error;
2107   const char *path;
2108   dbus_int32_t event_types;
2109   DBusMessage *reply = NULL;
2110
2111   dbus_error_init(&error);
2112   if (!dbus_message_get_args(message, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_UINT32, &event_types, DBUS_TYPE_INVALID))
2113   {
2114     return droute_invalid_arguments_error (message);
2115   }
2116   listener = spi_dec_listener_new (dbus_message_get_sender(message), path, event_types);
2117   spi_controller_deregister_device_listener (
2118           controller, listener);
2119   reply = dbus_message_new_method_return (message);
2120   return reply;
2121 }
2122
2123 static unsigned int dec_xkb_get_slowkeys_delay (SpiDEController *controller)
2124 {
2125   unsigned int retval = 0;
2126   DEControllerPrivateData *priv = (DEControllerPrivateData *)
2127           g_object_get_qdata (G_OBJECT (controller), spi_dec_private_quark);
2128 #ifdef HAVE_XKB
2129 #ifdef XKB_HAS_GET_SLOW_KEYS_DELAY      
2130   retval = XkbGetSlowKeysDelay (spi_get_display (),
2131                                 XkbUseCoreKbd, &bounce_delay);
2132 #else
2133   if (!(priv->xkb_desc == (XkbDescPtr) BadAlloc || priv->xkb_desc == NULL))
2134     {
2135       Status s = XkbGetControls (spi_get_display (),
2136                                  XkbAllControlsMask, priv->xkb_desc);
2137       if (s == Success)
2138         {
2139          if (priv->xkb_desc->ctrls->enabled_ctrls & XkbSlowKeysMask)
2140                  retval = priv->xkb_desc->ctrls->slow_keys_delay;
2141         }
2142     }
2143 #endif
2144 #endif
2145 #ifdef SPI_XKB_DEBUG
2146         fprintf (stderr, "SlowKeys delay: %d\n", (int) retval);
2147 #endif
2148         return retval;
2149 }
2150
2151 static unsigned int dec_xkb_get_bouncekeys_delay (SpiDEController *controller)
2152 {
2153   unsigned int retval = 0;
2154   DEControllerPrivateData *priv = (DEControllerPrivateData *)
2155           g_object_get_qdata (G_OBJECT (controller), spi_dec_private_quark);
2156 #ifdef HAVE_XKB
2157 #ifdef XKB_HAS_GET_BOUNCE_KEYS_DELAY    
2158   retval = XkbGetBounceKeysDelay (spi_get_display (),
2159                                   XkbUseCoreKbd, &bounce_delay);
2160 #else
2161   if (!(priv->xkb_desc == (XkbDescPtr) BadAlloc || priv->xkb_desc == NULL))
2162     {
2163       Status s = XkbGetControls (spi_get_display (),
2164                                  XkbAllControlsMask, priv->xkb_desc);
2165       if (s == Success)
2166         {
2167           if (priv->xkb_desc->ctrls->enabled_ctrls & XkbBounceKeysMask)
2168                   retval = priv->xkb_desc->ctrls->debounce_delay;
2169         }
2170     }
2171 #endif
2172 #endif
2173 #ifdef SPI_XKB_DEBUG
2174   fprintf (stderr, "BounceKeys delay: %d\n", (int) retval);
2175 #endif
2176   return retval;
2177 }
2178
2179 static gboolean
2180 dec_synth_keycode_press (SpiDEController *controller,
2181                          unsigned int keycode)
2182 {
2183         unsigned int time = CurrentTime;
2184         unsigned int bounce_delay;
2185         unsigned int elapsed_msec;
2186         struct timeval tv;
2187         DEControllerPrivateData *priv =
2188                 (DEControllerPrivateData *) g_object_get_qdata (G_OBJECT (controller),
2189                                                                 spi_dec_private_quark);
2190         if (keycode == priv->last_release_keycode)
2191         {
2192                 bounce_delay = dec_xkb_get_bouncekeys_delay (controller); 
2193                 if (bounce_delay)
2194                 {
2195                         gettimeofday (&tv, NULL);
2196                         elapsed_msec =
2197                                 (tv.tv_sec - priv->last_release_time.tv_sec) * 1000
2198                                 + (tv.tv_usec - priv->last_release_time.tv_usec) / 1000;
2199 #ifdef SPI_XKB_DEBUG                    
2200                         fprintf (stderr, "%d ms elapsed (%ld usec)\n", elapsed_msec,
2201                                  (long) (tv.tv_usec - priv->last_release_time.tv_usec));
2202 #endif
2203 #ifdef THIS_IS_BROKEN
2204                         if (elapsed_msec < bounce_delay)
2205                                 time = bounce_delay - elapsed_msec + 1;
2206 #else
2207                         time = bounce_delay + 10;
2208                         /* fudge for broken XTest */
2209 #endif
2210 #ifdef SPI_XKB_DEBUG                    
2211                         fprintf (stderr, "waiting %d ms\n", time);
2212 #endif
2213                 }
2214         }
2215         XTestFakeKeyEvent (spi_get_display (), keycode, True, time);
2216         priv->last_press_keycode = keycode;
2217         XFlush (spi_get_display ());
2218         XSync (spi_get_display (), False);
2219         gettimeofday (&priv->last_press_time, NULL);
2220         return TRUE;
2221 }
2222
2223 static gboolean
2224 dec_synth_keycode_release (SpiDEController *controller,
2225                            unsigned int keycode)
2226 {
2227         unsigned int time = CurrentTime;
2228         unsigned int slow_delay;
2229         unsigned int elapsed_msec;
2230         struct timeval tv;
2231         DEControllerPrivateData *priv =
2232                 (DEControllerPrivateData *) g_object_get_qdata (G_OBJECT (controller),
2233                                                                 spi_dec_private_quark);
2234         if (keycode == priv->last_press_keycode)
2235         {
2236                 slow_delay = dec_xkb_get_slowkeys_delay (controller);
2237                 if (slow_delay)
2238                 {
2239                         gettimeofday (&tv, NULL);
2240                         elapsed_msec =
2241                                 (tv.tv_sec - priv->last_press_time.tv_sec) * 1000
2242                                 + (tv.tv_usec - priv->last_press_time.tv_usec) / 1000;
2243 #ifdef SPI_XKB_DEBUG                    
2244                         fprintf (stderr, "%d ms elapsed (%ld usec)\n", elapsed_msec,
2245                                  (long) (tv.tv_usec - priv->last_press_time.tv_usec));
2246 #endif
2247 #ifdef THIS_IS_BROKEN_DUNNO_WHY
2248                         if (elapsed_msec < slow_delay)
2249                                 time = slow_delay - elapsed_msec + 1;
2250 #else
2251                         time = slow_delay + 10;
2252                         /* our XTest seems broken, we have to add slop as above */
2253 #endif
2254 #ifdef SPI_XKB_DEBUG                    
2255                         fprintf (stderr, "waiting %d ms\n", time);
2256 #endif
2257                 }
2258         }
2259         XTestFakeKeyEvent (spi_get_display (), keycode, False, time);
2260         priv->last_release_keycode = keycode;
2261         XSync (spi_get_display (), False);
2262         gettimeofday (&priv->last_release_time, NULL);
2263         return TRUE;
2264 }
2265
2266 static unsigned
2267 dec_get_modifier_state (SpiDEController *controller)
2268 {
2269         return mouse_mask_state;
2270 }
2271
2272 static gboolean
2273 dec_lock_modifiers (SpiDEController *controller, unsigned modifiers)
2274 {
2275     DEControllerPrivateData *priv = (DEControllerPrivateData *) 
2276     g_object_get_qdata (G_OBJECT (controller), spi_dec_private_quark);   
2277     
2278     if (priv->have_xkb) {
2279         return XkbLockModifiers (spi_get_display (), XkbUseCoreKbd, 
2280                                   modifiers, modifiers);
2281     } else {
2282         int mod_index;
2283         for (mod_index=0;mod_index<8;mod_index++)
2284             if (modifiers & (1<<mod_index))
2285                 dec_synth_keycode_press(controller, xmkeymap->modifiermap[mod_index]);
2286         return TRUE;
2287     }
2288 }
2289
2290 static gboolean
2291 dec_unlock_modifiers (SpiDEController *controller, unsigned modifiers)
2292 {
2293     DEControllerPrivateData *priv = (DEControllerPrivateData *) 
2294     g_object_get_qdata (G_OBJECT (controller), spi_dec_private_quark);   
2295     
2296     if (priv->have_xkb) {
2297         return XkbLockModifiers (spi_get_display (), XkbUseCoreKbd, 
2298                                   modifiers, 0);
2299     } else {
2300         int mod_index;
2301         for (mod_index=0;mod_index<8;mod_index++)
2302             if (modifiers & (1<<mod_index))
2303                 dec_synth_keycode_release(controller, xmkeymap->modifiermap[mod_index]);
2304         return TRUE;
2305     }
2306 }
2307
2308 static KeySym
2309 dec_keysym_for_unichar (SpiDEController *controller, gunichar unichar)
2310 {
2311         return ucs2keysym ((long) unichar);
2312 }
2313
2314 static gboolean
2315 dec_synth_keysym (SpiDEController *controller, KeySym keysym)
2316 {
2317         KeyCode key_synth_code;
2318         unsigned int modifiers, synth_mods, lock_mods;
2319
2320         key_synth_code = keycode_for_keysym (controller, keysym, &synth_mods);
2321
2322         if ((key_synth_code == 0) || (synth_mods == 0xFF)) return FALSE;
2323
2324         /* TODO: set the modifiers accordingly! */
2325         modifiers = dec_get_modifier_state (controller);
2326         /* side-effect; we may unset mousebutton modifiers here! */
2327
2328         lock_mods = 0;
2329         if (synth_mods != modifiers) {
2330                 lock_mods = synth_mods & ~modifiers;
2331                 dec_lock_modifiers (controller, lock_mods);
2332         }
2333         dec_synth_keycode_press (controller, key_synth_code);
2334         dec_synth_keycode_release (controller, key_synth_code);
2335
2336         if (synth_mods != modifiers) 
2337                 dec_unlock_modifiers (controller, lock_mods);
2338         return TRUE;
2339 }
2340
2341
2342 static gboolean
2343 dec_synth_keystring (SpiDEController *controller, const char *keystring)
2344 {
2345         /* probably we need to create and inject an XIM handler eventually. */
2346         /* for now, try to match the string to existing 
2347          * keycode+modifier states. 
2348          */
2349         KeySym *keysyms;
2350         gint maxlen = 0;
2351         gunichar unichar = 0;
2352         gint i = 0;
2353         gboolean retval = TRUE;
2354         const gchar *c;
2355
2356         maxlen = strlen (keystring) + 1;
2357         keysyms = g_new0 (KeySym, maxlen);
2358         if (!(keystring && *keystring && g_utf8_validate (keystring, -1, &c))) { 
2359                 retval = FALSE;
2360         } 
2361         else {
2362 #ifdef SPI_DEBUG
2363                 fprintf (stderr, "[keystring synthesis attempted on %s]\n", keystring);
2364 #endif
2365                 while (keystring && (unichar = g_utf8_get_char (keystring))) {
2366                         KeySym keysym;
2367                         char bytes[6];
2368                         gint mbytes;
2369                         
2370                         mbytes = g_unichar_to_utf8 (unichar, bytes);
2371                         bytes[mbytes] = '\0';
2372 #ifdef SPI_DEBUG
2373                         fprintf (stderr, "[unichar %s]", bytes);
2374 #endif
2375                         keysym = dec_keysym_for_unichar (controller, unichar);
2376                         if (keysym == NoSymbol) {
2377 #ifdef SPI_DEBUG
2378                                 fprintf (stderr, "no keysym for %s", bytes);
2379 #endif
2380                                 retval = FALSE;
2381                                 break;
2382                         }
2383                         keysyms[i++] = keysym;
2384                         keystring = g_utf8_next_char (keystring); 
2385                 }
2386                 keysyms[i++] = 0;
2387                 XSynchronize (spi_get_display (), TRUE);
2388                 for (i = 0; keysyms[i]; ++i) {
2389                         if (!dec_synth_keysym (controller, keysyms[i])) {
2390 #ifdef SPI_DEBUG
2391                                 fprintf (stderr, "could not synthesize %c\n",
2392                                          (int) keysyms[i]);
2393 #endif
2394                                 retval = FALSE;
2395                                 break;
2396                         }
2397                 }
2398                 XSynchronize (spi_get_display (), FALSE);
2399         }
2400         g_free (keysyms);
2401
2402         return retval;
2403 }
2404
2405
2406 /*
2407  * DBus Accessibility::DEController::registerKeystrokeListener
2408  *     method implementation
2409  */
2410 static DBusMessage * impl_generate_keyboard_event (DBusConnection *bus, DBusMessage *message, void *user_data)
2411 {
2412   SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER(user_data);
2413   DBusError error;
2414   dbus_int32_t keycode;
2415   char *keystring;
2416   dbus_uint32_t synth_type;
2417   gint err;
2418   KeySym keysym;
2419   DEControllerPrivateData *priv;
2420   DBusMessage *reply = NULL;
2421
2422   dbus_error_init(&error);
2423   if (!dbus_message_get_args(message, &error, DBUS_TYPE_INT32, &keycode, DBUS_TYPE_STRING, &keystring, DBUS_TYPE_UINT32, &synth_type, DBUS_TYPE_INVALID))
2424   {
2425     return droute_invalid_arguments_error (message);
2426   }
2427
2428 #ifdef SPI_DEBUG
2429         fprintf (stderr, "synthesizing keystroke %ld, type %d\n",
2430                  (long) keycode, (int) synth_type);
2431 #endif
2432   /* TODO: hide/wrap/remove X dependency */
2433
2434   /*
2435    * TODO: when initializing, query for XTest extension before using,
2436    * and fall back to XSendEvent() if XTest is not available.
2437    */
2438   
2439   gdk_error_trap_push ();
2440
2441   priv = (DEControllerPrivateData *) 
2442       g_object_get_qdata (G_OBJECT (controller), spi_dec_private_quark);
2443
2444   if (!priv->have_xkb && xmkeymap==NULL) {
2445     xmkeymap = XGetModifierMapping(spi_get_display ());
2446   }
2447
2448   switch (synth_type)
2449     {
2450       case Accessibility_KEY_PRESS:
2451               dec_synth_keycode_press (controller, keycode);
2452               break;
2453       case Accessibility_KEY_PRESSRELEASE:
2454               dec_synth_keycode_press (controller, keycode);
2455       case Accessibility_KEY_RELEASE:
2456               dec_synth_keycode_release (controller, keycode);
2457               break;
2458       case Accessibility_KEY_SYM:
2459 #ifdef SPI_XKB_DEBUG          
2460               fprintf (stderr, "KeySym synthesis\n");
2461 #endif
2462               /* 
2463                * note: we are using long for 'keycode'
2464                * in our arg list; it can contain either
2465                * a keycode or a keysym.
2466                */
2467               dec_synth_keysym (controller, (KeySym) keycode);
2468               break;
2469       case Accessibility_KEY_STRING:
2470               if (!dec_synth_keystring (controller, keystring))
2471                       fprintf (stderr, "Keystring synthesis failure, string=%s\n",
2472                                keystring);
2473               break;
2474     }
2475   if (synth_type == Accessibility_KEY_SYM) {
2476     keysym = keycode;
2477   }
2478   else {
2479     keysym = XkbKeycodeToKeysym (spi_get_display (), keycode, 0, 0);
2480   }
2481   if (XkbKeysymToModifiers (spi_get_display (), keysym) == 0) 
2482     {
2483       spi_dec_clear_unlatch_pending (controller);
2484     }
2485   reply = dbus_message_new_method_return (message);
2486   return reply;
2487 }
2488
2489 /* Accessibility::DEController::generateMouseEvent */
2490 static DBusMessage * impl_generate_mouse_event (DBusConnection *bus, DBusMessage *message, void *user_data)
2491 {
2492   DBusError error;
2493   dbus_int32_t       x;
2494   dbus_int32_t       y;
2495   char *eventName;
2496   DBusMessage *reply = NULL;
2497   int button = 0;
2498   gboolean err = FALSE;
2499   Display *display = spi_get_display ();
2500
2501   if (!dbus_message_get_args(message, &error, DBUS_TYPE_INT32, &x, DBUS_TYPE_INT32, &y, DBUS_TYPE_STRING, &eventName, DBUS_TYPE_INVALID))
2502   {
2503     return droute_invalid_arguments_error (message);
2504   }
2505
2506 #ifdef SPI_DEBUG
2507   fprintf (stderr, "generating mouse %s event at %ld, %ld\n",
2508            eventName, (long int) x, (long int) y);
2509 #endif
2510   switch (eventName[0])
2511     {
2512       case 'b':
2513         switch (eventName[1])
2514           {
2515           /* TODO: check number of buttons before parsing */
2516           case '1':
2517                     button = 1;
2518                     break;
2519           case '2':
2520                   button = 2;
2521                   break;
2522           case '3':
2523                   button = 3;
2524                   break;
2525           case '4':
2526                   button = 4;
2527                   break;
2528           case '5':
2529                   button = 5;
2530                   break;
2531           default:
2532                   err = TRUE;
2533           }
2534         if (!err)
2535           {
2536             if (x != -1 && y != -1)
2537               {
2538                 XTestFakeMotionEvent (display, DefaultScreen (display),
2539                                       x, y, 0);
2540               }
2541             XTestFakeButtonEvent (display, button, !(eventName[2] == 'r'), 0);
2542             if (eventName[2] == 'c')
2543               XTestFakeButtonEvent (display, button, FALSE, 1);
2544             else if (eventName[2] == 'd')
2545               {
2546               XTestFakeButtonEvent (display, button, FALSE, 1);
2547               XTestFakeButtonEvent (display, button, TRUE, 2);
2548               XTestFakeButtonEvent (display, button, FALSE, 3);
2549               }
2550           }
2551         break;
2552       case 'r': /* relative motion */ 
2553         XTestFakeRelativeMotionEvent (display, x, y, 0);
2554         break;
2555       case 'a': /* absolute motion */
2556         XTestFakeMotionEvent (display, DefaultScreen (display),
2557                               x, y, 0);
2558         break;
2559     }
2560   reply = dbus_message_new_method_return (message);
2561   return reply;
2562 }
2563
2564 /* Accessibility::DEController::notifyListenersSync */
2565 static DBusMessage *
2566 impl_notify_listeners_sync (DBusConnection *bus, DBusMessage *message, void *user_data)
2567 {
2568   SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER(user_data);
2569   Accessibility_DeviceEvent event;
2570   dbus_bool_t ret;
2571   DBusMessage *reply = NULL;
2572
2573   if (!spi_dbus_demarshal_deviceEvent(message, &event))
2574   {
2575     return droute_invalid_arguments_error (message);
2576   }
2577 #ifdef SPI_DEBUG
2578   g_print ("notifylistening listeners synchronously: controller %p, event id %d\n",
2579            controller, (int) event.id);
2580 #endif
2581   ret = spi_controller_notify_keylisteners (controller,
2582                                              (Accessibility_DeviceEvent *) 
2583                                              &event, FALSE) ?
2584           TRUE : FALSE; 
2585   reply = dbus_message_new_method_return (message);
2586   if (reply)
2587   {
2588     dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret, DBUS_TYPE_INVALID);
2589   }
2590   return reply;
2591 }
2592
2593 static DBusMessage *
2594 impl_notify_listeners_async (DBusConnection *bus, DBusMessage *message, void *user_data)
2595 {
2596   SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER(user_data);
2597   Accessibility_DeviceEvent event;
2598   DBusMessage *reply = NULL;
2599
2600   if (!spi_dbus_demarshal_deviceEvent(message, &event))
2601   {
2602     return droute_invalid_arguments_error (message);
2603   }
2604 #ifdef SPI_DEBUG
2605   g_print ("notifylistening listeners asynchronously: controller %p, event id %d\n",
2606            controller, (int) event.id);
2607 #endif
2608   spi_controller_notify_keylisteners (controller, (Accessibility_DeviceEvent *)
2609                                       &event, FALSE); 
2610   reply = dbus_message_new_method_return (message);
2611   return reply;
2612 }
2613
2614 static void
2615 spi_device_event_controller_class_init (SpiDEControllerClass *klass)
2616 {
2617   GObjectClass * object_class = (GObjectClass *) klass;
2618
2619   spi_device_event_controller_parent_class = g_type_class_peek_parent (klass);
2620
2621   object_class->finalize = spi_device_event_controller_object_finalize;
2622
2623   if (!spi_dec_private_quark)
2624           spi_dec_private_quark = g_quark_from_static_string ("spi-dec-private");
2625 }
2626
2627 #ifdef HAVE_XEVIE
2628 static Bool isEvent(Display *dpy, XEvent *event, char *arg)
2629 {
2630    return TRUE;
2631 }
2632
2633 static gboolean
2634 handle_io (GIOChannel *source,
2635            GIOCondition condition,
2636            gpointer data) 
2637 {
2638   SpiDEController *controller = (SpiDEController *) data;
2639   gboolean is_consumed = FALSE;
2640   XEvent ev;
2641
2642   while (XCheckIfEvent(controller->xevie_display, &ev, isEvent, NULL))
2643     {
2644       if (ev.type == KeyPress || ev.type == KeyRelease)
2645         is_consumed = spi_device_event_controller_forward_key_event (controller, &ev);
2646
2647       if (! is_consumed)
2648         XevieSendEvent(controller->xevie_display, &ev, XEVIE_UNMODIFIED);
2649     }
2650
2651   return TRUE;
2652 }
2653 #endif /* HAVE_XEVIE */
2654
2655 static void
2656 spi_device_event_controller_init (SpiDEController *device_event_controller)
2657 {
2658 #ifdef HAVE_XEVIE
2659   GIOChannel *ioc;
2660   int fd;
2661 #endif /* HAVE_XEVIE */
2662
2663   DEControllerPrivateData *private;     
2664   device_event_controller->key_listeners   = NULL;
2665   device_event_controller->mouse_listeners = NULL;
2666   device_event_controller->keygrabs_list   = NULL;
2667   device_event_controller->xevie_display   = NULL;
2668
2669 #ifdef HAVE_XEVIE
2670   device_event_controller->xevie_display = XOpenDisplay(NULL);
2671
2672   if (XevieStart(device_event_controller->xevie_display) == TRUE)
2673     {
2674 #ifdef SPI_KEYEVENT_DEBUG
2675       fprintf (stderr, "XevieStart() success \n");
2676 #endif
2677       XevieSelectInput(device_event_controller->xevie_display, KeyPressMask | KeyReleaseMask);
2678
2679       fd = ConnectionNumber(device_event_controller->xevie_display);
2680       ioc = g_io_channel_unix_new (fd);
2681       g_io_add_watch (ioc, G_IO_IN | G_IO_HUP, handle_io, device_event_controller);
2682       g_io_channel_unref (ioc);
2683     }
2684   else
2685     {
2686       device_event_controller->xevie_display = NULL;
2687 #ifdef SPI_KEYEVENT_DEBUG
2688       fprintf (stderr, "XevieStart() failed, only one client is allowed to do event int exception\n");
2689 #endif
2690     }
2691 #endif /* HAVE_XEVIE */
2692
2693   private = g_new0 (DEControllerPrivateData, 1);
2694   gettimeofday (&private->last_press_time, NULL);
2695   gettimeofday (&private->last_release_time, NULL);
2696   g_object_set_qdata (G_OBJECT (device_event_controller),
2697                       spi_dec_private_quark,
2698                       private);
2699   spi_controller_register_with_devices (device_event_controller);
2700 }
2701
2702 static gboolean
2703 spi_device_event_controller_forward_key_event (SpiDEController *controller,
2704                                                const XEvent    *event)
2705 {
2706   Accessibility_DeviceEvent key_event;
2707   gboolean ret;
2708
2709   g_assert (event->type == KeyPress || event->type == KeyRelease);
2710
2711   key_event = spi_keystroke_from_x_key_event ((XKeyEvent *) event);
2712
2713   if (controller->xevie_display == NULL)
2714     spi_controller_update_key_grabs (controller, &key_event);
2715
2716   /* relay to listeners, and decide whether to consume it or not */
2717   ret = spi_controller_notify_keylisteners (controller, &key_event, TRUE);
2718   g_free(key_event.event_string);
2719   return ret;
2720 }
2721
2722
2723 static gboolean
2724 is_key_released (KeyCode code)
2725 {
2726   char keys[32];
2727   int down;
2728
2729   XQueryKeymap (spi_get_display (), keys);
2730   down = BIT (keys, code);
2731   return (down == 0);
2732 }
2733
2734 static gboolean
2735 check_release (gpointer data)
2736 {
2737   gboolean released;
2738   Accessibility_DeviceEvent *event = (Accessibility_DeviceEvent *)data;
2739   KeyCode code = event->hw_code;
2740
2741   released = is_key_released (code);
2742
2743   if (released)
2744     {
2745       check_release_handler = 0;
2746       event->type = Accessibility_KEY_RELEASED_EVENT;
2747       spi_controller_notify_keylisteners (saved_controller, event, TRUE);
2748     }
2749   return (released == 0);
2750 }
2751
2752 static void wait_for_release_event (XEvent          *event,
2753                                     SpiDEController *controller)
2754 {
2755   pressed_event = spi_keystroke_from_x_key_event ((XKeyEvent *) event);
2756   saved_controller = controller;
2757   check_release_handler = g_timeout_add (CHECK_RELEASE_DELAY, check_release, &pressed_event);
2758 }
2759
2760 static DRouteMethod dev_methods[] =
2761 {
2762   { impl_register_keystroke_listener, "registerKeystrokeListener" },
2763   { impl_register_device_event_listener, "registerDeviceEventListener" },
2764   { impl_deregister_keystroke_listener, "deregisterKeystrokeListener" },
2765   { impl_deregister_device_event_listener, "deregisterDeviceEventListener" },
2766   { impl_generate_keyboard_event, "generateKeyboardEvent" },
2767   { impl_generate_mouse_event, "generateMouseEvent" },
2768   { impl_notify_listeners_sync, "notifyListenersSync" },
2769   { impl_notify_listeners_async, "notifyListenersAsync" },
2770   { NULL, NULL }
2771 };
2772
2773 SpiDEController *
2774 spi_registry_dec_new (SpiRegistry *reg, DBusConnection *bus, DRouteContext *droute)
2775 {
2776   SpiDEController *dec = g_object_new (SPI_DEVICE_EVENT_CONTROLLER_TYPE, NULL);
2777   DRoutePath *path;
2778
2779   dec->registry = g_object_ref (reg);
2780   dec->bus = bus;
2781
2782   path = droute_add_one (droute,
2783                          SPI_DBUS_PATH_DEC,
2784                          dec);
2785
2786   droute_path_add_interface (path,
2787                              SPI_DBUS_INTERFACE_DEC,
2788                              dev_methods,
2789                              NULL);
2790
2791   spi_dec_init_mouse_listener (dec);
2792   /* TODO: kill mouse listener on finalize */
2793
2794   return dec;
2795 }
2796
2797 void
2798 spi_device_event_controller_start_poll_mouse (SpiRegistry *registry)
2799 {
2800   if (!have_mouse_event_listener)
2801     {
2802       have_mouse_event_listener = TRUE;
2803       if (!have_mouse_listener)
2804       g_timeout_add (100, spi_dec_poll_mouse_idle, registry);
2805     }
2806 }
2807
2808 void
2809 spi_device_event_controller_stop_poll_mouse (void)
2810 {
2811   have_mouse_event_listener = FALSE;
2812 }