Merge lp:~bregma/geis/lp-733296 into lp:geis

Proposed by Stephen M. Webb
Status: Merged
Merged at revision: 116
Proposed branch: lp:~bregma/geis/lp-733296
Merge into: lp:geis
Diff against target: 921 lines (+541/-38)
14 files modified
ChangeLog (+85/-0)
doc/Doxyfile (+1/-1)
doc/geistest.1 (+18/-1)
include/geis/geis.h (+36/-4)
libutouch-geis/backend/test_fixture/geis_backend_test_fixture.c (+3/-1)
libutouch-geis/backend/xcb/geis_xcb_backend.c (+191/-4)
libutouch-geis/geis.c (+1/-1)
libutouch-geis/geis_attr.c (+5/-1)
libutouch-geis/geis_device.c (+38/-13)
libutouch-geis/geis_v1.c (+105/-5)
testsuite/geis1/check_gesture_attrs.c (+0/-1)
testsuite/geis2/check_device.c (+15/-1)
testsuite/geis2/check_subscription.c (+1/-1)
testsuite/geistest/geistest.c (+42/-4)
To merge this branch: bzr merge lp:~bregma/geis/lp-733296
Reviewer Review Type Date Requested Status
Chase Douglas (community) Approve
Henrik Rydberg (community) Needs Information
Review via email: mp+53161@code.launchpad.net

Description of the change

Implements multi-touch device enumeration in the GEIS v1 and v2 APIs through the XCB back end.

Includes an extension to the geistest tool for verification. Unit tests are not possible since this change is an integration with an external data source, although existing unit tests for the API still apply.

To post a comment you must log in.
lp:~bregma/geis/lp-733296 updated
122. By Stephen M. Webb

Initialized an uninitialized variable.

Revision history for this message
Chase Douglas (chasedouglas) wrote :

We will probably want a 5th device type: multi-finger devices. These devices are like partial multitouch devices, but they don't even give us a bounding box.

I think we should also make a comment in the header that partial devices may only report drag, pinch, and tap (no rotate), and that multi-finger devices may only report drag and tap (no pinch nor rotate). Both of these devices can still report the current and max number of touches (will usually be a max of 3 for these devices). The comments for these devices should also note that they are a subclass of dependent devices.

A comment should be made that if GEIS_DEVICE_ATTRIBUTE_TOUCHES == 0, then the maximum number of touches is unknown.

Other than the issues above, and any changes that need to be taken to support them, I'm happy about the additions! In the interest of time and because multi-finger/partial-mt devices won't actually be supported in Natty, it would be good enough to add them to the header files for now and leave the implemenation of the class additions to later.

review: Needs Fixing
Revision history for this message
Henrik Rydberg (rydberg) wrote :

Concurring with previous speaker, otherwise looks OK.

Revision history for this message
Chase Douglas (chasedouglas) wrote :

I should clarify one point. While multi-finger devices won't be supported in Natty, partial-mt devices should be. In fact, they already work today. We should do whatever fixups are needed for them.

lp:~bregma/geis/lp-733296 updated
123. By Stephen M. Webb

Refined input device class handling.

Revision history for this message
Stephen M. Webb (bregma) wrote :

I believe I have addressed all the concerns with the latest commit to this merge request. Please take another look-see and check if this meets you approval(s).

Revision history for this message
Henrik Rydberg (rydberg) wrote :

What about tablets, in the old meaning? Those are direct in terms of representing a screen, but still dependent in that they need a pointer to operate. From the kernel, we get DIRECT, POINTER, ABS_MT and SEMI_MT, basically. From DIRECT and POINTER, we can form three types (touchscreen, touchpad, tablet), and then we have ABS_MT and SEMI_MT to give multitouch, semi-mt or just multi-finger.

review: Needs Information
lp:~bregma/geis/lp-733296 updated
124. By Stephen M. Webb

Replaced device class with explicit attributes.

Revision history for this message
Chase Douglas (chasedouglas) wrote :

I'm ok with this proposal. It drops the semi-multitouch and multi-finger properties, but we can add them in if/when we find someone who really wants to know. Comments:

1. I'd like to see an either/or comment in the header file, like "True if device is a direct touch device (e.g. a touchscreen), false if device is an indirect touch device (e.g. a touchpad)." This makes it clearer what it means when the attribute is false.

2. All attributes should be set at all times. The independent pointer attribute isn't set when it's false.

Thanks for proposing the change!

review: Needs Fixing
lp:~bregma/geis/lp-733296 updated
125. By Stephen M. Webb

Set new device attrs to false always when they're not true.

Revision history for this message
Chase Douglas (chasedouglas) wrote :

Stephen said on irc that he'll fix the header comments up in a further patchset. I'm good now :).

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ChangeLog'
2--- ChangeLog 2011-03-09 19:46:45 +0000
3+++ ChangeLog 2011-03-16 22:13:52 +0000
4@@ -1,3 +1,88 @@
5+2011-03-16 Stephen M. Webb <stephen.webb@canonical.com>
6+
7+ Replaced device class with explicit attributes.
8+
9+ * include/geis/geis.h (GEIS_DEVICE_CLASS_*) removed
10+ (GEIS_DEVICE_ATTRIBUTE_DIRECT_TOUCH): added
11+ (GEIS_DEVICE_ATTRIBUTE_INDEPENDENT_TOUCH): added
12+ * libutouch-geis/backend/xcb/geis_xcb_backend.c:
13+ (_map_xi2_mode_to_geis_device_attrs): replaced function
14+ _map_xi2_mode_to_geis_device_class
15+ * testsuite/geis2/check_device.c: added checks for new attributes
16+
17+2011-03-16 Stephen M. Webb <stephen.webb@canonical.com>
18+
19+ Refinement of input device class handling.
20+
21+ * include/geis/geis.h (GEIS_DEVICE_CLASS_UNKNOWN): new device class
22+ (GEIS_DEVICE_CLASS_TOUCH_MULTIFINGER): new device class
23+ * libutouch-geis/backend/xcb/geis_xcb_backend.c
24+ (_map_xi2_mode_to_geis_device_class): new function
25+ (_report_an_xcb_device): used it
26+
27+2011-03-13 Stephen M. Webb <stephen.webb@canonical.com>
28+
29+ Initialized an uninitialized variable.
30+
31+ * libutouch-geis/geis_v1.c (_v1_input_callback): initialized device_id
32+
33+2011-03-12 Stephen M. Webb <stephen.webb@canonical.com>
34+
35+ Added spcifying devices to geistest.
36+
37+ * libutouch-geis/backend/xcb/geis_xcb_backend.c: added -d swicth
38+ * doc/geistest.1: documented its use
39+
40+2011-03-12 Stephen M. Webb <stephen.webb@canonical.com>
41+
42+ Added proper device ID filtering for GEIS v1.
43+
44+ * libutouch-geis/geis_v1.c (_subscribe_device): Added filter for device ID.
45+
46+2011-03-11 Stephen M. Webb <stephen.webb@canonical.com>
47+
48+ Implement device enumeration (LP: #733296)
49+
50+ * libutouch-geis/backend/xcb/geis_xcb_backend.c (_report_an_xcb_device): new
51+ (_report_xcb_devices): imlemented
52+ * libutouch-geis/geis_device.c (geis_device_new): made "id" an attr
53+ (geis_device_id): same
54+ (geis_device_add_attr): implemented missing function
55+ * libutouch-geis/geis_v1.c (_v1_input_callback): new function
56+ (geis_input_devices): implemented
57+ * testsuite/geis1/check_gesture_attrs.c: removed debug message
58+ * testsuite/geistest/geistest.c (input_device_added): added a dump
59+
60+2011-03-11 Stephen M. Webb <stephen.webb@canonical.com>
61+
62+ Fix a lifetime issue with string attrs.
63+
64+ * libutouch_ges/geis_attr.c (geis_attr_new): dup all strings
65+ (geis_attr_delete): free strings
66+
67+2011-03-11 Stephen M. Webb <stephen.webb@canonical.com>
68+
69+ Added new device symbolic constants due to a change in the GEIS spec.
70+
71+ * include/geis/geis.h (GEIS_DEVICE_ATTRIBUTE_CLASS): new constant
72+ (GEIS_DEVICE_ATTRIBUTE_TOUCHES): new constant
73+ (GEIS_DEVICE_CLASS_TOUCH_DIRECT): new constant
74+ (GEIS_DEVICE_CLASS_TOUCH_DEPENDENT): new constant
75+ (GEIS_DEVICE_CLASS_TOUCH_INDEPENDENT): new constant
76+ (GEIS_DEVICE_CLASS_TOUCH_PARTIAL): new constant
77+ * testsuite/geis2/check_device.c: added tests for the above
78+
79+2011-03-11 Stephen M. Webb <stephen.webb@canonical.com>
80+
81+ Added a required symbolic constant for device events.
82+
83+ * include/geis/geis.h (GEIS_EVENT_ATTRIBUTE_DEVICE): new symbol
84+ (GEIS_DEVICE_ATTRIBUTE_ID): new symbol
85+ * libutouch-geis/backend/test_fixture/geis_backend_test_fixture.c: used them
86+ * libutouch-geis/geis.c: used them
87+ * testsuite/geis2/check_device.c (geis_device_types): checked them
88+ * testsuite/geis2/check_subscription.c: used them
89+
90 2011-03-08 Stephen M. Webb <stephen.webb@canonical.com>
91
92 Released utouch-geis v2.0.3.
93
94=== modified file 'doc/Doxyfile'
95--- doc/Doxyfile 2010-12-01 12:23:29 +0000
96+++ doc/Doxyfile 2011-03-16 22:13:52 +0000
97@@ -1398,7 +1398,7 @@
98 # undefined via #undef or recursively expanded use the := operator
99 # instead of the = operator.
100
101-PREDEFINED = GEIS_API=
102+PREDEFINED = GEIS_API=""
103
104 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
105 # this tag can be used to specify a list of macro names that should be expanded.
106
107=== modified file 'doc/geistest.1'
108--- doc/geistest.1 2011-02-28 17:40:46 +0000
109+++ doc/geistest.1 2011-03-16 22:13:52 +0000
110@@ -8,6 +8,10 @@
111 .B -w
112 .I windowid
113 .B ]
114+.B [
115+.B -d
116+.I deviceid
117+.B ]
118 .br
119
120 .SH DESCRIPTION
121@@ -23,13 +27,26 @@
122 .I windowId
123 of a specific window to associate with gestures.
124 Particularly useful with touchscreens.
125+If this argument is not set, the default action is to read gestures on all
126+windows.
127
128 The
129 .I windowId
130 can be determined using the program
131 .BR xwininfo .
132
133-If this argument is not set, the default action is to read gestures on all windows.
134+.IP -d
135+Specifies the
136+.I deviceId
137+of a specific input device to be tested for multi-touch gestural input.
138+If this argument is not set, the default action is to listen to multi-touch
139+input on all devices. This argument may be used more than once to specify
140+multiple input devices.
141+
142+The
143+.I deviceId
144+can be determined using the program
145+.BR xinput .
146
147 .SH ENVIRONMENT
148 .IP GEIS_DEBUG
149
150=== modified file 'include/geis/geis.h'
151--- include/geis/geis.h 2011-02-21 14:23:43 +0000
152+++ include/geis/geis.h 2011-03-16 22:13:52 +0000
153@@ -128,8 +128,6 @@
154 #define GEIS_TOUCH_ATTRIBUTE_X "touch x"
155 #define GEIS_TOUCH_ATTRIBUTE_Y "touch y"
156
157-#define GEIS_DEVICE_ATTRIBUTE_NAME "device name"
158-
159 #define GEIS_REGION_ATTRIBUTE_WINDOWID "windowid"
160
161 #define GEIS_FALSE 0
162@@ -855,8 +853,36 @@
163 * @defgroup geis2_device Gesture Input Devices (GEIS v2.0)
164 * @{
165 */
166-
167-/**
168+#define GEIS_EVENT_ATTRIBUTE_DEVICE "device"
169+
170+/**
171+ * @def GEIS_DEVICE_ATTRIBUTE_NAME
172+ * The name of the input device. Not guaranteed unique.
173+ *
174+ * @def GEIS_DEVICE_ATTRIBUTE_ID
175+ * The unique integer ID of the device. Guaranteed unique within a Geis
176+ * instance.
177+ *
178+ * @def GEIS_DEVICE_ATTRIBUTE_TOUCHES
179+ * The simultaneous number of touches the device claims to be able to detect if
180+ * it is a multi-touch device. A value of zero indicates the maximum number of
181+ * touches can not be determined.
182+ *
183+ * @def GEIS_DEVICE_ATTRIBUTE_DIRECT_TOUCH
184+ * Indicates if this is a direct touch device (eg. touchscreen).
185+ *
186+ * @def GEIS_DEVICE_ATTRIBUTE_INDEPENDENT_TOUCH
187+ * Indicates if this is an independent touch device (eg. Apple MagicMouse).
188+ */
189+#define GEIS_DEVICE_ATTRIBUTE_NAME "device name"
190+#define GEIS_DEVICE_ATTRIBUTE_ID "device id"
191+#define GEIS_DEVICE_ATTRIBUTE_TOUCHES "device touches"
192+#define GEIS_DEVICE_ATTRIBUTE_DIRECT_TOUCH "direct touch"
193+#define GEIS_DEVICE_ATTRIBUTE_INDEPENDENT_TOUCH "independent touch"
194+
195+
196+/**
197+ * @class GeisDevice
198 * An opaque pointer type representing a gesture-capable input device.
199 *
200 * GeisDevice objects are created by the GEIS API and are reference counted.
201@@ -869,6 +895,7 @@
202
203 /**
204 * Adds a reference count to a device.
205+ * @public @memberof GeisDevice
206 *
207 * @param[in] device The device.
208 *
209@@ -880,6 +907,7 @@
210
211 /**
212 * Removes a reference count from a device.
213+ * @public @memberof GeisDevice
214 *
215 * @param[in] device The device.
216 *
217@@ -890,6 +918,7 @@
218
219 /**
220 * Gets the name of the input device.
221+ * @memberof GeisDevice
222 *
223 * @param[in] device The device.
224 */
225@@ -897,6 +926,7 @@
226
227 /**
228 * Gets the system identifier of the iput device.
229+ * @memberof GeisDevice
230 *
231 * @param[in] device The device.
232 *
233@@ -907,6 +937,7 @@
234
235 /**
236 * Gets the number of attributes of the device.
237+ * @memberof GeisDevice
238 *
239 * @param[in] device The device.
240 */
241@@ -914,6 +945,7 @@
242
243 /**
244 * Gets the indicated attribute of the device.
245+ * @memberof GeisDevice
246 *
247 * @param[in] device The device.
248 */
249
250=== modified file 'libutouch-geis/backend/test_fixture/geis_backend_test_fixture.c'
251--- libutouch-geis/backend/test_fixture/geis_backend_test_fixture.c 2011-03-09 18:59:00 +0000
252+++ libutouch-geis/backend/test_fixture/geis_backend_test_fixture.c 2011-03-16 22:13:52 +0000
253@@ -137,7 +137,9 @@
254 {
255 GeisDevice device = geis_device_new("abs-test-device", 0);
256 GeisEvent event = geis_event_new(GEIS_EVENT_DEVICE_AVAILABLE);
257- GeisAttr attr = geis_attr_new("geis-device", GEIS_ATTR_TYPE_POINTER, device);
258+ GeisAttr attr = geis_attr_new(GEIS_EVENT_ATTRIBUTE_DEVICE,
259+ GEIS_ATTR_TYPE_POINTER,
260+ device);
261 geis_event_add_attr(event, attr);
262 geis_post_event(tf->tf_geis, event);
263 }
264
265=== modified file 'libutouch-geis/backend/xcb/geis_xcb_backend.c'
266--- libutouch-geis/backend/xcb/geis_xcb_backend.c 2011-02-27 21:41:00 +0000
267+++ libutouch-geis/backend/xcb/geis_xcb_backend.c 2011-03-16 22:13:52 +0000
268@@ -23,6 +23,7 @@
269 #include "geis_attr.h"
270 #include "geis_backend_protected.h"
271 #include "geis_class.h"
272+#include "geis_device.h"
273 #include "geis_event.h"
274 #include "geis_frame.h"
275 #include "geis_filter.h"
276@@ -33,8 +34,10 @@
277 #include "grail_gestures.h"
278 #include <grail.h>
279 #include <grail-types.h>
280+#include <stdio.h>
281 #include <string.h>
282 #include "xcb_gesture.h"
283+#include <X11/extensions/XInput2.h>
284 #include <X11/X.h>
285 #include <X11/Xlib-xcb.h>
286 #include <xcb/xcb.h>
287@@ -100,6 +103,45 @@
288 };
289
290
291+static void
292+_map_xi2_mode_to_geis_device_attrs(int xi2_mode, GeisDevice geis_device)
293+{
294+ GeisAttr device_attr;
295+ GeisBoolean is_direct = GEIS_FALSE;
296+ GeisBoolean is_independent = GEIS_FALSE;
297+
298+ if (xi2_mode == XIDirectTouch)
299+ is_direct = GEIS_TRUE;
300+
301+ device_attr = geis_attr_new(GEIS_DEVICE_ATTRIBUTE_DIRECT_TOUCH,
302+ GEIS_ATTR_TYPE_BOOLEAN,
303+ &is_direct);
304+ if (!device_attr)
305+ {
306+ geis_error("failed to create device attr");
307+ }
308+ else
309+ {
310+ geis_device_add_attr(geis_device, device_attr);
311+ }
312+
313+ if (xi2_mode == XIIndependentPointer)
314+ is_independent = GEIS_TRUE;
315+
316+ device_attr = geis_attr_new(GEIS_DEVICE_ATTRIBUTE_INDEPENDENT_TOUCH,
317+ GEIS_ATTR_TYPE_BOOLEAN,
318+ &is_independent);
319+ if (!device_attr)
320+ {
321+ geis_error("failed to create device attr");
322+ }
323+ else
324+ {
325+ geis_device_add_attr(geis_device, device_attr);
326+ }
327+}
328+
329+
330 static int
331 _verify_xcb_version(xcb_connection_t *xcb_connection)
332 {
333@@ -348,8 +390,8 @@
334 GeisString name = geis_attr_name(attr);
335 GeisFilterOperation op = geis_filter_term_operation(term);
336
337- if (0 == strcmp(name, GEIS_DEVICE_ATTRIBUTE_NAME)
338- && op == GEIS_FILTER_OP_EQ)
339+ if (0 == strcmp(name, GEIS_DEVICE_ATTRIBUTE_ID)
340+ && op == GEIS_FILTER_OP_EQ)
341 {
342 if (*device_count >= MAX_NUM_DEVICES)
343 {
344@@ -637,7 +679,7 @@
345 * Tears down an XCB-specific subscription instance.
346 */
347 static GeisStatus
348-_unsubscribe(GeisBackend be, GeisSubscription sub)
349+_unsubscribe(GeisBackend be __attribute__((unused)), GeisSubscription sub)
350 {
351 GeisStatus status = GEIS_STATUS_SUCCESS;
352 XcbGestureSub xsub = geis_subscription_pdata(sub);
353@@ -646,10 +688,155 @@
354 }
355
356
357-/** @todo implement this */
358+/*
359+ * Report a gesture-capable device.
360+ */
361+static void
362+_report_an_xcb_device(GeisXcbBackend be, XIDeviceInfo *xcb_device)
363+{
364+ int class_index;
365+ GeisDevice geis_device;
366+ GeisAttr device_attr;
367+ GeisEvent device_event;
368+
369+ device_event = geis_event_new(GEIS_EVENT_DEVICE_AVAILABLE);
370+ if (!device_event)
371+ {
372+ geis_error("failed to create device-available event");
373+ goto final_exit;
374+ }
375+
376+ geis_device = geis_device_new(xcb_device->name, xcb_device->deviceid);
377+ if (!geis_device)
378+ {
379+ geis_error("failed to create device");
380+ goto unroll_event;
381+ }
382+
383+ device_attr = geis_attr_new(GEIS_EVENT_ATTRIBUTE_DEVICE,
384+ GEIS_ATTR_TYPE_POINTER,
385+ geis_device);
386+ if (!device_attr)
387+ {
388+ geis_error("failed to create device attr");
389+ goto unroll_device;
390+ }
391+ geis_event_add_attr(device_event, device_attr);
392+
393+ for (class_index = 0; class_index < xcb_device->num_classes; ++class_index)
394+ {
395+ XIAnyClassInfo *any = xcb_device->classes[class_index];
396+ if (any->type == XITouchClass)
397+ {
398+ XITouchClassInfo *v = (XITouchClassInfo *)any;
399+ _map_xi2_mode_to_geis_device_attrs(v->mode, geis_device);
400+ geis_debug("touch class for device %d \"%s\": mode %d num_touches %d",
401+ xcb_device->deviceid, xcb_device->name,
402+ v->mode, v->num_touches);
403+
404+ device_attr = geis_attr_new(GEIS_DEVICE_ATTRIBUTE_TOUCHES,
405+ GEIS_ATTR_TYPE_INTEGER,
406+ &v->num_touches);
407+ if (!device_attr)
408+ {
409+ geis_error("failed to create device attr");
410+ }
411+ else
412+ {
413+ geis_device_add_attr(geis_device, device_attr);
414+ }
415+ }
416+ else if (any->type == XITouchValuatorClass)
417+ {
418+ char name[64];
419+ GeisFloat f;
420+ GeisInteger i;
421+ XITouchValuatorClassInfo *v = (XITouchValuatorClassInfo *)any;
422+ char *label = v->label ? XGetAtomName(be->x11_display, v->label) : "";
423+ sprintf(name, "%.48s %d min", label, v->number);
424+ f = v->min;
425+ geis_debug("touch valuator for device %d \"%s\": label \"%s\" %g",
426+ xcb_device->deviceid, xcb_device->name, name, f);
427+ device_attr = geis_attr_new(name, GEIS_ATTR_TYPE_FLOAT, &f);
428+ if (!device_attr)
429+ {
430+ geis_error("failed to create device attr");
431+ }
432+ else
433+ {
434+ geis_device_add_attr(geis_device, device_attr);
435+ }
436+
437+ sprintf(name, "%.48s %d max", label, v->number);
438+ f = v->max;
439+ geis_debug("touch valuator for device %d \"%s\": label \"%s\" %g",
440+ xcb_device->deviceid, xcb_device->name, name, v->max);
441+ device_attr = geis_attr_new(name, GEIS_ATTR_TYPE_FLOAT, &f);
442+ if (!device_attr)
443+ {
444+ geis_error("failed to create device attr");
445+ }
446+ else
447+ {
448+ geis_device_add_attr(geis_device, device_attr);
449+ }
450+
451+ sprintf(name, "%.48s %d resolution", label, v->number);
452+ i = v->resolution;
453+ geis_debug("touch valuator for device %d \"%s\": label \"%s\" %d",
454+ xcb_device->deviceid, xcb_device->name, name, i);
455+ device_attr = geis_attr_new(name, GEIS_ATTR_TYPE_INTEGER, &i);
456+ if (!device_attr)
457+ {
458+ geis_error("failed to create device attr");
459+ }
460+ else
461+ {
462+ geis_device_add_attr(geis_device, device_attr);
463+ }
464+ }
465+ }
466+ geis_post_event(be->geis, device_event);
467+ goto final_exit;
468+
469+unroll_device:
470+ geis_device_unref(geis_device);
471+unroll_event:
472+ geis_event_delete(device_event);
473+final_exit:
474+ return;
475+}
476+
477+
478+/*
479+ * Enumerates all input devices known to the X server and reports those that may
480+ * give gestural input.
481+ */
482 static void
483 _report_xcb_devices(GeisXcbBackend be)
484 {
485+ XIDeviceInfo *devices;
486+ int device_index;
487+ int num_devices;
488+
489+ devices = XIQueryDevice(be->x11_display, XIAllDevices, &num_devices);
490+ for (device_index = 0; device_index < num_devices; ++device_index)
491+ {
492+ int class_index;
493+ for (class_index = 0;
494+ class_index < devices[device_index].num_classes;
495+ ++class_index)
496+ {
497+ XIAnyClassInfo *any = devices[device_index].classes[class_index];
498+ if (any->type == XITouchClass)
499+ {
500+ _report_an_xcb_device(be, &devices[device_index]);
501+ break;
502+ }
503+ }
504+ }
505+
506+ XIFreeDeviceInfo(devices);
507 }
508
509
510
511=== modified file 'libutouch-geis/geis.c'
512--- libutouch-geis/geis.c 2011-02-27 21:41:00 +0000
513+++ libutouch-geis/geis.c 2011-03-16 22:13:52 +0000
514@@ -80,7 +80,7 @@
515 _device_event_handler(Geis geis, GeisEvent event)
516 {
517 GeisBoolean handled = GEIS_FALSE;
518- GeisAttr attr = geis_event_attr_by_name(event, "geis-device");
519+ GeisAttr attr = geis_event_attr_by_name(event, GEIS_EVENT_ATTRIBUTE_DEVICE);
520 if (!attr)
521 {
522 geis_warning("invalid device event received from back end.");
523
524=== modified file 'libutouch-geis/geis_attr.c'
525--- libutouch-geis/geis_attr.c 2011-02-28 17:37:00 +0000
526+++ libutouch-geis/geis_attr.c 2011-03-16 22:13:52 +0000
527@@ -185,7 +185,7 @@
528 break;
529
530 case GEIS_ATTR_TYPE_STRING:
531- attr->attr_value.s = (GeisString)attr_value;
532+ attr->attr_value.s = (GeisString)strdup(attr_value);
533 break;
534
535 default:
536@@ -203,6 +203,10 @@
537 {
538 attr->attr_destructor(attr->attr_value.p);
539 }
540+ else if (attr->attr_type == GEIS_ATTR_TYPE_STRING)
541+ {
542+ free((char *)attr->attr_value.s);
543+ }
544 free((void *)attr->attr_name);
545 free(attr);
546 }
547
548=== modified file 'libutouch-geis/geis_device.c'
549--- libutouch-geis/geis_device.c 2011-02-17 15:06:21 +0000
550+++ libutouch-geis/geis_device.c 2011-03-16 22:13:52 +0000
551@@ -31,7 +31,6 @@
552 struct _GeisDevice
553 {
554 GeisRefCount ref_count;
555- GeisInteger id;
556 GeisAttrBag attr_bag;
557 };
558
559@@ -163,6 +162,7 @@
560 GeisDevice
561 geis_device_new(GeisString name, GeisInteger id)
562 {
563+ GeisAttr attr;
564 GeisDevice device = calloc(1, sizeof(struct _GeisDevice));
565 if (!device)
566 {
567@@ -177,17 +177,26 @@
568 goto unwind_device;
569 }
570
571- GeisAttr name_attr = geis_attr_new(GEIS_DEVICE_ATTRIBUTE_NAME,
572- GEIS_ATTR_TYPE_STRING,
573- (void *)name);
574- if (!name_attr)
575- {
576- geis_debug("error allocating device name");
577- goto unwind_attrs;
578- }
579- geis_attr_bag_insert(device->attr_bag, name_attr);
580-
581- device->id = id;
582+ attr = geis_attr_new(GEIS_DEVICE_ATTRIBUTE_NAME,
583+ GEIS_ATTR_TYPE_STRING,
584+ (void *)name);
585+ if (!attr)
586+ {
587+ geis_debug("error allocating device name attr");
588+ goto unwind_attrs;
589+ }
590+ geis_attr_bag_insert(device->attr_bag, attr);
591+
592+ attr = geis_attr_new(GEIS_DEVICE_ATTRIBUTE_ID,
593+ GEIS_ATTR_TYPE_INTEGER,
594+ &id);
595+ if (!attr)
596+ {
597+ geis_debug("error allocating device id attr");
598+ goto unwind_attrs;
599+ }
600+ geis_attr_bag_insert(device->attr_bag, attr);
601+
602 geis_device_ref(device);
603 goto final_exit;
604
605@@ -258,7 +267,13 @@
606 GeisInteger
607 geis_device_id(GeisDevice device)
608 {
609- return device->id;
610+ GeisInteger device_id = -1;
611+ GeisAttr attr = geis_attr_bag_find(device->attr_bag, GEIS_DEVICE_ATTRIBUTE_ID);
612+ if (attr)
613+ {
614+ device_id = geis_attr_value_to_integer(attr);
615+ }
616+ return device_id;
617 }
618
619
620@@ -273,6 +288,16 @@
621
622
623 /*
624+ * Inserts an attr into a device.
625+ */
626+void
627+geis_device_add_attr(GeisDevice device, GeisAttr attr)
628+{
629+ geis_attr_bag_insert(device->attr_bag, attr);
630+}
631+
632+
633+/*
634 * Gets the indicated attribute of the device.
635 */
636 GeisAttr
637
638=== modified file 'libutouch-geis/geis_v1.c'
639--- libutouch-geis/geis_v1.c 2011-03-09 19:02:53 +0000
640+++ libutouch-geis/geis_v1.c 2011-03-16 22:13:52 +0000
641@@ -37,6 +37,8 @@
642 {
643 GeisSubscription subscription;
644 GeisFilter window_filter;
645+ GeisInputFuncs *input_funcs;
646+ GeisPointer input_context;
647 GeisGestureFuncs *gesture_funcs;
648 GeisPointer gesture_cookie;
649 };
650@@ -541,6 +543,15 @@
651 const char **g;
652
653 geis_debug("subscribing device %d for the following gestures:", device_id);
654+ result = geis_filter_add_term(instance->window_filter,
655+ GEIS_FILTER_DEVICE,
656+ GEIS_DEVICE_ATTRIBUTE_ID, GEIS_FILTER_OP_EQ, device_id,
657+ NULL);
658+ if (result != GEIS_STATUS_SUCCESS)
659+ {
660+ geis_error("error adding device filter term");
661+ }
662+
663 for (g = gesture_list; *g; ++g)
664 {
665 GeisV1AttrMap v1attr;
666@@ -681,12 +692,101 @@
667 }
668
669
670+static void
671+_v1_input_callback(Geis geis, GeisEvent event, void *context)
672+{
673+ GeisInstance v1_instance = (GeisInstance)context;
674+ GeisDevice device;
675+ GeisAttr attr;
676+ GeisSize i;
677+ GeisInputDeviceId device_id = 0;
678+
679+ attr = geis_event_attr_by_name(event, GEIS_EVENT_ATTRIBUTE_DEVICE);
680+ if (!attr)
681+ {
682+ geis_error("no touchset for gesture event");
683+ goto final_exit;
684+ }
685+
686+ device = geis_attr_value_to_pointer(attr);
687+ if (!device)
688+ {
689+ geis_warning("can not convert attr to device");
690+ goto final_exit;
691+ }
692+
693+ GeisGestureAttr *attrs = calloc(geis_device_attr_count(device) + 1,
694+ sizeof(GeisGestureAttr));
695+ if (!attrs)
696+ {
697+ geis_error("can not allocate device attrs");
698+ goto final_exit;
699+ }
700+
701+ for (i = 0; i < geis_device_attr_count(device); ++i)
702+ {
703+ attr = geis_device_attr(device, i);
704+ if (0 == strcmp(geis_attr_name(attr), GEIS_DEVICE_ATTRIBUTE_ID))
705+ {
706+ device_id = geis_attr_value_to_integer(attr);
707+ }
708+ attrs[i].name = geis_attr_name(attr);
709+ attrs[i].type = geis_attr_type(attr);
710+ switch (attrs[i].type)
711+ {
712+ case GEIS_ATTR_TYPE_BOOLEAN:
713+ attrs[i].boolean_val = geis_attr_value_to_boolean(attr);
714+ break;
715+ case GEIS_ATTR_TYPE_FLOAT:
716+ attrs[i].float_val = geis_attr_value_to_float(attr);
717+ break;
718+ case GEIS_ATTR_TYPE_INTEGER:
719+ attrs[i].integer_val = geis_attr_value_to_integer(attr);
720+ break;
721+ case GEIS_ATTR_TYPE_STRING:
722+ attrs[i].string_val = geis_attr_value_to_string(attr);
723+ break;
724+ default:
725+ break;
726+ }
727+ }
728+
729+ switch (geis_event_type(event))
730+ {
731+ case GEIS_EVENT_DEVICE_AVAILABLE:
732+ v1_instance->input_funcs->added(v1_instance->input_context,
733+ device_id,
734+ attrs);
735+ break;
736+ case GEIS_EVENT_DEVICE_UNAVAILABLE:
737+ v1_instance->input_funcs->removed(v1_instance->input_context,
738+ device_id,
739+ attrs);
740+ break;
741+ default:
742+ geis_debug("-- event ignored --");
743+ break;
744+ }
745+
746+ free(attrs);
747+
748+final_exit:
749+ geis_event_delete(event);
750+}
751+
752+
753 GeisStatus
754-geis_input_devices(GeisInstance geis_instance __attribute__((unused)),
755- GeisInputFuncs *func,
756- void *cookie)
757+geis_input_devices(GeisInstance instance,
758+ GeisInputFuncs *funcs,
759+ void *context)
760 {
761- geis_debug("ends");
762- return GEIS_STATUS_SUCCESS;
763+ GeisStatus result = GEIS_STATUS_SUCCESS;
764+
765+ instance->input_funcs = funcs;
766+ instance->input_context = context;
767+
768+ geis_register_device_callback(g_geis, _v1_input_callback, instance);
769+
770+ return result;
771 }
772
773
774=== modified file 'testsuite/geis1/check_gesture_attrs.c'
775--- testsuite/geis1/check_gesture_attrs.c 2011-03-09 18:59:00 +0000
776+++ testsuite/geis1/check_gesture_attrs.c 2011-03-16 22:13:52 +0000
777@@ -74,7 +74,6 @@
778
779 for (i = 0; i < attr_count; ++i)
780 {
781- fprintf(stderr, "==smw> attr[%lu].name=\"%s\"\n", i, attrs[i].name);
782 if (0 == strcmp(attrs[i].name, GEIS_GESTURE_ATTRIBUTE_FOCUS_X)
783 && fabs(attrs[i].float_val - 123.456) < 0.01)
784 {
785
786=== modified file 'testsuite/geis2/check_device.c'
787--- testsuite/geis2/check_device.c 2011-02-20 15:45:00 +0000
788+++ testsuite/geis2/check_device.c 2011-03-16 22:13:52 +0000
789@@ -23,10 +23,24 @@
790 }
791
792
793-/* Compile-time test to ensure types are defined */
794+/* Compile-time test to ensure types and constants are defined */
795 START_TEST(geis_device_types)
796 {
797+ GeisString attr_name;
798+ GeisInteger attr_ivalue;
799+
800+ /* Types */
801 GeisEventType type CK_ATTRIBUTE_UNUSED;
802+
803+ /* 5.3 Events */
804+ attr_name = GEIS_EVENT_ATTRIBUTE_DEVICE;
805+
806+ /* 5.1.2 Device Attributes */
807+ attr_name = GEIS_DEVICE_ATTRIBUTE_NAME;
808+ attr_name = GEIS_DEVICE_ATTRIBUTE_ID;
809+ attr_name = GEIS_DEVICE_ATTRIBUTE_DIRECT_TOUCH;
810+ attr_name = GEIS_DEVICE_ATTRIBUTE_INDEPENDENT_TOUCH;
811+ attr_name = GEIS_DEVICE_ATTRIBUTE_TOUCHES;
812 }
813 END_TEST
814
815
816=== modified file 'testsuite/geis2/check_subscription.c'
817--- testsuite/geis2/check_subscription.c 2011-02-17 17:40:49 +0000
818+++ testsuite/geis2/check_subscription.c 2011-03-16 22:13:52 +0000
819@@ -99,7 +99,7 @@
820 GeisFilter filter;
821 GeisStatus fs;
822
823- attr = geis_event_attr_by_name(event, "geis-device");
824+ attr = geis_event_attr_by_name(event, GEIS_EVENT_ATTRIBUTE_DEVICE);
825 fail_if (!attr, "geis-device attr not found in device event");
826
827 device = geis_attr_value_to_pointer(attr);
828
829=== modified file 'testsuite/geistest/geistest.c'
830--- testsuite/geistest/geistest.c 2011-02-28 17:40:46 +0000
831+++ testsuite/geistest/geistest.c 2011-03-16 22:13:52 +0000
832@@ -36,10 +36,14 @@
833 NULL
834 };
835
836+GeisSize g_device_count = 0;
837+GeisInputDeviceId *g_devices = GEIS_ALL_INPUT_DEVICES;
838+
839+
840 static void
841 print_attr(GeisGestureAttr *attr)
842 {
843- fprintf(stdout, "\tattr %s=", attr->name);
844+ fprintf(stdout, "\tattr \"%s\" = ", attr->name);
845 switch (attr->type)
846 {
847 case GEIS_ATTR_TYPE_BOOLEAN:
848@@ -64,6 +68,12 @@
849 static void
850 input_device_added(void *cookie, GeisInputDeviceId device_id, void *attrs)
851 {
852+ GeisGestureAttr *a;
853+ fprintf(stdout, "Device %d added\n", device_id);
854+ for (a = attrs; a->name; ++a)
855+ {
856+ print_attr(a);
857+ }
858 }
859
860
861@@ -160,12 +170,28 @@
862 };
863
864
865+static void
866+_add_device_id(GeisInteger id)
867+{
868+ GeisInputDeviceId *d = realloc(g_devices, g_device_count + 2);
869+ if (!d)
870+ {
871+ fprintf(stderr, "error allocating device list.\n");
872+ exit(1);
873+ }
874+ g_devices = d;
875+ g_devices[g_device_count] = id;
876+ g_devices[g_device_count+1] = 0;
877+ ++g_device_count;
878+}
879+
880+
881 int
882 parse_opts(int argc, char* argv[], uint32_t *window_id)
883 {
884 int opt;
885
886- while ((opt = getopt(argc, argv, "w:")) != -1)
887+ while ((opt = getopt(argc, argv, "w:d:")) != -1)
888 {
889 switch (opt)
890 {
891@@ -173,8 +199,20 @@
892 *window_id = strtol(optarg, NULL, 0);
893 break;
894
895+ case 'd':
896+ {
897+ GeisInteger id = strtol(optarg, NULL, 0);
898+ if (0 == id)
899+ {
900+ fprintf(stderr, "invalid device id '%s'\n'", optarg);
901+ return 0;
902+ }
903+ _add_device_id(id);
904+ }
905+ break;
906+
907 default:
908- return 0;
909+ return 0;
910 }
911 }
912
913@@ -212,7 +250,7 @@
914 }
915
916 status = geis_subscribe(instance,
917- GEIS_ALL_INPUT_DEVICES,
918+ g_devices,
919 s_gestures,
920 &gesture_funcs,
921 NULL);

Subscribers

People subscribed via source and target branches