~elementary-os/elementaryos/os-patch-at-spi2-core-xenial

« back to all changes in this revision

Viewing changes to registryd/deviceeventcontroller.c

  • Committer: RabbitBot
  • Date: 2016-11-16 09:38:52 UTC
  • Revision ID: rabbitbot@elementary.io-20161116093852-xn6hcgpg5y25xooo
Initial import, version 2.18.3-4ubuntu1

Show diffs side-by-side

added added

removed removed

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