Add names to every timeout
[platform/upstream/at-spi2-core.git] / registryd / deviceeventcontroller-x11.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-x11.c: X-specific DeviceEventController support */
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/Xutil.h>
39 #include <X11/extensions/XTest.h>
40 #include <X11/XKBlib.h>
41
42 #define XK_MISCELLANY
43 #define XK_LATIN1
44 #include <X11/keysymdef.h>
45
46 #ifdef HAVE_XEVIE
47 #include <X11/Xproto.h>
48 #include <X11/X.h>
49 #include <X11/extensions/Xevie.h>
50 #endif /* HAVE_XEVIE */
51
52 #include <glib.h>
53
54 #include <dbus/dbus.h>
55
56 #include "paths.h"
57 #include "keymasks.h"
58 #include "de-types.h"
59 #include "de-marshaller.h"
60 #include "display.h"
61 #include "event-source.h"
62
63 #include "deviceeventcontroller.h"
64 #include "reentrant-list.h"
65
66 #include "introspection.h"
67
68 static void spi_dec_x11_emit_modifier_event (SpiDEController *controller,
69                              guint prev_mask,
70                              guint current_mask);
71
72 #define CHECK_RELEASE_DELAY 20
73 #define BIT(c, x)       (c[x/8]&(1<<(x%8)))
74 static guint check_release_handler = 0;
75 static Accessibility_DeviceEvent pressed_event;
76 static void wait_for_release_event (XEvent *event, SpiDEController *controller);
77
78 static int spi_error_code = 0;
79 struct _SpiPoint {
80     gint x;
81     gint y;
82 };
83 typedef struct _SpiPoint SpiPoint;
84 static SpiPoint last_mouse_pos_static = {0, 0}; 
85 static SpiPoint *last_mouse_pos = &last_mouse_pos_static;
86 static unsigned int mouse_mask_state = 0;
87 static unsigned int mouse_button_mask =
88   Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask;
89 static unsigned int key_modifier_mask =
90   Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask | ShiftMask | LockMask | ControlMask | SPI_KEYMASK_NUMLOCK;
91 static unsigned int _numlock_physical_mask = Mod2Mask; /* a guess, will be reset */
92
93 static XModifierKeymap* xmkeymap = NULL;
94
95
96 static int (*x_default_error_handler) (Display *display, XErrorEvent *error_event);
97
98 typedef struct {
99   Display *xevie_display;
100   unsigned int last_press_keycode;
101   unsigned int last_release_keycode;
102   struct timeval last_press_time;
103   struct timeval last_release_time;
104   int have_xkb;
105   int xkb_major_extension_opcode;
106   int xkb_base_event_code;
107   int xkb_base_error_code;
108   unsigned int xkb_latch_mask;
109   unsigned int pending_xkb_mod_relatch_mask;
110   XkbDescPtr xkb_desc;
111   KeyCode reserved_keycode;
112   KeySym reserved_keysym;
113   guint  reserved_reset_timeout;
114 } DEControllerPrivateData;
115
116 static void     spi_controller_register_with_devices          (SpiDEController           *controller);
117 static gboolean spi_device_event_controller_forward_key_event (SpiDEController           *controller,
118                                                                const XEvent              *event);
119
120
121 static SpiDEController *saved_controller;
122
123 static unsigned int
124 keysym_mod_mask (KeySym keysym, KeyCode keycode)
125 {
126         /* we really should use XKB and look directly at the keymap */
127         /* this is very inelegant */
128         Display *display = spi_get_display ();
129         unsigned int mods_rtn = 0;
130         unsigned int retval = 0;
131         KeySym sym_rtn;
132
133         if (XkbLookupKeySym (display, keycode, 0, &mods_rtn, &sym_rtn) &&
134             (sym_rtn == keysym)) {
135                 retval = 0;
136         }
137         else if (XkbLookupKeySym (display, keycode, ShiftMask, &mods_rtn, &sym_rtn) &&
138                  (sym_rtn == keysym)) {
139                 retval = ShiftMask;
140         }
141         else if (XkbLookupKeySym (display, keycode, Mod2Mask, &mods_rtn, &sym_rtn) &&
142                  (sym_rtn == keysym)) {
143                 retval = Mod2Mask;
144         }
145         else if (XkbLookupKeySym (display, keycode, Mod3Mask, &mods_rtn, &sym_rtn) &&
146                  (sym_rtn == keysym)) {
147                 retval = Mod3Mask;
148         }
149         else if (XkbLookupKeySym (display, keycode, 
150                                   ShiftMask | Mod2Mask, &mods_rtn, &sym_rtn) &&
151                  (sym_rtn == keysym)) {
152                 retval = (Mod2Mask | ShiftMask);
153         }
154         else if (XkbLookupKeySym (display, keycode, 
155                                   ShiftMask | Mod3Mask, &mods_rtn, &sym_rtn) &&
156                  (sym_rtn == keysym)) {
157                 retval = (Mod3Mask | ShiftMask);
158         }
159         else if (XkbLookupKeySym (display, keycode, 
160                                   ShiftMask | Mod4Mask, &mods_rtn, &sym_rtn) &&
161                  (sym_rtn == keysym)) {
162                 retval = (Mod4Mask | ShiftMask);
163         }
164         else
165                 retval = 0xFFFF;
166         return retval;
167 }
168
169 static gboolean
170 replace_map_keysym (DEControllerPrivateData *priv, KeyCode keycode, KeySym keysym)
171 {
172 #ifdef HAVE_XKB
173   Display *dpy = spi_get_display ();
174   XkbDescPtr desc;
175   if (!(desc = XkbGetMap (dpy, XkbAllMapComponentsMask, XkbUseCoreKbd)))
176     {
177       fprintf (stderr, "ERROR getting map\n");
178     }
179   XFlush (dpy);
180   XSync (dpy, False);
181   if (desc && desc->map)
182     {
183       gint offset = desc->map->key_sym_map[keycode].offset;
184       desc->map->syms[offset] = keysym; 
185     }
186   else
187     {
188       fprintf (stderr, "Error changing key map: empty server structure\n");
189     }           
190   XkbSetMap (dpy, XkbAllMapComponentsMask, desc);
191   /**
192    *  FIXME: the use of XkbChangeMap, and the reuse of the priv->xkb_desc structure, 
193    * would be far preferable.
194    * HOWEVER it does not seem to work using XFree 4.3. 
195    **/
196   /*        XkbChangeMap (dpy, priv->xkb_desc, priv->changes); */
197   XFlush (dpy);
198   XSync (dpy, False);
199   XkbFreeKeyboard (desc, 0, TRUE);
200
201   return TRUE;
202 #else
203   return FALSE;
204 #endif
205 }
206
207 static gboolean
208 spi_dec_reset_reserved (gpointer data)
209 {
210   DEControllerPrivateData *priv = data;
211   replace_map_keysym (priv, priv->reserved_keycode, priv->reserved_keysym);
212   priv->reserved_reset_timeout = 0;
213   return FALSE;
214 }
215
216 static gint
217 spi_dec_x11_get_keycode (SpiDEController *controller,
218                           gint keysym,
219                           gchar *key_str,
220                           gboolean fix,
221                           guint *modmask)
222 {
223         KeyCode keycode = 0;
224   if (key_str && key_str[0])
225                 keysym = XStringToKeysym(key_str);
226         keycode = XKeysymToKeycode (spi_get_display (), (KeySym) keysym);
227         if (!keycode && fix)
228         {
229                 DEControllerPrivateData *priv = controller->priv;
230                 /* if there's no keycode available, fix it */
231                 if (replace_map_keysym (priv, priv->reserved_keycode, keysym))
232                 {
233                         keycode = priv->reserved_keycode;
234                         /* 
235                          * queue a timer to restore the old keycode.  Ugly, but required 
236                          * due to races / asynchronous X delivery.   
237                          * Long-term fix is to extend the X keymap here instead of replace entries.
238                          */
239                         priv->reserved_reset_timeout = g_timeout_add (500, spi_dec_reset_reserved, priv);
240                         g_source_set_name_by_id (priv->reserved_reset_timeout, "[at-spi2-core] spi_dec_reset_reserved");
241                 }               
242                 if (modmask)
243                         *modmask = 0;
244                 return keycode;
245         }
246         if (modmask) 
247                 *modmask = keysym_mod_mask (keysym, keycode);
248         return keycode;
249 }
250
251 static void
252 spi_dec_set_unlatch_pending (SpiDEController *controller, unsigned mask)
253 {
254   DEControllerPrivateData *priv = controller->priv;
255 #ifdef SPI_XKB_DEBUG
256   if (priv->xkb_latch_mask) fprintf (stderr, "unlatch pending! %x\n", 
257                                      priv->xkb_latch_mask);
258 #endif
259   priv->pending_xkb_mod_relatch_mask |= priv->xkb_latch_mask; 
260 }
261  
262 static gboolean
263 spi_dec_button_update_and_emit (SpiDEController *controller,
264                                 guint mask_return)
265 {
266   Accessibility_DeviceEvent mouse_e;
267   gchar event_detail[3];
268   gboolean is_consumed = FALSE;
269
270   if ((mask_return & mouse_button_mask) !=
271       (mouse_mask_state & mouse_button_mask)) 
272     {
273       int button_number = 0;
274       gboolean is_down = False;
275       
276       if (!(mask_return & Button1Mask) &&
277           (mouse_mask_state & Button1Mask)) 
278         {
279           mouse_mask_state &= ~Button1Mask;
280           button_number = 1;
281         } 
282       else if ((mask_return & Button1Mask) &&
283                !(mouse_mask_state & Button1Mask)) 
284         {
285           mouse_mask_state |= Button1Mask;
286           button_number = 1;
287           is_down = True;
288         } 
289       else if (!(mask_return & Button2Mask) &&
290                (mouse_mask_state & Button2Mask)) 
291         {
292           mouse_mask_state &= ~Button2Mask;
293           button_number = 2;
294         } 
295       else if ((mask_return & Button2Mask) &&
296                !(mouse_mask_state & Button2Mask)) 
297         {
298           mouse_mask_state |= Button2Mask;
299           button_number = 2;
300           is_down = True;
301         } 
302       else if (!(mask_return & Button3Mask) &&
303                (mouse_mask_state & Button3Mask)) 
304         {
305           mouse_mask_state &= ~Button3Mask;
306           button_number = 3;
307         } 
308       else if ((mask_return & Button3Mask) &&
309                !(mouse_mask_state & Button3Mask)) 
310         {
311           mouse_mask_state |= Button3Mask;
312           button_number = 3;
313           is_down = True;
314         } 
315       else if (!(mask_return & Button4Mask) &&
316                (mouse_mask_state & Button4Mask)) 
317         {
318           mouse_mask_state &= ~Button4Mask;
319           button_number = 4;
320         } 
321       else if ((mask_return & Button4Mask) &&
322                !(mouse_mask_state & Button4Mask)) 
323         {
324           mouse_mask_state |= Button4Mask;
325           button_number = 4;
326           is_down = True;
327         } 
328       else if (!(mask_return & Button5Mask) &&
329                (mouse_mask_state & Button5Mask)) 
330         {
331           mouse_mask_state &= ~Button5Mask;
332           button_number = 5;
333         }
334       else if ((mask_return & Button5Mask) &&
335                !(mouse_mask_state & Button5Mask)) 
336         {
337           mouse_mask_state |= Button5Mask;
338           button_number = 5;
339           is_down = True;
340         }
341       if (button_number) {
342 #ifdef SPI_DEBUG                  
343         fprintf (stderr, "Button %d %s\n",
344                  button_number, (is_down) ? "Pressed" : "Released");
345 #endif
346         snprintf (event_detail, 3, "%d%c", button_number,
347                   (is_down) ? 'p' : 'r');
348         /* TODO: FIXME distinguish between physical and 
349          * logical buttons 
350          */
351         mouse_e.type      = (is_down) ? 
352           Accessibility_BUTTON_PRESSED_EVENT :
353           Accessibility_BUTTON_RELEASED_EVENT;
354         mouse_e.id        = button_number;
355         mouse_e.hw_code   = button_number;
356         mouse_e.modifiers = (dbus_uint16_t) mouse_mask_state; 
357         mouse_e.timestamp = 0;
358         mouse_e.event_string = "";
359         mouse_e.is_text   = FALSE;
360         is_consumed = 
361           spi_controller_notify_mouselisteners (controller, 
362                                                 &mouse_e);
363         if (!is_consumed)
364           {
365             dbus_uint32_t x = last_mouse_pos->x, y = last_mouse_pos->y;
366             spi_dec_dbus_emit(controller, SPI_DBUS_INTERFACE_EVENT_MOUSE, "Button", event_detail, x, y);
367           }
368         else
369           spi_dec_set_unlatch_pending (controller, mask_return);
370       }
371       return TRUE;
372     }
373   else
374     {
375       return FALSE;
376     }
377 }
378
379 static guint
380 spi_dec_x11_mouse_check (SpiDEController *controller, 
381                      int *x, int *y, gboolean *moved)
382 {
383   int win_x_return,win_y_return;
384   unsigned int mask_return;
385   Window root_return, child_return;
386   Display *display = spi_get_display ();
387
388   if (display != NULL)
389     XQueryPointer(display, DefaultRootWindow (display),
390                   &root_return, &child_return,
391                   x, y,
392                   &win_x_return, &win_y_return, &mask_return);
393   /* 
394    * Since many clients grab the pointer, and X goes an automatic
395    * pointer grab on mouse-down, we often must detect mouse button events
396    * by polling rather than via a button grab. 
397    * The while loop (rather than if) is used since it's possible that 
398    * multiple buttons have changed state since we last checked.
399    */
400   if (mask_return != mouse_mask_state) 
401     {
402       while (spi_dec_button_update_and_emit (controller, mask_return));
403     }
404
405   if (*x != last_mouse_pos->x || *y != last_mouse_pos->y) 
406     {
407       // TODO: combine these two signals?
408       dbus_uint32_t ix = *x, iy = *y;
409       spi_dec_dbus_emit(controller, SPI_DBUS_INTERFACE_EVENT_MOUSE, "Abs", "", ix, iy);
410       ix -= last_mouse_pos->x;
411       iy -= last_mouse_pos->y;
412       spi_dec_dbus_emit(controller, SPI_DBUS_INTERFACE_EVENT_MOUSE, "Rel", "", ix, iy);
413       last_mouse_pos->x = *x;
414       last_mouse_pos->y = *y;
415       *moved = True;
416     }
417   else
418     {
419       *moved = False;
420     }
421
422   return mask_return;
423 }
424
425 #ifdef WE_NEED_UGRAB_MOUSE
426 static int
427 spi_dec_ungrab_mouse (gpointer data)
428 {
429         Display *display = spi_get_display ();
430         if (display)
431           {
432             XUngrabButton (spi_get_display (), AnyButton, AnyModifier,
433                            XDefaultRootWindow (spi_get_display ()));
434           }
435         return FALSE;
436 }
437 #endif
438
439 static void
440 spi_dec_init_mouse_listener (SpiDEController *dec)
441 {
442 #ifdef GRAB_BUTTON
443   Display *display = spi_get_display ();
444
445   if (display)
446     {
447       if (XGrabButton (display, AnyButton, AnyModifier,
448                        spi_get_root_window (),
449                        True, ButtonPressMask | ButtonReleaseMask,
450                        GrabModeSync, GrabModeAsync, None, None) != Success) {
451 #ifdef SPI_DEBUG
452         fprintf (stderr, "WARNING: could not grab mouse buttons!\n");
453 #endif
454         ;
455       }
456       XSync (display, False);
457 #ifdef SPI_DEBUG
458       fprintf (stderr, "mouse buttons grabbed\n");
459 #endif
460     }
461 #endif
462 }
463
464 static void
465 spi_dec_clear_unlatch_pending (SpiDEController *controller)
466 {
467   DEControllerPrivateData *priv = controller->priv;
468   priv->xkb_latch_mask = 0;
469 }
470
471 static void
472 spi_device_event_controller_forward_mouse_event (SpiDEController *controller,
473                                                  XEvent *xevent)
474 {
475   Accessibility_DeviceEvent mouse_e;
476   gchar event_detail[3];
477   gboolean is_consumed = FALSE;
478   gboolean xkb_mod_unlatch_occurred;
479   XButtonEvent *xbutton_event = (XButtonEvent *) xevent;
480   dbus_uint32_t ix, iy;
481
482   int button = xbutton_event->button;
483   
484   unsigned int mouse_button_state = xbutton_event->state;
485
486   switch (button)
487     {
488     case 1:
489             mouse_button_state |= Button1Mask;
490             break;
491     case 2:
492             mouse_button_state |= Button2Mask;
493             break;
494     case 3:
495             mouse_button_state |= Button3Mask;
496             break;
497     case 4:
498             mouse_button_state |= Button4Mask;
499             break;
500     case 5:
501             mouse_button_state |= Button5Mask;
502             break;
503     }
504
505   last_mouse_pos->x = ((XButtonEvent *) xevent)->x_root;
506   last_mouse_pos->y = ((XButtonEvent *) xevent)->y_root;
507
508 #ifdef SPI_DEBUG  
509   fprintf (stderr, "mouse button %d %s (%x)\n",
510            xbutton_event->button, 
511            (xevent->type == ButtonPress) ? "Press" : "Release",
512            mouse_button_state);
513 #endif
514   snprintf (event_detail, 3, "%d%c", button,
515             (xevent->type == ButtonPress) ? 'p' : 'r');
516
517   /* TODO: FIXME distinguish between physical and logical buttons */
518   mouse_e.type      = (xevent->type == ButtonPress) ? 
519                       Accessibility_BUTTON_PRESSED_EVENT :
520                       Accessibility_BUTTON_RELEASED_EVENT;
521   mouse_e.id        = button;
522   mouse_e.hw_code   = button;
523   mouse_e.modifiers = (dbus_uint16_t) xbutton_event->state;
524   mouse_e.timestamp = (dbus_uint32_t) xbutton_event->time;
525   mouse_e.event_string = "";
526   mouse_e.is_text   = FALSE;
527   if ((mouse_button_state & mouse_button_mask) != 
528        (mouse_mask_state & mouse_button_mask))
529     { 
530       if ((mouse_mask_state & key_modifier_mask) !=
531           (mouse_button_state & key_modifier_mask))
532         spi_dec_x11_emit_modifier_event (controller, 
533                                      mouse_mask_state, mouse_button_state);
534       mouse_mask_state = mouse_button_state;
535       is_consumed = 
536         spi_controller_notify_mouselisteners (controller, &mouse_e);
537       ix = last_mouse_pos->x;
538       iy = last_mouse_pos->y;
539       spi_dec_dbus_emit(controller, SPI_DBUS_INTERFACE_EVENT_MOUSE, "Button", event_detail, ix, iy);
540     }
541
542   xkb_mod_unlatch_occurred = (xevent->type == ButtonPress ||
543                               xevent->type == ButtonRelease);
544   
545   /* if client wants to consume this event, and XKB latch state was
546    *   unset by this button event, we reset it
547    */
548   if (is_consumed && xkb_mod_unlatch_occurred)
549     spi_dec_set_unlatch_pending (controller, mouse_mask_state);
550   
551   XAllowEvents (spi_get_display (),
552                 (is_consumed) ? SyncPointer : ReplayPointer,
553                 CurrentTime);
554 }
555
556 static void
557 global_filter_fn (XEvent *xevent, void *data)
558 {
559   SpiDEController *controller;
560   DEControllerPrivateData *priv;
561   Display *display = spi_get_display ();
562   controller = SPI_DEVICE_EVENT_CONTROLLER (data);
563   priv = controller->priv;
564
565   if (xevent->type == MappingNotify)
566     xmkeymap = NULL;
567
568   if (xevent->type == KeyPress || xevent->type == KeyRelease)
569     {
570       if (priv->xevie_display == NULL)
571         {
572           gboolean is_consumed;
573
574           is_consumed =
575             spi_device_event_controller_forward_key_event (controller, xevent);
576
577           if (is_consumed)
578             {
579               int n_events;
580               int i;
581               XEvent next_event;
582               n_events = XPending (display);
583
584 #ifdef SPI_KEYEVENT_DEBUG
585               g_print ("Number of events pending: %d\n", n_events);
586 #endif
587               for (i = 0; i < n_events; i++)
588                 {
589                   XNextEvent (display, &next_event);
590                   if (next_event.type != KeyPress &&
591                       next_event.type != KeyRelease)
592                         g_warning ("Unexpected event type %d in queue", next_event.type);
593                  }
594
595               XAllowEvents (display, AsyncKeyboard, CurrentTime);
596               if (n_events)
597                 XUngrabKeyboard (display, CurrentTime);
598             }
599           else
600             {
601               if (xevent->type == KeyPress)
602                 wait_for_release_event (xevent, controller);
603               XAllowEvents (display, ReplayKeyboard, CurrentTime);
604             }
605         }
606
607       return;
608     }
609   if (xevent->type == ButtonPress || xevent->type == ButtonRelease)
610     {
611       spi_device_event_controller_forward_mouse_event (controller, xevent);
612     }
613   if (xevent->type == priv->xkb_base_event_code)
614     {
615       XkbAnyEvent * xkb_ev = (XkbAnyEvent *) xevent;
616       /* ugly but probably necessary...*/
617       XSynchronize (display, TRUE);
618
619       if (xkb_ev->xkb_type == XkbStateNotify)
620         {
621           XkbStateNotifyEvent *xkb_snev =
622                   (XkbStateNotifyEvent *) xkb_ev;
623           /* check the mouse, to catch mouse events grabbed by
624            * another client; in case we should revert this XKB delatch 
625            */
626           if (!priv->pending_xkb_mod_relatch_mask)
627             {
628               int x, y;
629               gboolean moved;
630               spi_dec_x11_mouse_check (controller, &x, &y, &moved);
631             }
632           /* we check again, since the previous call may have 
633              changed this flag */
634           if (priv->pending_xkb_mod_relatch_mask)
635             {
636               unsigned int feedback_mask;
637 #ifdef SPI_XKB_DEBUG
638               fprintf (stderr, "relatching %x\n",
639                        priv->pending_xkb_mod_relatch_mask);
640 #endif
641               /* temporarily turn off the latch bell, if it's on */
642               XkbGetControls (display,
643                               XkbAccessXFeedbackMask,
644                               priv->xkb_desc);
645               feedback_mask = priv->xkb_desc->ctrls->ax_options;
646               if (feedback_mask & XkbAX_StickyKeysFBMask)
647               {
648                 XkbControlsChangesRec changes = {XkbAccessXFeedbackMask,
649                                                  0, False};      
650                 priv->xkb_desc->ctrls->ax_options
651                               &= ~(XkbAX_StickyKeysFBMask);
652                 XkbChangeControls (display, priv->xkb_desc, &changes);
653               }
654               /* TODO: account for lock as well as latch */
655               XkbLatchModifiers (display,
656                                  XkbUseCoreKbd,
657                                  priv->pending_xkb_mod_relatch_mask,
658                                  priv->pending_xkb_mod_relatch_mask);
659               if (feedback_mask & XkbAX_StickyKeysFBMask)
660               { 
661                 XkbControlsChangesRec changes = {XkbAccessXFeedbackMask,
662                                                  0, False};      
663                 priv->xkb_desc->ctrls->ax_options = feedback_mask;
664                 XkbChangeControls (display, priv->xkb_desc, &changes);
665               }
666 #ifdef SPI_XKB_DEBUG
667               fprintf (stderr, "relatched %x\n",
668                        priv->pending_xkb_mod_relatch_mask);
669 #endif
670               priv->pending_xkb_mod_relatch_mask = 0;
671             }
672           else
673             {
674               priv->xkb_latch_mask = xkb_snev->latched_mods;
675             }
676         }
677       XSynchronize (display, FALSE);
678     }
679   
680   return;
681 }
682
683 static int
684 _spi_controller_device_error_handler (Display *display, XErrorEvent *error)
685 {
686   if (error->error_code == BadAccess) 
687     {  
688       g_message ("Could not complete key grab: grab already in use.\n");
689       spi_error_code = BadAccess;
690       return 0;
691     }
692   else 
693     {
694       return (*x_default_error_handler) (display, error);
695     }
696 }
697
698 static void
699 spi_controller_register_with_devices (SpiDEController *controller)
700 {
701   DEControllerPrivateData *priv;
702   int event_base, error_base, major_version, minor_version;
703
704   priv = controller->priv;
705   if (XTestQueryExtension (spi_get_display(), &event_base, &error_base, &major_version, &minor_version))
706     {
707       XTestGrabControl (spi_get_display (), True);
708     }
709
710   /* calls to device-specific implementations and routines go here */
711   /* register with: keyboard hardware code handler */
712   /* register with: (translated) keystroke handler */
713
714   priv->have_xkb = XkbQueryExtension (spi_get_display (),
715                                       &priv->xkb_major_extension_opcode,
716                                       &priv->xkb_base_event_code,
717                                       &priv->xkb_base_error_code, NULL, NULL);
718   if (priv->have_xkb)
719     {
720       gint i;
721       guint64 reserved = 0;
722       priv->xkb_desc = XkbGetMap (spi_get_display (), XkbKeySymsMask, XkbUseCoreKbd);
723       XkbSelectEvents (spi_get_display (),
724                        XkbUseCoreKbd,
725                        XkbStateNotifyMask, XkbStateNotifyMask);     
726       _numlock_physical_mask = XkbKeysymToModifiers (spi_get_display (), 
727                                                      XK_Num_Lock);
728       for (i = priv->xkb_desc->max_key_code; i >= priv->xkb_desc->min_key_code; --i)
729       {
730           if (priv->xkb_desc->map->key_sym_map[i].kt_index[0] == XkbOneLevelIndex)
731           { 
732               if (XkbKeycodeToKeysym (spi_get_display (), i, 0, 0) != 0)
733               {
734                   /* don't use this one if there's a grab client! */
735
736                   /* Runtime errors are generated from these functions,
737                    * that are then quashed. Equivalent to:
738                    * try
739                    *   {Blah}
740                    * except
741                    *   {;}
742                    */
743
744                   spi_x_error_trap ();
745                   XGrabKey (spi_get_display (), i, 0, 
746                             spi_get_root_window (),
747                             TRUE,
748                             GrabModeSync, GrabModeSync);
749                   XSync (spi_get_display (), TRUE);
750                   XUngrabKey (spi_get_display (), i, 0, 
751                               spi_get_root_window ());
752                   if (!spi_x_error_release ())
753                   {
754                       reserved = i;
755                       break;
756                   }
757               }
758           }
759       }
760       if (reserved) 
761       {
762           priv->reserved_keycode = reserved;
763           priv->reserved_keysym = XkbKeycodeToKeysym (spi_get_display (), reserved, 0, 0);
764       }
765       else
766       { 
767           priv->reserved_keycode = XKeysymToKeycode (spi_get_display (), XK_numbersign);
768           priv->reserved_keysym = XK_numbersign;
769       }
770 #ifdef SPI_RESERVED_DEBUG
771       unsigned sym = 0;
772       sym = XKeycodeToKeysym (spi_get_display (), reserved, 0);
773       fprintf (stderr, "%x\n", sym);
774       fprintf (stderr, "setting the reserved keycode to %d (%s)\n", 
775                reserved, 
776                XKeysymToString (XKeycodeToKeysym (spi_get_display (),
777                                                             reserved, 0)));
778 #endif
779     }   
780
781   spi_set_filter (global_filter_fn, controller);
782   spi_set_events (KeyPressMask | KeyReleaseMask);
783
784   x_default_error_handler = XSetErrorHandler (_spi_controller_device_error_handler);
785 }
786
787 static Accessibility_DeviceEvent
788 spi_keystroke_from_x_key_event (XKeyEvent *x_key_event)
789 {
790   Accessibility_DeviceEvent key_event;
791   KeySym keysym;
792   const int cbuf_bytes = 20;
793   char cbuf [21];
794   int nbytes;
795
796   nbytes = XLookupString (x_key_event, cbuf, cbuf_bytes, &keysym, NULL);  
797   key_event.id = (dbus_int32_t)(keysym);
798   key_event.hw_code = (dbus_int16_t) x_key_event->keycode;
799   if (((XEvent *) x_key_event)->type == KeyPress)
800     {
801       key_event.type = Accessibility_KEY_PRESSED_EVENT;
802     }
803   else
804     {
805       key_event.type = Accessibility_KEY_RELEASED_EVENT;
806     } 
807   key_event.modifiers = (dbus_uint16_t)(x_key_event->state);
808   key_event.is_text = FALSE;
809   switch (keysym)
810     {
811       case ' ':
812         key_event.event_string = g_strdup ("space");
813         break;
814       case XK_Tab:
815         key_event.event_string = g_strdup ("Tab");
816         break;
817       case XK_BackSpace:
818         key_event.event_string = g_strdup ("Backspace");
819         break;
820       case XK_Return:
821         key_event.event_string = g_strdup ("Return");
822         break;
823       case XK_Home:
824         key_event.event_string = g_strdup ("Home");
825         break;
826       case XK_Page_Down:
827         key_event.event_string = g_strdup ("Page_Down");
828         break;
829       case XK_Page_Up:
830         key_event.event_string = g_strdup ("Page_Up");
831         break;
832       case XK_F1:
833         key_event.event_string = g_strdup ("F1");
834         break;
835       case XK_F2:
836         key_event.event_string = g_strdup ("F2");
837         break;
838       case XK_F3:
839         key_event.event_string = g_strdup ("F3");
840         break;
841       case XK_F4:
842         key_event.event_string = g_strdup ("F4");
843         break;
844       case XK_F5:
845         key_event.event_string = g_strdup ("F5");
846         break;
847       case XK_F6:
848         key_event.event_string = g_strdup ("F6");
849         break;
850       case XK_F7:
851         key_event.event_string = g_strdup ("F7");
852         break;
853       case XK_F8:
854         key_event.event_string = g_strdup ("F8");
855         break;
856       case XK_F9:
857         key_event.event_string = g_strdup ("F9");
858         break;
859       case XK_F10:
860         key_event.event_string = g_strdup ("F10");
861         break;
862       case XK_F11:
863         key_event.event_string = g_strdup ("F11");
864         break;
865       case XK_F12:
866         key_event.event_string = g_strdup ("F12");
867         break;
868       case XK_End:
869         key_event.event_string = g_strdup ("End");
870         break;
871       case XK_Escape:
872         key_event.event_string = g_strdup ("Escape");
873         break;
874       case XK_Up:
875         key_event.event_string = g_strdup ("Up");
876         break;
877       case XK_Down:
878         key_event.event_string = g_strdup ("Down");
879         break;
880       case XK_Left:
881         key_event.event_string = g_strdup ("Left");
882         break;
883       case XK_Right:
884         key_event.event_string = g_strdup ("Right");
885         break;
886       default:
887         if (nbytes > 0)
888           {
889             gunichar c;
890             cbuf[nbytes] = '\0'; /* OK since length is cbuf_bytes+1 */
891             key_event.event_string = g_strdup (cbuf);
892             c = keysym2ucs (keysym);
893             if (c > 0 && !g_unichar_iscntrl (c))
894               {
895                 key_event.is_text = TRUE; 
896                 /* incorrect for some composed chars? */
897               }
898           }
899         else
900           {
901             key_event.event_string = g_strdup ("");
902           }
903     }
904
905   key_event.timestamp = (dbus_uint32_t) x_key_event->time;
906 #ifdef SPI_KEYEVENT_DEBUG
907   {
908     char *pressed_str  = "pressed";
909     char *released_str = "released";
910     char *state_ptr;
911
912     if (key_event.type == Accessibility_KEY_PRESSED_EVENT)
913       state_ptr = pressed_str;
914     else
915       state_ptr = released_str;
916  
917     fprintf (stderr,
918              "Key %lu %s (%c), modifiers %d; string=%s [%x] %s\n",
919              (unsigned long) keysym,
920              state_ptr,
921              keysym ? (int) keysym : '*',
922              (int) x_key_event->state,
923              key_event.event_string,
924              key_event.event_string[0],
925              (key_event.is_text == TRUE) ? "(text)" : "(not text)");
926   }
927 #endif
928 #ifdef SPI_DEBUG
929   fprintf (stderr, "%s%c\n",
930      (x_key_event->state & Mod1Mask)?"Alt-":"",
931      ((x_key_event->state & ShiftMask)^(x_key_event->state & LockMask))?
932      g_ascii_toupper (keysym) : g_ascii_tolower (keysym));
933   fprintf (stderr, "serial: %x Time: %x\n", x_key_event->serial, x_key_event->time);
934 #endif /* SPI_DEBUG */
935   return key_event;     
936 }
937
938 static gboolean
939 spi_dec_x11_grab_key (SpiDEController *controller,
940                       guint key_val,
941                       Accessibility_ControllerEventMask mod_mask)
942 {
943   XGrabKey (spi_get_display (),
944             key_val,
945             mod_mask,
946             spi_get_root_window (),
947             True,
948             GrabModeSync,
949             GrabModeSync);
950   XSync (spi_get_display (), False);
951   return spi_clear_error_state ();
952 }
953
954 static void
955 spi_dec_x11_ungrab_key (SpiDEController *controller,
956                         guint key_val,
957                         Accessibility_ControllerEventMask mod_mask)
958 {
959   XUngrabKey (spi_get_display (),
960               key_val,
961               mod_mask,
962               spi_get_root_window ());
963 }
964
965 static unsigned int
966 xkb_get_slowkeys_delay (SpiDEController *controller)
967 {
968   unsigned int retval = 0;
969   DEControllerPrivateData *priv = controller->priv;
970 #ifdef HAVE_XKB
971 #ifdef XKB_HAS_GET_SLOW_KEYS_DELAY      
972   retval = XkbGetSlowKeysDelay (spi_get_display (),
973                                 XkbUseCoreKbd, &bounce_delay);
974 #else
975   if (!(priv->xkb_desc == (XkbDescPtr) BadAlloc || priv->xkb_desc == NULL))
976     {
977       Status s = XkbGetControls (spi_get_display (),
978                                  XkbAllControlsMask, priv->xkb_desc);
979       if (s == Success)
980         {
981          if (priv->xkb_desc->ctrls->enabled_ctrls & XkbSlowKeysMask)
982                  retval = priv->xkb_desc->ctrls->slow_keys_delay;
983         }
984     }
985 #endif
986 #endif
987 #ifdef SPI_XKB_DEBUG
988         fprintf (stderr, "SlowKeys delay: %d\n", (int) retval);
989 #endif
990         return retval;
991 }
992
993 static unsigned int
994 xkb_get_bouncekeys_delay (SpiDEController *controller)
995 {
996   unsigned int retval = 0;
997   DEControllerPrivateData *priv = controller->priv;
998 #ifdef HAVE_XKB
999 #ifdef XKB_HAS_GET_BOUNCE_KEYS_DELAY    
1000   retval = XkbGetBounceKeysDelay (spi_get_display (),
1001                                   XkbUseCoreKbd, &bounce_delay);
1002 #else
1003   if (!(priv->xkb_desc == (XkbDescPtr) BadAlloc || priv->xkb_desc == NULL))
1004     {
1005       Status s = XkbGetControls (spi_get_display (),
1006                                  XkbAllControlsMask, priv->xkb_desc);
1007       if (s == Success)
1008         {
1009           if (priv->xkb_desc->ctrls->enabled_ctrls & XkbBounceKeysMask)
1010                   retval = priv->xkb_desc->ctrls->debounce_delay;
1011         }
1012     }
1013 #endif
1014 #endif
1015 #ifdef SPI_XKB_DEBUG
1016   fprintf (stderr, "BounceKeys delay: %d\n", (int) retval);
1017 #endif
1018   return retval;
1019 }
1020
1021 static gboolean
1022 spi_dec_x11_synth_keycode_press (SpiDEController *controller,
1023                          unsigned int keycode)
1024 {
1025         unsigned int time = CurrentTime;
1026         unsigned int bounce_delay;
1027         unsigned int elapsed_msec;
1028         struct timeval tv;
1029         DEControllerPrivateData *priv = controller->priv;
1030
1031         spi_x_error_trap ();
1032         if (keycode == priv->last_release_keycode)
1033         {
1034                 bounce_delay = xkb_get_bouncekeys_delay (controller); 
1035                 if (bounce_delay)
1036                 {
1037                         gettimeofday (&tv, NULL);
1038                         elapsed_msec =
1039                                 (tv.tv_sec - priv->last_release_time.tv_sec) * 1000
1040                                 + (tv.tv_usec - priv->last_release_time.tv_usec) / 1000;
1041 #ifdef SPI_XKB_DEBUG                    
1042                         fprintf (stderr, "%d ms elapsed (%ld usec)\n", elapsed_msec,
1043                                  (long) (tv.tv_usec - priv->last_release_time.tv_usec));
1044 #endif
1045 #ifdef THIS_IS_BROKEN
1046                         if (elapsed_msec < bounce_delay)
1047                                 time = bounce_delay - elapsed_msec + 1;
1048 #else
1049                         time = bounce_delay + 10;
1050                         /* fudge for broken XTest */
1051 #endif
1052 #ifdef SPI_XKB_DEBUG                    
1053                         fprintf (stderr, "waiting %d ms\n", time);
1054 #endif
1055                 }
1056         }
1057         XTestFakeKeyEvent (spi_get_display (), keycode, True, time);
1058         priv->last_press_keycode = keycode;
1059         XFlush (spi_get_display ());
1060         XSync (spi_get_display (), False);
1061         gettimeofday (&priv->last_press_time, NULL);
1062         return TRUE;
1063 }
1064
1065 static gboolean
1066 spi_dec_x11_synth_keycode_release (SpiDEController *controller,
1067                            unsigned int keycode)
1068 {
1069         unsigned int time = CurrentTime;
1070         unsigned int slow_delay;
1071         unsigned int elapsed_msec;
1072         struct timeval tv;
1073         DEControllerPrivateData *priv = controller->priv;
1074
1075         spi_x_error_trap ();
1076         if (keycode == priv->last_press_keycode)
1077         {
1078                 slow_delay = xkb_get_slowkeys_delay (controller);
1079                 if (slow_delay)
1080                 {
1081                         gettimeofday (&tv, NULL);
1082                         elapsed_msec =
1083                                 (tv.tv_sec - priv->last_press_time.tv_sec) * 1000
1084                                 + (tv.tv_usec - priv->last_press_time.tv_usec) / 1000;
1085 #ifdef SPI_XKB_DEBUG                    
1086                         fprintf (stderr, "%d ms elapsed (%ld usec)\n", elapsed_msec,
1087                                  (long) (tv.tv_usec - priv->last_press_time.tv_usec));
1088 #endif
1089 #ifdef THIS_IS_BROKEN_DUNNO_WHY
1090                         if (elapsed_msec < slow_delay)
1091                                 time = slow_delay - elapsed_msec + 1;
1092 #else
1093                         time = slow_delay + 10;
1094                         /* our XTest seems broken, we have to add slop as above */
1095 #endif
1096 #ifdef SPI_XKB_DEBUG                    
1097                         fprintf (stderr, "waiting %d ms\n", time);
1098 #endif
1099                 }
1100         }
1101         XTestFakeKeyEvent (spi_get_display (), keycode, False, time);
1102         priv->last_release_keycode = keycode;
1103         XSync (spi_get_display (), False);
1104         gettimeofday (&priv->last_release_time, NULL);
1105         return TRUE;
1106 }
1107
1108 static gboolean
1109 spi_dec_x11_lock_modifiers (SpiDEController *controller, unsigned modifiers)
1110 {
1111     DEControllerPrivateData *priv = controller->priv;
1112     
1113     if (priv->have_xkb) {
1114         return XkbLockModifiers (spi_get_display (), XkbUseCoreKbd, 
1115                                   modifiers, modifiers);
1116     } else {
1117         int mod_index;
1118         if (xmkeymap==NULL)
1119           xmkeymap = XGetModifierMapping(spi_get_display ());
1120         for (mod_index=0;mod_index<8;mod_index++)
1121             if (modifiers & (1<<mod_index))
1122                 spi_dec_x11_synth_keycode_press(controller, xmkeymap->modifiermap[mod_index]);
1123         return TRUE;
1124     }
1125 }
1126
1127 static gboolean
1128 spi_dec_x11_unlock_modifiers (SpiDEController *controller, unsigned modifiers)
1129 {
1130     DEControllerPrivateData *priv = controller->priv;
1131     
1132     if (priv->have_xkb) {
1133         return XkbLockModifiers (spi_get_display (), XkbUseCoreKbd, 
1134                                   modifiers, 0);
1135     } else {
1136         int mod_index;
1137         if (xmkeymap==NULL)
1138           xmkeymap = XGetModifierMapping(spi_get_display ());
1139
1140         for (mod_index=0;mod_index<8;mod_index++)
1141             if (modifiers & (1<<mod_index))
1142                 spi_dec_x11_synth_keycode_release(controller, xmkeymap->modifiermap[mod_index]);
1143         return TRUE;
1144     }
1145 }
1146
1147 static KeySym
1148 keysym_for_unichar (SpiDEController *controller, gunichar unichar)
1149 {
1150         return (KeySym) ucs2keysym ((long) unichar);
1151 }
1152
1153 static gboolean
1154 spi_dec_x11_synth_keystring (SpiDEController *controller, guint synth_type, gint keycode, const char *keystring)
1155 {
1156         /* probably we need to create and inject an XIM handler eventually. */
1157         /* for now, try to match the string to existing 
1158          * keycode+modifier states. 
1159          */
1160         KeySym *keysyms;
1161         gint maxlen = 0;
1162         gunichar unichar = 0;
1163         gint i = 0;
1164         gboolean retval = TRUE;
1165         const gchar *c;
1166         KeySym keysym;
1167
1168         maxlen = strlen (keystring) + 1;
1169         keysyms = g_new0 (KeySym, maxlen);
1170         if (!(keystring && *keystring && g_utf8_validate (keystring, -1, &c))) { 
1171                 retval = FALSE;
1172         } 
1173         else {
1174 #ifdef SPI_DEBUG
1175                 fprintf (stderr, "[keystring synthesis attempted on %s]\n", keystring);
1176 #endif
1177                 while (keystring && (unichar = g_utf8_get_char (keystring))) {
1178                         char bytes[6];
1179                         gint mbytes;
1180                         
1181                         mbytes = g_unichar_to_utf8 (unichar, bytes);
1182                         bytes[mbytes] = '\0';
1183 #ifdef SPI_DEBUG
1184                         fprintf (stderr, "[unichar %s]", bytes);
1185 #endif
1186                         keysym = keysym_for_unichar (controller, unichar);
1187                         if (keysym == NoSymbol) {
1188 #ifdef SPI_DEBUG
1189                                 fprintf (stderr, "no keysym for %s", bytes);
1190 #endif
1191                                 retval = FALSE;
1192                                 break;
1193                         }
1194                         keysyms[i++] = keysym;
1195                         keystring = g_utf8_next_char (keystring); 
1196                 }
1197                 keysyms[i++] = 0;
1198                 XSynchronize (spi_get_display (), TRUE);
1199                 for (i = 0; keysyms[i]; ++i) {
1200                         if (!spi_dec_synth_keysym (controller, keysyms[i])) {
1201 #ifdef SPI_DEBUG
1202                                 fprintf (stderr, "could not synthesize %c\n",
1203                                          (int) keysyms[i]);
1204 #endif
1205                                 retval = FALSE;
1206                                 break;
1207                         }
1208                 }
1209                 XSynchronize (spi_get_display (), FALSE);
1210         }
1211         g_free (keysyms);
1212
1213         if (synth_type == Accessibility_KEY_SYM) {
1214                 keysym = keycode;
1215         }
1216         else {
1217                 keysym = XkbKeycodeToKeysym (spi_get_display (), keycode, 0, 0);
1218         }
1219         if (XkbKeysymToModifiers (spi_get_display (), keysym) == 0)  {
1220                 spi_dec_clear_unlatch_pending (controller);
1221         }
1222         return retval;
1223 }
1224
1225 #ifdef HAVE_XEVIE
1226 static Bool
1227 isEvent(Display *dpy, XEvent *event, char *arg)
1228 {
1229    return TRUE;
1230 }
1231
1232 static gboolean
1233 handle_io (GIOChannel *source,
1234            GIOCondition condition,
1235            gpointer data) 
1236 {
1237   SpiDEController *controller = (SpiDEController *) data;
1238     DEControllerPrivateData *priv = controller->priv;
1239   gboolean is_consumed = FALSE;
1240   XEvent ev;
1241
1242   while (XCheckIfEvent(priv->xevie_display, &ev, isEvent, NULL))
1243     {
1244       if (ev.type == KeyPress || ev.type == KeyRelease)
1245         is_consumed = spi_device_event_controller_forward_key_event (controller, &ev);
1246
1247       if (! is_consumed)
1248         XevieSendEvent(priv->xevie_display, &ev, XEVIE_UNMODIFIED);
1249     }
1250
1251   return TRUE;
1252 }
1253 #endif /* HAVE_XEVIE */
1254
1255 static void
1256 spi_dec_x11_init (SpiDEController *controller)
1257 {
1258   DEControllerPrivateData *priv = controller->priv;     
1259   spi_events_init (spi_get_display());
1260 #ifdef HAVE_XEVIE
1261   GIOChannel *ioc;
1262   int fd;
1263 #endif /* HAVE_XEVIE */
1264
1265   spi_events_init (spi_get_display ());
1266 #ifdef HAVE_XEVIE
1267   priv->xevie_display = XOpenDisplay(NULL);
1268
1269   if (XevieStart(priv->xevie_display) == TRUE)
1270     {
1271 #ifdef SPI_KEYEVENT_DEBUG
1272       fprintf (stderr, "XevieStart() success \n");
1273 #endif
1274       XevieSelectInput(priv->xevie_display, KeyPressMask | KeyReleaseMask);
1275
1276       fd = ConnectionNumber(priv->xevie_display);
1277       ioc = g_io_channel_unix_new (fd);
1278       g_io_add_watch (ioc, G_IO_IN | G_IO_HUP, handle_io, controller);
1279       g_io_channel_unref (ioc);
1280     }
1281   else
1282     {
1283 #ifdef SPI_KEYEVENT_DEBUG
1284       fprintf (stderr, "XevieStart() failed, only one client is allowed to do event int exception\n");
1285 #endif
1286     }
1287 #endif /* HAVE_XEVIE */
1288
1289   gettimeofday (&priv->last_press_time, NULL);
1290   gettimeofday (&priv->last_release_time, NULL);
1291   spi_controller_register_with_devices (controller);
1292
1293   spi_dec_init_mouse_listener (controller);
1294
1295   saved_controller = controller;
1296 }
1297
1298 static void
1299 spi_dec_x11_finalize (SpiDEController *controller)
1300 {
1301                 DEControllerPrivateData *priv = controller->priv;
1302   /* disconnect any special listeners, get rid of outstanding keygrabs */
1303   XUngrabKey (spi_get_display (), AnyKey, AnyModifier, DefaultRootWindow (spi_get_display ()));
1304
1305 #ifdef HAVE_XEVIE
1306   if (priv->xevie_display != NULL)
1307     {
1308       XevieEnd(priv->xevie_display);
1309 #ifdef SPI_KEYEVENT_DEBUG
1310       printf("XevieEnd(dpy) finished \n");
1311 #endif
1312     }
1313 #endif
1314
1315   if (priv->xkb_desc)
1316   XkbFreeKeyboard (priv->xkb_desc, 0, True);
1317   /* TODO: Should free the keymap */
1318 }
1319
1320 static gboolean
1321 spi_device_event_controller_forward_key_event (SpiDEController *controller,
1322                                                const XEvent    *event)
1323 {
1324                 DEControllerPrivateData *priv = controller->priv;
1325   Accessibility_DeviceEvent key_event;
1326   gboolean ret;
1327
1328   g_assert (event->type == KeyPress || event->type == KeyRelease);
1329
1330   key_event = spi_keystroke_from_x_key_event ((XKeyEvent *) event);
1331
1332   if (priv->xevie_display == NULL)
1333     spi_controller_update_key_grabs (controller, &key_event);
1334
1335   /* relay to listeners, and decide whether to consume it or not */
1336   ret = spi_controller_notify_keylisteners (controller, &key_event, TRUE);
1337   g_free(key_event.event_string);
1338   return ret;
1339 }
1340
1341
1342 static gboolean
1343 is_key_released (long code)
1344 {
1345   char keys[32];
1346   int down;
1347
1348   XQueryKeymap (spi_get_display (), keys);
1349   down = BIT (keys, code);
1350   return (down == 0);
1351 }
1352
1353 static gboolean
1354 check_release (gpointer data)
1355 {
1356   gboolean released;
1357   Accessibility_DeviceEvent *event = (Accessibility_DeviceEvent *)data;
1358   KeyCode code = event->hw_code;
1359
1360   released = is_key_released (code);
1361
1362   if (released)
1363     {
1364       check_release_handler = 0;
1365       event->type = Accessibility_KEY_RELEASED_EVENT;
1366       spi_controller_notify_keylisteners (saved_controller, event, TRUE);
1367     }
1368   return (released == 0);
1369 }
1370
1371 static void
1372 wait_for_release_event (XEvent          *event,
1373                                     SpiDEController *controller)
1374 {
1375   pressed_event = spi_keystroke_from_x_key_event ((XKeyEvent *) event);
1376   check_release_handler = g_timeout_add (CHECK_RELEASE_DELAY, check_release, &pressed_event);
1377   g_source_set_name_by_id (check_release_handler, "[at-spi2-core] check_release");
1378 }
1379
1380 static void
1381 spi_dec_x11_emit_modifier_event (SpiDEController *controller, guint prev_mask, 
1382                              guint current_mask)
1383 {
1384   dbus_uint32_t d1, d2;
1385
1386 #ifdef SPI_XKB_DEBUG
1387   fprintf (stderr, "MODIFIER CHANGE EVENT! %x to %x\n", 
1388            prev_mask, current_mask);
1389 #endif
1390
1391   /* set bits for the virtual modifiers like NUMLOCK */
1392   if (prev_mask & _numlock_physical_mask) 
1393     prev_mask |= SPI_KEYMASK_NUMLOCK;
1394   if (current_mask & _numlock_physical_mask) 
1395     current_mask |= SPI_KEYMASK_NUMLOCK;
1396
1397   d1 = prev_mask & key_modifier_mask;
1398   d2 = current_mask & key_modifier_mask;
1399       spi_dec_dbus_emit(controller, SPI_DBUS_INTERFACE_EVENT_KEYBOARD, "Modifiers", "", d1, d2);
1400 }
1401
1402 static void
1403 spi_dec_x11_generate_mouse_event (SpiDEController *controller,
1404                                   gint x,
1405                                   gint y,
1406                                   const char *eventName)
1407 {
1408   int button = 0;
1409   gboolean err = FALSE;
1410   Display *display = spi_get_display ();
1411
1412   switch (eventName[0])
1413     {
1414       case 'b':
1415         switch (eventName[1])
1416           {
1417           /* TODO: check number of buttons before parsing */
1418           case '1':
1419                     button = 1;
1420                     break;
1421           case '2':
1422                   button = 2;
1423                   break;
1424           case '3':
1425                   button = 3;
1426                   break;
1427           case '4':
1428                   button = 4;
1429                   break;
1430           case '5':
1431                   button = 5;
1432                   break;
1433           default:
1434                   err = TRUE;
1435           }
1436         if (!err)
1437           {
1438             if (x != -1 && y != -1)
1439               {
1440                 XTestFakeMotionEvent (display, DefaultScreen (display),
1441                                       x, y, 0);
1442               }
1443             XTestFakeButtonEvent (display, button, !(eventName[2] == 'r'), 0);
1444             if (eventName[2] == 'c')
1445               XTestFakeButtonEvent (display, button, FALSE, 1);
1446             else if (eventName[2] == 'd')
1447               {
1448               XTestFakeButtonEvent (display, button, FALSE, 1);
1449               XTestFakeButtonEvent (display, button, TRUE, 2);
1450               XTestFakeButtonEvent (display, button, FALSE, 3);
1451               }
1452           }
1453         break;
1454       case 'r': /* relative motion */ 
1455         XTestFakeRelativeMotionEvent (display, x, y, 0);
1456         break;
1457       case 'a': /* absolute motion */
1458         XTestFakeMotionEvent (display, DefaultScreen (display),
1459                               x, y, 0);
1460         break;
1461     }
1462 }
1463
1464 void
1465 spi_dec_setup_x11 (SpiDEControllerClass *klass)
1466 {
1467   GObjectClass *object_class = G_OBJECT_CLASS (klass);
1468
1469   klass->plat.get_keycode = spi_dec_x11_get_keycode;
1470   klass->plat.mouse_check = spi_dec_x11_mouse_check;
1471   klass->plat.synth_keycode_press = spi_dec_x11_synth_keycode_press;
1472   klass->plat.synth_keycode_release = spi_dec_x11_synth_keycode_release;
1473   klass->plat.lock_modifiers = spi_dec_x11_lock_modifiers;
1474   klass->plat.unlock_modifiers = spi_dec_x11_unlock_modifiers;
1475   klass->plat.synth_keystring = spi_dec_x11_synth_keystring;
1476   klass->plat.grab_key = spi_dec_x11_grab_key;
1477   klass->plat.ungrab_key = spi_dec_x11_ungrab_key;
1478   klass->plat.emit_modifier_event = spi_dec_x11_emit_modifier_event;
1479   klass->plat.generate_mouse_event = spi_dec_x11_generate_mouse_event;
1480
1481   klass->plat.init = spi_dec_x11_init;
1482   klass->plat.finalize = spi_dec_x11_finalize;
1483
1484   g_type_class_add_private (object_class, sizeof (DEControllerPrivateData));
1485 }