~ubuntu-branches/ubuntu/vivid/clutter-1.0/vivid-proposed

« back to all changes in this revision

Viewing changes to clutter/x11/clutter-input-device-core-x11.c

  • Committer: Package Import Robot
  • Author(s): Emilio Pozuelo Monfort
  • Date: 2014-03-26 11:51:28 UTC
  • mfrom: (1.5.1) (4.1.30 experimental)
  • Revision ID: package-import@ubuntu.com-20140326115128-timmbsde8734o6wz
Tags: 1.18.0-1
* New upstream release.
* debian/control.in:
  + Bump gtk-doc-tools build dependency.
  + Also break libcogl15.
  + Standards-Version is 3.9.5, no changes needed.
* debian/libclutter-1.0-0.symbols:
  + Drop a few symbols that were accidentally exported in the DSO because
    they had a clutter_ prefix but were not in the public headers.
  + Add one new symbol.
  + Drop unnecessary debian revisions from some symbols.
* debian/control.in,
  debian/rules,
  debian/libclutter-1.0-0.symbols:
  + Temporarily disable evdev input support. It was only enabled in 1.17.6-1
    in experimental and there is nothing using it yet, and I would like to
    wait a bit before uploading libinput to unstable as the ABI isn't stable
    yet.
* d/p/0001-wayland-Add-missing-CLUTTER_AVAILABLE-annotations.patch:
  + Add missing annotations so that a few symbols are exported in the DSO.

* Upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
#include "clutter-backend-x11.h"
34
34
#include "clutter-stage-x11.h"
35
35
 
36
 
#ifdef HAVE_XINPUT
37
 
#include <X11/extensions/XInput.h>
38
 
#endif
39
 
 
40
 
#define MAX_DEVICE_CLASSES      13
41
 
 
42
36
typedef struct _ClutterInputDeviceClass         ClutterInputDeviceX11Class;
43
37
 
44
38
/* a specific X11 input device */
46
40
{
47
41
  ClutterInputDevice device;
48
42
 
49
 
#ifdef HAVE_XINPUT
50
 
  XDevice *xdevice;
51
 
 
52
 
  XEventClass event_classes[MAX_DEVICE_CLASSES];
53
 
  int num_classes;
54
 
 
55
 
  int button_press_type;
56
 
  int button_release_type;
57
 
  int motion_notify_type;
58
 
  int state_notify_type;
59
 
  int key_press_type;
60
 
  int key_release_type;
61
 
#endif /* HAVE_XINPUT */
62
 
 
63
 
  gint *axis_data;
64
 
 
65
43
  int min_keycode;
66
44
  int max_keycode;
67
45
};
72
50
               clutter_input_device_x11,
73
51
               CLUTTER_TYPE_INPUT_DEVICE);
74
52
 
75
 
static void
76
 
clutter_input_device_x11_select_stage_events (ClutterInputDevice *device,
77
 
                                              ClutterStage       *stage,
78
 
                                              gint                event_mask)
79
 
{
80
 
#if HAVE_XINPUT
81
 
  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (device->backend);
82
 
  ClutterInputDeviceX11 *device_x11;
83
 
  ClutterStageX11 *stage_x11;
84
 
  XEventClass class;
85
 
  gint i;
86
 
 
87
 
  device_x11 = CLUTTER_INPUT_DEVICE_X11 (device);
88
 
 
89
 
  stage_x11 = CLUTTER_STAGE_X11 (_clutter_stage_get_window (stage));
90
 
 
91
 
  i = 0;
92
 
 
93
 
  if (event_mask & ButtonPressMask)
94
 
    {
95
 
      DeviceButtonPress (device_x11->xdevice,
96
 
                         device_x11->button_press_type,
97
 
                         class);
98
 
      if (class != 0)
99
 
        device_x11->event_classes[i++] = class;
100
 
 
101
 
      DeviceButtonPressGrab (device_x11->xdevice, 0, class);
102
 
      if (class != 0)
103
 
        device_x11->event_classes[i++] = class;
104
 
    }
105
 
 
106
 
  if (event_mask & ButtonReleaseMask)
107
 
    {
108
 
      DeviceButtonRelease (device_x11->xdevice,
109
 
                           device_x11->button_release_type,
110
 
                           class);
111
 
      if (class != 0)
112
 
        device_x11->event_classes[i++] = class;
113
 
    }
114
 
 
115
 
  if (event_mask & PointerMotionMask)
116
 
    {
117
 
      DeviceMotionNotify (device_x11->xdevice,
118
 
                          device_x11->motion_notify_type,
119
 
                          class);
120
 
      if (class != 0)
121
 
        device_x11->event_classes[i++] = class;
122
 
 
123
 
      DeviceStateNotify (device_x11->xdevice,
124
 
                         device_x11->state_notify_type,
125
 
                         class);
126
 
      if (class != 0)
127
 
        device_x11->event_classes[i++] = class;
128
 
    }
129
 
 
130
 
  if (event_mask & KeyPressMask)
131
 
    {
132
 
      DeviceKeyPress (device_x11->xdevice,
133
 
                      device_x11->key_press_type,
134
 
                      class);
135
 
      if (class != 0)
136
 
        device_x11->event_classes[i++] = class;
137
 
    }
138
 
 
139
 
  if (event_mask & KeyReleaseMask)
140
 
    {
141
 
      DeviceKeyRelease (device_x11->xdevice,
142
 
                        device_x11->key_release_type,
143
 
                        class);
144
 
      if (class != 0)
145
 
        device_x11->event_classes[i++] = class;
146
 
    }
147
 
 
148
 
  device_x11->num_classes = i;
149
 
 
150
 
  XSelectExtensionEvent (backend_x11->xdpy,
151
 
                         stage_x11->xwin,
152
 
                         device_x11->event_classes,
153
 
                         device_x11->num_classes);
154
 
#endif /* HAVE_XINPUT */
155
 
}
156
 
 
157
 
static void
158
 
clutter_input_device_x11_dispose (GObject *gobject)
159
 
{
160
 
  ClutterInputDeviceX11 *device_x11 = CLUTTER_INPUT_DEVICE_X11 (gobject);
161
 
 
162
 
#ifdef HAVE_XINPUT
163
 
  if (device_x11->xdevice)
164
 
    {
165
 
      ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (gobject);
166
 
      ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (device->backend);
167
 
 
168
 
      XCloseDevice (backend_x11->xdpy, device_x11->xdevice);
169
 
      device_x11->xdevice = NULL;
170
 
    }
171
 
#endif /* HAVE_XINPUT */
172
 
 
173
 
  g_free (device_x11->axis_data);
174
 
 
175
 
  G_OBJECT_CLASS (clutter_input_device_x11_parent_class)->dispose (gobject);
176
 
}
177
 
 
178
 
static void
179
 
clutter_input_device_x11_constructed (GObject *gobject)
180
 
{
181
 
#ifdef HAVE_XINPUT
182
 
  ClutterInputDeviceX11 *device_x11 = CLUTTER_INPUT_DEVICE_X11 (gobject);
183
 
  ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (gobject);
184
 
  ClutterBackendX11 *backend_x11;
185
 
 
186
 
  backend_x11 = CLUTTER_BACKEND_X11 (device->backend);
187
 
 
188
 
  clutter_x11_trap_x_errors ();
189
 
 
190
 
  device_x11->xdevice = XOpenDevice (backend_x11->xdpy, device->id);
191
 
 
192
 
  if (clutter_x11_untrap_x_errors ())
193
 
    {
194
 
      g_warning ("Device '%s' cannot be opened",
195
 
                 clutter_input_device_get_device_name (device));
196
 
    }
197
 
#endif /* HAVE_XINPUT */
198
 
 
199
 
  if (G_OBJECT_CLASS (clutter_input_device_x11_parent_class)->constructed)
200
 
    G_OBJECT_CLASS (clutter_input_device_x11_parent_class)->constructed (gobject);
201
 
}
202
 
 
203
53
static gboolean
204
54
clutter_input_device_x11_keycode_to_evdev (ClutterInputDevice *device,
205
55
                                           guint hardware_keycode,
217
67
static void
218
68
clutter_input_device_x11_class_init (ClutterInputDeviceX11Class *klass)
219
69
{
220
 
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
221
70
  ClutterInputDeviceClass *device_class = CLUTTER_INPUT_DEVICE_CLASS (klass);
222
71
 
223
 
  gobject_class->constructed = clutter_input_device_x11_constructed;
224
 
  gobject_class->dispose = clutter_input_device_x11_dispose;
225
 
 
226
 
  device_class->select_stage_events = clutter_input_device_x11_select_stage_events;
227
72
  device_class->keycode_to_evdev = clutter_input_device_x11_keycode_to_evdev;
228
73
}
229
74
 
231
76
clutter_input_device_x11_init (ClutterInputDeviceX11 *self)
232
77
{
233
78
}
234
 
 
235
 
void
236
 
_clutter_input_device_x11_set_keycodes (ClutterInputDeviceX11 *device_x11,
237
 
                                        int                    min_keycode,
238
 
                                        int                    max_keycode)
239
 
{
240
 
  device_x11->min_keycode = min_keycode;
241
 
  device_x11->max_keycode = max_keycode;
242
 
}
243
 
 
244
 
int
245
 
_clutter_input_device_x11_get_min_keycode (ClutterInputDeviceX11 *device_x11)
246
 
{
247
 
  return device_x11->min_keycode;
248
 
}
249
 
 
250
 
int
251
 
_clutter_input_device_x11_get_max_keycode (ClutterInputDeviceX11 *device_x11)
252
 
{
253
 
  return device_x11->max_keycode;
254
 
}
255
 
 
256
 
#ifdef HAVE_XINPUT
257
 
static void
258
 
update_axes (ClutterInputDeviceX11 *device_x11,
259
 
             guint                  n_axes,
260
 
             gint                   first_axis,
261
 
             gint                  *axes_data)
262
 
{
263
 
  ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_x11);
264
 
  gint i;
265
 
 
266
 
  if (device_x11->axis_data == NULL)
267
 
    {
268
 
      device_x11->axis_data =
269
 
        g_new0 (gint, clutter_input_device_get_n_axes (device));
270
 
    }
271
 
 
272
 
  for (i = 0; i < n_axes; i++)
273
 
    device_x11->axis_data[first_axis + i] = axes_data[i];
274
 
}
275
 
 
276
 
static gdouble *
277
 
translate_axes (ClutterInputDeviceX11 *device_x11,
278
 
                ClutterStageX11       *stage_x11,
279
 
                gfloat                *event_x,
280
 
                gfloat                *event_y)
281
 
{
282
 
  ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_x11);
283
 
  gint root_x, root_y;
284
 
  gint n_axes, i;
285
 
  gdouble x, y;
286
 
  gdouble *retval;
287
 
 
288
 
  if (!_clutter_stage_x11_get_root_coords (stage_x11, &root_x, &root_y))
289
 
    return NULL;
290
 
 
291
 
  x = y = 0.0f;
292
 
  n_axes = clutter_input_device_get_n_axes (device);
293
 
 
294
 
  retval = g_new0 (gdouble, n_axes);
295
 
 
296
 
  for (i = 0; i < n_axes; i++)
297
 
    {
298
 
      ClutterInputAxis axis;
299
 
 
300
 
      axis = clutter_input_device_get_axis (device, i);
301
 
      switch (axis)
302
 
        {
303
 
        case CLUTTER_INPUT_AXIS_X:
304
 
        case CLUTTER_INPUT_AXIS_Y:
305
 
          _clutter_x11_input_device_translate_screen_coord (device,
306
 
                                                            root_x, root_y,
307
 
                                                            i,
308
 
                                                            device_x11->axis_data[i],
309
 
                                                            &retval[i]);
310
 
          if (axis == CLUTTER_INPUT_AXIS_X)
311
 
            x = retval[i];
312
 
          else if (axis == CLUTTER_INPUT_AXIS_Y)
313
 
            y = retval[i];
314
 
          break;
315
 
 
316
 
        default:
317
 
          _clutter_input_device_translate_axis (device, i,
318
 
                                                device_x11->axis_data[i],
319
 
                                                &retval[i]);
320
 
          break;
321
 
        }
322
 
    }
323
 
 
324
 
  if (event_x)
325
 
    *event_x = x;
326
 
 
327
 
  if (event_y)
328
 
    *event_y = y;
329
 
 
330
 
  return retval;
331
 
}
332
 
 
333
 
/*
334
 
 * translate_state:
335
 
 * @state: the keyboard state of the core device
336
 
 * @device_state: the button state of the device
337
 
 *
338
 
 * Trivially translates the state and the device state into a
339
 
 * single bitmask.
340
 
 */
341
 
static guint
342
 
translate_state (guint state,
343
 
                 guint device_state)
344
 
{
345
 
  return device_state | (state & 0xff);
346
 
}
347
 
#endif /* HAVE_XINPUT */
348
 
 
349
 
gboolean
350
 
_clutter_input_device_x11_translate_xi_event (ClutterInputDeviceX11 *device_x11,
351
 
                                              ClutterStageX11       *stage_x11,
352
 
                                              XEvent                *xevent,
353
 
                                              ClutterEvent          *event)
354
 
{
355
 
#ifdef HAVE_XINPUT
356
 
  ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_x11);
357
 
 
358
 
  if ((xevent->type == device_x11->button_press_type) ||
359
 
      (xevent->type == device_x11->button_release_type))
360
 
    {
361
 
      XDeviceButtonEvent *xdbe = (XDeviceButtonEvent *) xevent;
362
 
 
363
 
      event->button.type = event->type =
364
 
        (xdbe->type == device_x11->button_press_type) ? CLUTTER_BUTTON_PRESS
365
 
                                                      : CLUTTER_BUTTON_RELEASE;
366
 
      event->button.device = device;
367
 
      event->button.time = xdbe->time;
368
 
      event->button.button = xdbe->button;
369
 
      event->button.modifier_state =
370
 
        translate_state (xdbe->state, xdbe->device_state);
371
 
 
372
 
      update_axes (device_x11,
373
 
                   xdbe->axes_count,
374
 
                   xdbe->first_axis,
375
 
                   xdbe->axis_data);
376
 
 
377
 
      event->button.axes = translate_axes (device_x11, stage_x11,
378
 
                                           &event->button.x,
379
 
                                           &event->button.y);
380
 
 
381
 
      _clutter_stage_x11_set_user_time (stage_x11, event->button.time);
382
 
 
383
 
      return TRUE;
384
 
    }
385
 
 
386
 
  if ((xevent->type == device_x11->key_press_type) ||
387
 
      (xevent->type == device_x11->key_release_type))
388
 
    {
389
 
      XDeviceKeyEvent *xdke = (XDeviceKeyEvent *) xevent;
390
 
 
391
 
      if (xdke->keycode < device_x11->min_keycode ||
392
 
          xdke->keycode >= device_x11->max_keycode)
393
 
        {
394
 
          g_warning ("Invalid device key code received: %d", xdke->keycode);
395
 
          return FALSE;
396
 
        }
397
 
 
398
 
      clutter_input_device_get_key (device,
399
 
                                    xdke->keycode - device_x11->min_keycode,
400
 
                                    &event->key.keyval,
401
 
                                    &event->key.modifier_state);
402
 
      if (event->key.keyval == 0)
403
 
        return FALSE;
404
 
 
405
 
      event->key.type = event->type =
406
 
        (xdke->type == device_x11->key_press_type) ? CLUTTER_KEY_PRESS
407
 
                                                   : CLUTTER_KEY_RELEASE;
408
 
      event->key.time = xdke->time;
409
 
      event->key.modifier_state |=
410
 
        translate_state (xdke->state, xdke->device_state);
411
 
      event->key.device = device;
412
 
 
413
 
#if 0
414
 
      if ((event->key.keyval >= 0x20) && (event->key.keyval <= 0xff))
415
 
        {
416
 
          event->key.unicode = (gunichar) event->key.keyval;
417
 
        }
418
 
#endif
419
 
 
420
 
      _clutter_stage_x11_set_user_time (stage_x11, event->key.time);
421
 
 
422
 
      return TRUE;
423
 
    }
424
 
 
425
 
  if (xevent->type == device_x11->motion_notify_type)
426
 
    {
427
 
      XDeviceMotionEvent *xdme = (XDeviceMotionEvent *) xevent;
428
 
 
429
 
      event->motion.type = event->type = CLUTTER_MOTION;
430
 
      event->motion.time = xdme->time;
431
 
      event->motion.modifier_state =
432
 
        translate_state (xdme->state, xdme->device_state);
433
 
      event->motion.device = device;
434
 
 
435
 
      event->motion.axes =
436
 
        g_new0 (gdouble, clutter_input_device_get_n_axes (device));
437
 
 
438
 
      update_axes (device_x11,
439
 
                   xdme->axes_count,
440
 
                   xdme->first_axis,
441
 
                   xdme->axis_data);
442
 
 
443
 
      event->motion.axes = translate_axes (device_x11, stage_x11,
444
 
                                           &event->motion.x,
445
 
                                           &event->motion.y);
446
 
 
447
 
      return TRUE;
448
 
    }
449
 
 
450
 
  if (xevent->type == device_x11->state_notify_type)
451
 
    {
452
 
      XDeviceStateNotifyEvent *xdse = (XDeviceStateNotifyEvent *) xevent;
453
 
      XInputClass *input_class = (XInputClass *) xdse->data;
454
 
      gint n_axes = clutter_input_device_get_n_axes (device);
455
 
      int i;
456
 
 
457
 
      for (i = 0; i < xdse->num_classes; i++)
458
 
        {
459
 
          if (input_class->class == ValuatorClass)
460
 
            {
461
 
              int *axis_data = ((XValuatorState *) input_class)->valuators;
462
 
 
463
 
              update_axes (device_x11, n_axes, 0, axis_data);
464
 
            }
465
 
 
466
 
          input_class =
467
 
            (XInputClass *)(((char *) input_class) + input_class->length);
468
 
        }
469
 
    }
470
 
#endif /* HAVE_XINPUT */
471
 
 
472
 
  return FALSE;
473
 
}