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