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