~ubuntu-branches/ubuntu/precise/xserver-xorg-input-evdev/precise-proposed

« back to all changes in this revision

Viewing changes to debian/patches/101-gestures.patch

  • Committer: Bazaar Package Importer
  • Author(s): Chase Douglas
  • Date: 2010-08-20 16:47:09 UTC
  • Revision ID: james.westby@ubuntu.com-20100820164709-nd4hnpqe1dmpwjei
Tags: 1:2.3.2-6ubuntu1
* Add gesture support
  - Add debian/patches/100-fix-touchup-problem-on-touchpads.patch and
    debian/patches/101-gestures.patch
  - debian/rules:
    - add configure option to enable utouch-grail support
* Replace xserver-xorg-input-gevdev as it was a temporary solution
* Depend on newer utouch-grail for udebs and ABI changes
* Build depend on latest xserver-xorg-dev for serverminver dependency

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
--- a/configure.ac
 
2
+++ b/configure.ac
 
3
@@ -67,6 +67,22 @@ AC_SUBST([sdkdir])
 
4
 # Checks for header files.
 
5
 AC_HEADER_STDC
 
6
 
 
7
+AC_ARG_ENABLE(utouch-grail, AS_HELP_STRING([--enable-grail], [Build with utouch-grail gesture support (default: auto)]), [GRAIL=$enableval], [GRAIL=auto])
 
8
+PKG_CHECK_MODULES(GRAIL, utouch-grail, [have_grail=yes], [have_grail=no])
 
9
+if test "x$GRAIL" = xauto; then
 
10
+        GRAIL="$have_grail"
 
11
+fi
 
12
+if test "x$GRAIL" = xyes; then
 
13
+        if test "x$have_grail" = xno; then
 
14
+                AC_MSG_ERROR([Grail build explicitly requested, but required modules not found.])
 
15
+        fi
 
16
+        AC_DEFINE(USE_GRAIL, 1, Whether to use grail or not)
 
17
+        AC_DEFINE(GESTURES, 1, Needed to interpret xorg headers properly)
 
18
+else
 
19
+        AC_DEFINE(USE_GRAIL, 0, Whether to use grail or not)
 
20
+fi
 
21
+AM_CONDITIONAL(USE_GRAIL, [test "x$GRAIL" = xyes])
 
22
+
 
23
 DRIVER_NAME=evdev
 
24
 AC_SUBST([DRIVER_NAME])
 
25
 
 
26
--- a/src/Makefile.am
 
27
+++ b/src/Makefile.am
 
28
@@ -27,13 +27,18 @@
 
29
 AM_CFLAGS = $(XORG_CFLAGS)
 
30
 
 
31
 @DRIVER_NAME@_drv_la_LTLIBRARIES = @DRIVER_NAME@_drv.la
 
32
-@DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version
 
33
+@DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version @GRAIL_LIBS@
 
34
 @DRIVER_NAME@_drv_ladir = @inputdir@
 
35
 
 
36
 INCLUDES=-I$(top_srcdir)/include/
 
37
 
 
38
-@DRIVER_NAME@_drv_la_SOURCES = @DRIVER_NAME@.c \
 
39
-                               @DRIVER_NAME@.h \
 
40
+if USE_GRAIL
 
41
+GRAIL_SRC=evdev-grail.c evdev-grail.h
 
42
+endif
 
43
+
 
44
+@DRIVER_NAME@_drv_la_SOURCES = evdev.c \
 
45
+                               evdev.h \
 
46
+                               $(GRAIL_SRC) \
 
47
                                emuMB.c \
 
48
                                emuWheel.c \
 
49
                                draglock.c
 
50
--- /dev/null
 
51
+++ b/src/evdev-grail.c
 
52
@@ -0,0 +1,313 @@
 
53
+/*
 
54
+ * Copyright © 2010 Canonical, Ltd.
 
55
+ *
 
56
+ * Permission to use, copy, modify, distribute, and sell this software
 
57
+ * and its documentation for any purpose is hereby granted without
 
58
+ * fee, provided that the above copyright notice appear in all copies
 
59
+ * and that both that copyright notice and this permission notice
 
60
+ * appear in supporting documentation, and that the name of Red Hat
 
61
+ * not be used in advertising or publicity pertaining to distribution
 
62
+ * of the software without specific, written prior permission.  Red
 
63
+ * Hat makes no representations about the suitability of this software
 
64
+ * for any purpose.  It is provided "as is" without express or implied
 
65
+ * warranty.
 
66
+ *
 
67
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 
68
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
 
69
+ * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 
70
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
 
71
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 
72
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 
73
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
74
+ *
 
75
+ * Authors:
 
76
+ *     Chase Douglas (chase.douglas@canonical.com)
 
77
+ */
 
78
+
 
79
+/* So we can get at the right data in xorg/windowstr.h */
 
80
+
 
81
+#ifdef HAVE_CONFIG_H
 
82
+#include "config.h"
 
83
+#endif
 
84
+
 
85
+#include <X11/Xatom.h>
 
86
+#include <xf86.h>
 
87
+#include <xf86Xinput.h>
 
88
+#include <exevents.h>
 
89
+#include <windowstr.h>
 
90
+#include <xorg/os.h>
 
91
+
 
92
+#include <evdev-properties.h>
 
93
+#include "evdev.h"
 
94
+#include "evdev-grail.h"
 
95
+#include "gestureproto.h"
 
96
+
 
97
+/* Copied from evdev.c, will be in evdev.h when xserver 1.9 is merged */
 
98
+#define EVDEV_RELATIVE_EVENTS   (1 << 2)
 
99
+#define EVDEV_TOUCHPAD          (1 << 4)
 
100
+
 
101
+static WindowPtr CommonAncestor(WindowPtr a, WindowPtr b)
 
102
+{
 
103
+    WindowPtr c;
 
104
+
 
105
+    if (a == b)
 
106
+        return a;
 
107
+
 
108
+    for (b = b; b; b = b->parent)
 
109
+        for (c = a; c; c = c->parent)
 
110
+            if (c == b)
 
111
+                return b;
 
112
+
 
113
+    return NullWindow;
 
114
+}
 
115
+
 
116
+static WindowPtr GetWindowForGestures(struct grail *grail,
 
117
+                                      const struct grail_coord *contacts,
 
118
+                                      int num_contacts)
 
119
+{
 
120
+    WindowPtr window = NULL;
 
121
+    int i;
 
122
+
 
123
+    for (i = 0; i < num_contacts; i++)
 
124
+    {
 
125
+        float screen_x = contacts[i].x;
 
126
+        float screen_y = contacts[i].y;
 
127
+        WindowPtr this_window;
 
128
+
 
129
+        this_window = xf86CoordinatesToWindow(screen_x, screen_y, 0);
 
130
+        if (!this_window)
 
131
+            return NullWindow;
 
132
+
 
133
+        if (!window)
 
134
+            window = this_window;
 
135
+        else
 
136
+            window = CommonAncestor(window, this_window);
 
137
+    }
 
138
+
 
139
+    return window;
 
140
+}
 
141
+
 
142
+static int GetClients(struct grail *grail,
 
143
+                     struct grail_client_info *clients, int max_clients,
 
144
+                     const struct grail_coord *contacts, int num_contacts,
 
145
+                     const grail_mask_t *types, int type_bytes)
 
146
+{
 
147
+    WindowPtr child_window;
 
148
+    WindowPtr window;
 
149
+    WindowPtr root_window = NULL;
 
150
+    InputInfoPtr pInfo = grail->priv;
 
151
+    EvdevPtr pEvdev = pInfo->private;
 
152
+    int j;
 
153
+    int found_match = 0;
 
154
+    int num_clients = 0;
 
155
+    int type;
 
156
+
 
157
+    if (max_clients <= 0)
 
158
+        return 0;
 
159
+
 
160
+    if (pEvdev->flags & (EVDEV_RELATIVE_EVENTS | EVDEV_TOUCHPAD))
 
161
+    {
 
162
+        DeviceIntPtr master = pInfo->dev->u.master;
 
163
+        struct grail_coord cursor_coord;
 
164
+
 
165
+        /* If this mouse isn't hooked up to a cursor, don't do anything */
 
166
+        if (!master)
 
167
+            return 0;
 
168
+
 
169
+        cursor_coord.x = master->last.valuators[0];
 
170
+        cursor_coord.y = master->last.valuators[1];
 
171
+
 
172
+        child_window = GetWindowForGestures(grail, &cursor_coord, 1);
 
173
+    } else
 
174
+        child_window = GetWindowForGestures(grail, contacts, num_contacts);
 
175
+
 
176
+    if (!child_window)
 
177
+        return 0;
 
178
+
 
179
+    memset(clients, 0, sizeof(struct grail_client_info) * max_clients);
 
180
+
 
181
+    /*
 
182
+     * Traverse the window hierarchy looking for a window with a client
 
183
+     * selecting for one of the recognized gestures.
 
184
+     *
 
185
+     * All clients of the top most window with a match will receive events if
 
186
+     * they have selected for gestures that have been recognized, even if they
 
187
+     * have selected for different gestures between them.
 
188
+     *
 
189
+     * Once any gesture is matched on a window, propagation through the window
 
190
+     * hierarchy ends.
 
191
+     */
 
192
+    for (window = child_window; window && !found_match; window = window->parent)
 
193
+    {
 
194
+        /* No client selected for gestures on this window */
 
195
+        if (!wGestureMasks(window))
 
196
+            continue;
 
197
+
 
198
+        /* For each recognized gesture */
 
199
+        grail_mask_foreach(type, types, type_bytes)
 
200
+        {
 
201
+            /* Check if any client selected for this gesture on the window */
 
202
+            if (BitIsOn(wGestureMasks(window)->mask, type))
 
203
+            {
 
204
+                GestureClientsPtr client;
 
205
+
 
206
+                if (!root_window)
 
207
+                    for (root_window = window; root_window->parent;
 
208
+                         root_window = root_window->parent);
 
209
+
 
210
+                /* For each client that selected for gestures on this window */
 
211
+                for (client = wGestureMasks(window)->clients; client;
 
212
+                     client = client->next)
 
213
+                {
 
214
+                     /*
 
215
+                      * Check if this client selected for this gesture. Request
 
216
+                      * may be for this device or all devices.
 
217
+                      */
 
218
+                     if (BitIsOn(client->gestureMask[pInfo->dev->id], type) ||
 
219
+                         BitIsOn(client->gestureMask[0], type))
 
220
+                     {
 
221
+                         /*
 
222
+                          * Find this client in the clients array passed back to
 
223
+                          * the caller.
 
224
+                          */
 
225
+                         for (j = 0; j < num_clients; j++)
 
226
+                             if (clients[j].id.client ==
 
227
+                                 CLIENT_ID(client->resource))
 
228
+                                 break;
 
229
+
 
230
+                         /* Check if the client exists in the array yet */
 
231
+                         if (j >= num_clients)
 
232
+                         {
 
233
+                             /* We ran out of room in the array, return error */
 
234
+                             if (num_clients >= max_clients)
 
235
+                                 return -1;
 
236
+                             /* Set up new client in array */
 
237
+                             clients[j].id.client = CLIENT_ID(client->resource);
 
238
+                             clients[j].id.root = root_window->drawable.id;
 
239
+                             clients[j].id.child = child_window->drawable.id;
 
240
+                             clients[j].id.event = window->drawable.id;
 
241
+                             num_clients++;
 
242
+                         }
 
243
+
 
244
+                         /* Set this gesture bit in the client's gesture mask */
 
245
+                         SetBit(clients[j].mask, type);
 
246
+                     }
 
247
+                }
 
248
+
 
249
+                /* A match has been found, stop propagating */
 
250
+                found_match = 1;
 
251
+            }
 
252
+        }
 
253
+    }
 
254
+
 
255
+    return num_clients;
 
256
+}
 
257
+
 
258
+static void GrailEvent(struct grail *grail, const struct input_event *ev)
 
259
+{
 
260
+    InputInfoPtr pInfo = (InputInfoPtr)grail->priv;
 
261
+    EvdevProcessEvent(pInfo, (struct input_event *)ev);
 
262
+}
 
263
+
 
264
+static void GrailGesture(struct grail *grail, const struct grail_event *ev)
 
265
+{
 
266
+    InputInfoPtr pInfo = grail->priv;
 
267
+    EvdevPtr pEvdev = pInfo->private;
 
268
+    GestureEvent event;
 
269
+    float props[DIM_GRAIL_PROP];
 
270
+    int len = sizeof(GestureEvent) + ev->nprop * sizeof(grail_prop_t);
 
271
+
 
272
+    /* Client could have disappeared by now */
 
273
+    if (!clients[ev->client_id.client])
 
274
+        return;
 
275
+
 
276
+    event.type = GenericEvent;
 
277
+    event.extension = GestureReqCode;
 
278
+    event.sequenceNumber = clients[ev->client_id.client]->sequence;
 
279
+    event.evtype = 0;
 
280
+    event.time = GetTimeInMillis();
 
281
+    event.length = (len - sizeof(xEvent)) / 4;
 
282
+    event.gesture_id = ev->id;
 
283
+    event.gesture_type = ev->type;
 
284
+    event.device_id = pInfo->dev->id;
 
285
+    event.root = ev->client_id.root;
 
286
+    event.event = ev->client_id.event;
 
287
+    event.child = ev->client_id.child;
 
288
+    event.status = ev->status;
 
289
+    event.num_props = ev->nprop;
 
290
+
 
291
+    /* Override event focus point if this is a relative device */
 
292
+    if (pEvdev->flags & (EVDEV_RELATIVE_EVENTS | EVDEV_TOUCHPAD))
 
293
+    {
 
294
+        DeviceIntPtr master = pInfo->dev->u.master;
 
295
+
 
296
+        /* If this mouse isn't hooked up to a cursor, don't do anything */
 
297
+        if (!master)
 
298
+            return;
 
299
+
 
300
+        /* Note: Master device valuators are in screen coordinates */
 
301
+        event.focus_x = master->last.valuators[0];
 
302
+        event.focus_y = master->last.valuators[1];
 
303
+    } else {
 
304
+        event.focus_x = ev->pos.x;
 
305
+        event.focus_y = ev->pos.y;
 
306
+    }
 
307
+
 
308
+    memcpy(props, ev->prop, ev->nprop * sizeof(grail_prop_t));
 
309
+
 
310
+    WriteToClient(clients[ev->client_id.client], sizeof(GestureEvent), &event);
 
311
+    WriteToClient(clients[ev->client_id.client],
 
312
+                  sizeof(float) * event.num_props, props);
 
313
+}
 
314
+
 
315
+int
 
316
+GrailOpen(InputInfoPtr pInfo)
 
317
+{
 
318
+    EvdevPtr pEvdev = pInfo->private;
 
319
+
 
320
+    pEvdev->grail = malloc(sizeof(struct grail));
 
321
+    if (!pEvdev->grail) {
 
322
+        xf86Msg(X_ERROR, "evdev-grail: failed to allocate grail structure\n");
 
323
+        return -1;
 
324
+    }
 
325
+
 
326
+    memset(pEvdev->grail, 0, sizeof(struct grail));
 
327
+    pEvdev->grail->get_clients = GetClients;
 
328
+    pEvdev->grail->event = GrailEvent;
 
329
+    pEvdev->grail->gesture = GrailGesture;
 
330
+    pEvdev->grail->priv = pInfo;
 
331
+
 
332
+    if (grail_open(pEvdev->grail, pInfo->fd)) {
 
333
+        xf86Msg(X_INFO,
 
334
+                "evdev-grail: failed to open grail, no gesture support\n");
 
335
+        free(pEvdev->grail);
 
336
+        pEvdev->grail = NULL;
 
337
+        return -1;
 
338
+    }
 
339
+
 
340
+    {
 
341
+        struct grail_coord min;
 
342
+        struct grail_coord max;
 
343
+
 
344
+        min.x = screenInfo.screens[0]->x;
 
345
+        min.y = screenInfo.screens[0]->y;
 
346
+        max.x = min.x + screenInfo.screens[0]->width;
 
347
+        max.y = min.y + screenInfo.screens[0]->height;
 
348
+
 
349
+        grail_set_bbox(pEvdev->grail, &min, &max);
 
350
+    }
 
351
+
 
352
+    return 0;
 
353
+}
 
354
+
 
355
+void
 
356
+GrailClose(InputInfoPtr pInfo)
 
357
+{
 
358
+    EvdevPtr pEvdev = pInfo->private;
 
359
+
 
360
+    if (pEvdev->grail) {
 
361
+        grail_close(pEvdev->grail, pInfo->fd);
 
362
+        free(pEvdev->grail);
 
363
+        pEvdev->grail = NULL;
 
364
+    }
 
365
+}
 
366
--- /dev/null
 
367
+++ b/src/evdev-grail.h
 
368
@@ -0,0 +1,9 @@
 
369
+#ifndef EVDEV_GRAIL_H_
 
370
+#define EVDEV_GRAIL_H_
 
371
+
 
372
+#include <grail.h>
 
373
+
 
374
+extern int GrailOpen(InputInfoPtr pInfo);
 
375
+extern void GrailClose(InputInfoPtr pInfo);
 
376
+
 
377
+#endif /* _EVDEV_GRAIL_H_ */
 
378
--- a/src/evdev.c
 
379
+++ b/src/evdev.c
 
380
@@ -78,6 +78,13 @@
 
381
 #endif
 
382
 /* end compat */
 
383
 
 
384
+#if USE_GRAIL
 
385
+#include "evdev-grail.h"
 
386
+#else
 
387
+#define GrailOpen(pInfo)
 
388
+#define GrailClose(pInfo)
 
389
+#endif
 
390
+
 
391
 #define ArrayLength(a) (sizeof(a) / (sizeof((a)[0])))
 
392
 
 
393
 /* evdev flags */
 
394
@@ -736,7 +743,7 @@ EvdevProcessSyncEvent(InputInfoPtr pInfo
 
395
  * Process the events from the device; nothing is actually posted to the server
 
396
  * until an EV_SYN event is received.
 
397
  */
 
398
-static void
 
399
+void
 
400
 EvdevProcessEvent(InputInfoPtr pInfo, struct input_event *ev)
 
401
 {
 
402
     switch (ev->type) {
 
403
@@ -771,7 +778,12 @@ EvdevReadInput(InputInfoPtr pInfo)
 
404
 
 
405
     while (len == sizeof(ev))
 
406
     {
 
407
-        len = read(pInfo->fd, &ev, sizeof(ev));
 
408
+#if USE_GRAIL
 
409
+        if (pEvdev->grail)
 
410
+            len = grail_pull(pEvdev->grail, pInfo->fd);
 
411
+        else
 
412
+#endif
 
413
+            len = read(pInfo->fd, &ev, sizeof(ev));
 
414
         if (len <= 0)
 
415
         {
 
416
             if (errno == ENODEV) /* May happen after resume */
 
417
@@ -794,6 +806,11 @@ EvdevReadInput(InputInfoPtr pInfo)
 
418
             break;
 
419
         }
 
420
 
 
421
+#if USE_GRAIL
 
422
+        if (pEvdev->grail)
 
423
+               return;
 
424
+#endif
 
425
+
 
426
         /* The kernel promises that we always only read a complete
 
427
          * event, so len != sizeof ev is an error. */
 
428
         if (len % sizeof(ev[0])) {
 
429
@@ -1214,7 +1231,7 @@ EvdevAddAbsClass(DeviceIntPtr device)
 
430
     memset(pEvdev->old_vals, -1, num_axes * sizeof(int));
 
431
     atoms = xalloc(pEvdev->num_vals * sizeof(Atom));
 
432
 
 
433
-    for (axis = ABS_X; axis <= ABS_MAX; axis++) {
 
434
+    for (axis = ABS_X; axis <= ABS_MISC; axis++) {
 
435
         pEvdev->axis_map[axis] = -1;
 
436
         if (!TestBit(axis, pEvdev->abs_bitmask))
 
437
             continue;
 
438
@@ -1234,7 +1251,7 @@ EvdevAddAbsClass(DeviceIntPtr device)
 
439
                                        GetMotionHistorySize(), Absolute))
 
440
         return !Success;
 
441
 
 
442
-    for (axis = ABS_X; axis <= ABS_MAX; axis++) {
 
443
+    for (axis = ABS_X; axis <= ABS_MISC; axis++) {
 
444
         int axnum = pEvdev->axis_map[axis];
 
445
         if (axnum == -1)
 
446
             continue;
 
447
@@ -1611,7 +1628,6 @@ EvdevOn(DeviceIntPtr device)
 
448
     return Success;
 
449
 }
 
450
 
 
451
-
 
452
 static int
 
453
 EvdevProc(DeviceIntPtr device, int what)
 
454
 {
 
455
@@ -1657,6 +1673,7 @@ EvdevProc(DeviceIntPtr device, int what)
 
456
             close(pInfo->fd);
 
457
             pInfo->fd = -1;
 
458
         }
 
459
+        GrailClose(pInfo);
 
460
         EvdevRemoveDevice(pInfo);
 
461
         pEvdev->min_maj = 0;
 
462
        break;
 
463
@@ -1927,6 +1944,8 @@ EvdevProbe(InputInfoPtr pInfo)
 
464
         xf86Msg(X_INFO, "%s: Found absolute axes\n", pInfo->name);
 
465
         pEvdev->flags |= EVDEV_ABSOLUTE_EVENTS;
 
466
 
 
467
+       GrailOpen(pInfo);
 
468
+
 
469
         if ((TestBit(ABS_X, pEvdev->abs_bitmask) &&
 
470
              TestBit(ABS_Y, pEvdev->abs_bitmask))) {
 
471
             xf86Msg(X_INFO, "%s: Found x and y absolute axes\n", pInfo->name);
 
472
--- a/src/evdev.h
 
473
+++ b/src/evdev.h
 
474
@@ -178,8 +178,14 @@ typedef struct {
 
475
     /* Event queue used to defer keyboard/button events until EV_SYN time. */
 
476
     int                     num_queue;
 
477
     EventQueueRec           queue[EVDEV_MAXQUEUE];
 
478
+
 
479
+#if USE_GRAIL
 
480
+    struct grail *grail;
 
481
+#endif
 
482
 } EvdevRec, *EvdevPtr;
 
483
 
 
484
+void EvdevProcessEvent(InputInfoPtr pInfo, struct input_event *ev);
 
485
+
 
486
 /* Event posting functions */
 
487
 void EvdevQueueKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value);
 
488
 void EvdevQueueButtonEvent(InputInfoPtr pInfo, int button, int value);
 
489
--- /dev/null
 
490
+++ b/src/gestureproto.h
 
491
@@ -0,0 +1,132 @@
 
492
+/*
 
493
+ * Copyright © 2010 Canonical, Ltd.
 
494
+ *
 
495
+ * Permission is hereby granted, free of charge, to any person obtaining a
 
496
+ * copy of this software and associated documentation files (the "Software"),
 
497
+ * to deal in the Software without restriction, including without limitation
 
498
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 
499
+ * and/or sell copies of the Software, and to permit persons to whom the
 
500
+ * Software is furnished to do so, subject to the following conditions:
 
501
+ *
 
502
+ * The above copyright notice and this permission notice (including the next
 
503
+ * paragraph) shall be included in all copies or substantial portions of the
 
504
+ * Software.
 
505
+ *
 
506
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
507
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
508
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 
509
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
510
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 
511
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
512
+ * DEALINGS IN THE SOFTWARE.
 
513
+ *
 
514
+ * Authors: Chase Douglas <chase.douglas@canonical.com>
 
515
+ *
 
516
+ */
 
517
+
 
518
+#ifndef _GESTUREPROTO_H_
 
519
+#define _GESTUREPROTO_H_
 
520
+
 
521
+#include <stdint.h>
 
522
+#include <X11/X.h>
 
523
+
 
524
+#define Window  uint32_t
 
525
+#define Time    uint32_t
 
526
+
 
527
+#define X_GestureQueryVersion                1
 
528
+#define X_GestureSelectEvents                2
 
529
+#define X_GestureGetSelectedEvents           3
 
530
+
 
531
+#define GESTUREREQUESTS (X_GestureGetSelectedEvents - X_GestureQueryVersion + 1)
 
532
+
 
533
+#define GestureAllDevices 0
 
534
+
 
535
+/**
 
536
+ * Used to select for events on a given window.
 
537
+ * Struct is followed by (mask_len * CARD8), with each bit set representing
 
538
+ * the event mask for the given type. A mask bit represents an event type if
 
539
+ * (mask == (1 << type)).
 
540
+ */
 
541
+typedef struct {
 
542
+    uint16_t    device_id;       /**< Device id to select for        */
 
543
+    uint16_t    mask_len;        /**< Length of mask in 4 byte units */
 
544
+} GestureEventMask;
 
545
+
 
546
+typedef struct {
 
547
+    uint8_t     reqType;                /**< Gesture extension major code */
 
548
+    uint8_t     ReqType;                /**< Always ::X_GestureQueryVersion */
 
549
+    uint16_t    length;                 /**< Length in 4 byte units */
 
550
+    uint16_t    major_version;
 
551
+    uint16_t    minor_version;
 
552
+} GestureQueryVersionReq;
 
553
+
 
554
+typedef struct {
 
555
+    uint8_t     repType;                /**< ::X_Reply */
 
556
+    uint8_t     RepType;                /**< Always ::X_GestureQueryVersion */
 
557
+    uint16_t    sequenceNumber;
 
558
+    uint32_t    length;
 
559
+    uint16_t    major_version;
 
560
+    uint16_t    minor_version;
 
561
+    uint32_t    pad1;
 
562
+    uint32_t    pad2;
 
563
+    uint32_t    pad3;
 
564
+    uint32_t    pad4;
 
565
+    uint32_t    pad5;
 
566
+} GestureQueryVersionReply;
 
567
+
 
568
+typedef struct {
 
569
+    uint8_t     reqType;                /**< Gesture extension major code */
 
570
+    uint8_t     ReqType;                /**< Always ::X_GestureSelectEvents */
 
571
+    uint16_t    length;                 /**< Length in 4 byte units */
 
572
+    Window      window;
 
573
+    GestureEventMask mask;
 
574
+} GestureSelectEventsReq;
 
575
+
 
576
+typedef struct {
 
577
+    uint8_t     reqType;                /**< Gesture extension major code */
 
578
+    uint8_t     ReqType;                /**< Always ::X_GestureGetSelectedEvents */
 
579
+    uint16_t    length;                 /**< Length in 4 byte units */
 
580
+    Window      window;
 
581
+} GestureGetSelectedEventsReq;
 
582
+
 
583
+typedef struct {
 
584
+    uint8_t     repType;                /**< Gesture extension major opcode */
 
585
+    uint8_t     RepType;                /**< Always ::X_GestureGetSelectedEvents */
 
586
+    uint16_t    sequenceNumber;
 
587
+    uint32_t    length;
 
588
+    uint16_t    num_masks;              /**< Number of GestureEventMask structs
 
589
+                                             trailing the reply */
 
590
+    uint16_t    pad0;
 
591
+    uint32_t    pad1;
 
592
+    uint32_t    pad2;
 
593
+    uint32_t    pad3;
 
594
+    uint32_t    pad4;
 
595
+    uint32_t    pad5;
 
596
+} GestureGetSelectedEventsReply;
 
597
+
 
598
+typedef struct
 
599
+{
 
600
+    uint8_t     type;                   /**< Always GenericEvent */
 
601
+    uint8_t     extension;              /**< Gesture extension offset */
 
602
+    uint16_t    sequenceNumber;         /**< Xevent sequence number */
 
603
+    uint32_t    length;                 /**< Length in 4 byte uints */
 
604
+    uint16_t    evtype;                 /**< X generic event type */
 
605
+    uint16_t    gesture_id;             /**< Unique ID for gesture */
 
606
+    uint16_t    gesture_type;           /**< Gesture type (zoom, rotate, etc.) */
 
607
+    uint16_t    device_id;              /**< Device that generated this gesture */
 
608
+    Time        time;                   /**< Time of gesture event */
 
609
+    Window      root;                   /**< Root window event occurred on */
 
610
+    Window      event;                  /**< Window selecting this event for a client */
 
611
+    Window      child;                  /**< Top-most window of gesture event */
 
612
+/* └──────── 32 byte boundary ────────┘ */
 
613
+    float       focus_x;                /**< Always window coords, 16.16 fixed point */
 
614
+    float       focus_y;                /**< Relative to event window */
 
615
+    uint16_t    status;                 /**< Gesture event status */
 
616
+    uint16_t    num_props;               /**< Number of properties for gesture event */
 
617
+/* └──── Gesture properties below ────┘ */
 
618
+} GestureEvent;
 
619
+
 
620
+#undef Window
 
621
+#undef Time
 
622
+
 
623
+#endif /* _GESTUREPROTO_H_ */