Merge lp:~oif-team/grail/trunk.v1.0.13 into lp:grail

Proposed by Henrik Rydberg
Status: Superseded
Proposed branch: lp:~oif-team/grail/trunk.v1.0.13
Merge into: lp:grail
Diff against target: 220 lines (+126/-3)
4 files modified
configure.ac (+1/-1)
include/grail-touch.h (+1/-0)
src/touch-caps.c (+37/-0)
src/touch-dev.c (+87/-2)
To merge this branch: bzr merge lp:~oif-team/grail/trunk.v1.0.13
Reviewer Review Type Date Requested Status
Chase Douglas (community) Needs Resubmitting
Review via email: mp+34788@code.launchpad.net

This proposal has been superseded by a proposal from 2010-09-08.

Description of the change

The changes needed to support non-MT devices through the utouch stack.

To post a comment you must log in.
Revision history for this message
Chase Douglas (chasedouglas) wrote :

Commit 79 makes sense, so no issues there.

However, I'm not sure what to do about commit 80. I think it looks good and it probably can introduce some interesting support for synaptics trackpads. However, it's also really late in the cycle to be adding this much new code.

I know it would be a bit of extra work, but can we keep commit 80 in a separate branch for now and not package it up for Maverick? By strict definition it is clearly out of scope at this point in the development cycle, and it likely won't actually add any new features since synaptics will be used for most of these devices anyways. However, I worry that there could be regressions in the single-touch touchscreen use case.

I guess the most appropriate review state for this is resubmit to include only commit 79. If you aren't meaning to push this into maverick, perhaps this could be merged as 1.1.0 and we would keep maverick on the 1.0.x series that would not include commit 80?

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

Well, I was thinking maverick for this, since there has already been bug reports about it. I see your point clearly, but I also see the conflict between the normal maverick procedure and the interests to make gestures work for as broad an audience as possible.

lp:~oif-team/grail/trunk.v1.0.13 updated
79. By Henrik Rydberg

Make sure contact area is always defined

Some devices do not always send touch_minor after touch_major
has been set. According to the MT protocol, this case should
be treated as if minor is equal to major. This patch makes sure
touch_minor is never zero when touch_major is set.

80. By Henrik Rydberg

Support legacy devices

Simulate MT touch events for legacy devices that support the
DOUBLETAP, TRIPLETAP and QUADTAP events. This allows multi-finger
tap and drag gestures to be emitted, providing a basic level of
MT functionality for legacy devices.

81. By Henrik Rydberg

Discard tapping even when there are zero events between dow
n and up

The current logic assumes there will be at least one frame with
between touch up and touch down or the tap will not be properly
timed out. Fixed with this patch.

Reported-by: Chase Douglas <email address hidden>

82. By Henrik Rydberg

Cancel tapping also on zoom events

The current code cancels tapping when dragging is active. This
patch adds zooming to the set, to inhibit tapping also when a
perfect zoom without dragging is performed.

Reported-by: Chase Douglas <email address hidden>

83. By Henrik Rydberg

Only emit abs events when motion is active

This bug was hidden behind the motion inhibit during tapping,
but resurfaced when tapping from resting finger was introduced.
With this patch, pointer movement is inhibited also when lifting
fingers from the surface.

Ideally, tapping should be treated as a transient event, which would
allow zero pointer event also _before_ the tap, but presently unity
seems to depend on the initial pointer movement as a touch-down event.

84. By Henrik Rydberg

Inhibit taps immediately after a finger is lifted

The intentional tap starts with a finger in the air. This patch
treats the sequence up-down-up as unintentional, unless performed
with a single finger. Fixes the problem with accidental taps during
multi-finger gestures.

85. By Henrik Rydberg

Allow slow tapping

For the benefit of hardware that cannot accurately meet the desirable
response times, allow for tapping times up to 300 ms.

86. By Henrik Rydberg

grail v1.0.13

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'configure.ac'
--- configure.ac 2010-09-01 21:01:08 +0000
+++ configure.ac 2010-09-08 09:41:45 +0000
@@ -1,7 +1,7 @@
1# Initialize Autoconf1# Initialize Autoconf
2AC_PREREQ([2.60])2AC_PREREQ([2.60])
3AC_INIT([Gesture Recognition And Instantiation Library],3AC_INIT([Gesture Recognition And Instantiation Library],
4 [1.0.12],4 [1.0.13],
5 [],5 [],
6 [utouch-grail])6 [utouch-grail])
7AC_CONFIG_SRCDIR([Makefile.am])7AC_CONFIG_SRCDIR([Makefile.am])
88
=== modified file 'include/grail-touch.h'
--- include/grail-touch.h 2010-08-19 20:26:11 +0000
+++ include/grail-touch.h 2010-09-08 09:41:45 +0000
@@ -72,6 +72,7 @@
72 int state;72 int state;
73};73};
7474
75int touch_caps_is_supported(struct touch_dev *dev, int fd);
75void touch_caps_init(struct touch_dev *dev);76void touch_caps_init(struct touch_dev *dev);
76float touch_angle(const struct touch_dev *dev, int orientation);77float touch_angle(const struct touch_dev *dev, int orientation);
77float touch_pressure(const struct touch_dev *dev, int pressure);78float touch_pressure(const struct touch_dev *dev, int pressure);
7879
=== modified file 'src/touch-caps.c'
--- src/touch-caps.c 2010-08-31 12:20:32 +0000
+++ src/touch-caps.c 2010-09-08 09:41:45 +0000
@@ -21,6 +21,7 @@
21 ****************************************************************************/21 ****************************************************************************/
2222
23#include <grail-touch.h>23#include <grail-touch.h>
24#include <errno.h>
24#include <math.h>25#include <math.h>
2526
26/* see mtdev-mapping.h */27/* see mtdev-mapping.h */
@@ -29,6 +30,42 @@
29#define MTDEV_ORIENTATION 430#define MTDEV_ORIENTATION 4
30#define MTDEV_PRESSURE 1031#define MTDEV_PRESSURE 10
3132
33#define SYSCALL(call) while (((call) == -1) && (errno == EINTR))
34
35static const int bits_per_long = 8 * sizeof(long);
36
37static inline int nlongs(int nbit)
38{
39 return (nbit + bits_per_long - 1) / bits_per_long;
40}
41
42static inline int getbit(const unsigned long *map, int key)
43{
44 return (map[key / bits_per_long] >> (key % bits_per_long)) & 0x01;
45}
46
47int touch_caps_is_supported(struct touch_dev *dev, int fd)
48{
49 unsigned long keybits[nlongs(KEY_MAX)];
50 unsigned long absbits[nlongs(ABS_MAX)];
51 int rc;
52
53 if (dev->mtdev.caps.has_mtdata)
54 return 1;
55
56 SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits));
57 if (rc < 0)
58 return 0;
59 SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbits)), absbits));
60 if (rc < 0)
61 return 0;
62
63 return getbit(absbits, ABS_X) &&
64 getbit(absbits, ABS_Y) &&
65 getbit(keybits, BTN_TOUCH) &&
66 getbit(keybits, BTN_TOOL_DOUBLETAP);
67}
68
32void touch_caps_init(struct touch_dev *dev)69void touch_caps_init(struct touch_dev *dev)
33{70{
34 const struct mtdev_caps *mt = &dev->mtdev.caps;71 const struct mtdev_caps *mt = &dev->mtdev.caps;
3572
=== modified file 'src/touch-dev.c'
--- src/touch-dev.c 2010-08-19 20:26:11 +0000
+++ src/touch-dev.c 2010-09-08 09:41:45 +0000
@@ -34,6 +34,8 @@
34static void finish_touch(struct touch_dev *dev, struct touch_frame *frame)34static void finish_touch(struct touch_dev *dev, struct touch_frame *frame)
35{35{
36 struct touch *t = &frame->touch[dev->slot];36 struct touch *t = &frame->touch[dev->slot];
37 if (t->touch_major && !t->touch_minor)
38 SET_PROP(touch_minor, t->touch_major);
37 if (dev->state > 0) {39 if (dev->state > 0) {
38 t->active = 1;40 t->active = 1;
39 grail_mask_set(frame->touches, dev->slot);41 grail_mask_set(frame->touches, dev->slot);
@@ -47,13 +49,45 @@
47 dev->state = 0;49 dev->state = 0;
48}50}
4951
52static void finish_legacy(struct touch_dev *dev, struct touch_frame *frame)
53{
54 static int trkid;
55 int i;
56 for (i = 0; i < frame->nactive; i++) {
57 struct touch *t = &frame->touch[i];
58 t->active = 1;
59 if (t->id < 0) {
60 t->id = trkid++ & 0xffff;
61 frame->ncreate++;
62 }
63 if (i > 0) {
64 SET_PROP(x, frame->touch[0].x);
65 SET_PROP(y, frame->touch[0].y);
66 SET_PROP(pressure, frame->touch[0].pressure);
67 }
68 grail_mask_set(frame->touches, i);
69 }
70 for (i = frame->nactive; i < DIM_TOUCH; i++) {
71 struct touch *t = &frame->touch[i];
72 t->active = 0;
73 if (t->id >= 0) {
74 t->id = -1;
75 frame->ndestroy++;
76 }
77 grail_mask_clear(frame->touches, i);
78 }
79}
80
50static void finish_packet(struct touch_dev *dev,81static void finish_packet(struct touch_dev *dev,
51 const struct input_event *syn)82 const struct input_event *syn)
52{83{
53 static const touch_time_t ms = 1000;84 static const touch_time_t ms = 1000;
54 struct touch_frame *frame = &dev->frame;85 struct touch_frame *frame = &dev->frame;
55 int i, nslot = 0;86 int i, nslot = 0;
56 finish_touch(dev, frame);87 if (dev->mtdev.caps.has_mtdata)
88 finish_touch(dev, frame);
89 else
90 finish_legacy(dev, frame);
57 grail_mask_foreach(i, frame->touches, DIM_TOUCH_BYTES)91 grail_mask_foreach(i, frame->touches, DIM_TOUCH_BYTES)
58 frame->active[nslot++] = &frame->touch[i];92 frame->active[nslot++] = &frame->touch[i];
59 frame->nactive = nslot;93 frame->nactive = nslot;
@@ -71,6 +105,21 @@
71 struct touch_frame *frame = &dev->frame;105 struct touch_frame *frame = &dev->frame;
72 struct touch *t = &frame->touch[dev->slot];106 struct touch *t = &frame->touch[dev->slot];
73 switch (ev->code) {107 switch (ev->code) {
108 case ABS_X:
109 if (dev->mtdev.caps.has_mtdata)
110 return 0;
111 SET_PROP(x, ev->value);
112 return 1;
113 case ABS_Y:
114 if (dev->mtdev.caps.has_mtdata)
115 return 0;
116 SET_PROP(y, ev->value);
117 return 1;
118 case ABS_PRESSURE:
119 if (dev->mtdev.caps.has_mtdata)
120 return 0;
121 SET_PROP(pressure, ev->value);
122 return 1;
74 case ABS_MT_SLOT:123 case ABS_MT_SLOT:
75 if (ev->value >= 0 && ev->value < DIM_TOUCH) {124 if (ev->value >= 0 && ev->value < DIM_TOUCH) {
76 if (dev->slot != ev->value)125 if (dev->slot != ev->value)
@@ -122,6 +171,40 @@
122 }171 }
123}172}
124173
174static int handle_key_event(struct touch_dev *dev,
175 const struct input_event *ev)
176{
177 struct touch_frame *frame = &dev->frame;
178 if (dev->mtdev.caps.has_mtdata)
179 return 0;
180 switch (ev->code) {
181 case BTN_TOUCH:
182 if (ev->value && !frame->nactive)
183 frame->nactive = 1;
184 else if (!ev->value && frame->nactive)
185 frame->nactive = 0;
186 return 1;
187 case BTN_TOOL_FINGER:
188 if (ev->value)
189 frame->nactive = 1;
190 return 1;
191 case BTN_TOOL_DOUBLETAP:
192 if (ev->value)
193 frame->nactive = 2;
194 return 1;
195 case BTN_TOOL_TRIPLETAP:
196 if (ev->value)
197 frame->nactive = 3;
198 return 1;
199 case BTN_TOOL_QUADTAP:
200 if (ev->value)
201 frame->nactive = 4;
202 return 1;
203 default:
204 return 0;
205 }
206}
207
125int touch_dev_open(struct touch_dev *dev, int fd)208int touch_dev_open(struct touch_dev *dev, int fd)
126{209{
127 struct touch_frame *frame = &dev->frame;210 struct touch_frame *frame = &dev->frame;
@@ -133,7 +216,7 @@
133 t->id = MT_ID_NULL;216 t->id = MT_ID_NULL;
134 }217 }
135 ret = mtdev_open(&dev->mtdev, fd);218 ret = mtdev_open(&dev->mtdev, fd);
136 if (!ret && !dev->mtdev.caps.has_mtdata)219 if (!ret && !touch_caps_is_supported(dev, fd))
137 ret = -ENODEV;220 ret = -ENODEV;
138 if (ret)221 if (ret)
139 goto error;222 goto error;
@@ -160,6 +243,8 @@
160 consumed++;243 consumed++;
161 } else if (ev.type == EV_ABS) {244 } else if (ev.type == EV_ABS) {
162 consumed += handle_abs_event(dev, &ev);245 consumed += handle_abs_event(dev, &ev);
246 } else if (ev.type == EV_KEY) {
247 consumed += handle_key_event(dev, &ev);
163 }248 }
164 if (!consumed && dev->event)249 if (!consumed && dev->event)
165 dev->event(dev, &ev);250 dev->event(dev, &ev);

Subscribers

People subscribed via source and target branches

to all changes: