summaryrefslogtreecommitdiff
path: root/src/touch-dev.c
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2010-08-19 20:03:15 +0200
committerHenrik Rydberg <rydberg@euromail.se>2010-08-19 20:03:15 +0200
commita704984e03d28b4be40e12c43be1b163bc9e09e2 (patch)
treec4720a59aa77918ffef742d7ec7ef2a7e2eda16e /src/touch-dev.c
parentcb2cad3b8c506a08a6bdad548a10ff47f85ef38b (diff)
Simplify touch machinery
To be able to model touch information uniformly across all supported devices, the semantics of the touch attributes has to be treated explicitly. Drop the generic touch property array and replace it by an actual structure. In addition, the touch-engine abstraction turned out to not be needed, so drop it as well. Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'src/touch-dev.c')
-rw-r--r--src/touch-dev.c164
1 files changed, 64 insertions, 100 deletions
diff --git a/src/touch-dev.c b/src/touch-dev.c
index b88cb8d..287076a 100644
--- a/src/touch-dev.c
+++ b/src/touch-dev.c
@@ -25,128 +25,97 @@
25#include <string.h> 25#include <string.h>
26#include <errno.h> 26#include <errno.h>
27 27
28/* from mtdev-mapping.h */ 28#define SET_PROP(name, value) \
29#define MT_TOUCH_MAJOR 0 29 if (t->name != value) { \
30#define MT_TOUCH_MINOR 1 30 t->name = value; \
31#define MT_WIDTH_MAJOR 2 31 frame->nmodify++; \
32#define MT_WIDTH_MINOR 3 32 }
33#define MT_ORIENTATION 4
34#define MT_POSITION_X 5
35#define MT_POSITION_Y 6
36#define MT_TRACKING_ID 9
37#define MT_PRESSURE 10
38
39struct touch_dev_impl {
40 int id[DIM_TOUCH];
41 int slot;
42 int status;
43 grail_mask_t mask[DIM_TOUCH_BYTES];
44 touch_prop_t prop[DIM_TOUCH_PROP];
45 struct mtdev mtdev;
46};
47
48static inline void set_info(struct touch_dev_caps *caps, int code,
49 const struct input_absinfo *info)
50{
51 grail_mask_set(caps->mask, code);
52 caps->info[code] = *info;
53}
54
55static void set_caps(struct touch_dev_caps *caps,
56 const struct mtdev_caps *mtcaps)
57{
58 if (mtcaps->has_abs[MT_POSITION_X])
59 set_info(caps, TP_POS_X, &mtcaps->abs[MT_POSITION_X]);
60 if (mtcaps->has_abs[MT_POSITION_Y])
61 set_info(caps, TP_POS_Y, &mtcaps->abs[MT_POSITION_Y]);
62 if (mtcaps->has_abs[MT_TOUCH_MAJOR])
63 set_info(caps, TP_TOUCH_MAJOR, &mtcaps->abs[MT_TOUCH_MAJOR]);
64 if (mtcaps->has_abs[MT_TOUCH_MINOR])
65 set_info(caps, TP_TOUCH_MINOR, &mtcaps->abs[MT_TOUCH_MINOR]);
66 if (mtcaps->has_abs[MT_WIDTH_MAJOR])
67 set_info(caps, TP_WIDTH_MAJOR, &mtcaps->abs[MT_WIDTH_MAJOR]);
68 if (mtcaps->has_abs[MT_WIDTH_MINOR])
69 set_info(caps, TP_WIDTH_MINOR, &mtcaps->abs[MT_WIDTH_MINOR]);
70 if (mtcaps->has_abs[MT_ORIENTATION])
71 set_info(caps, TP_ORIENTATION, &mtcaps->abs[MT_ORIENTATION]);
72 if (mtcaps->has_abs[MT_PRESSURE])
73 set_info(caps, TP_PRESSURE, &mtcaps->abs[MT_PRESSURE]);
74}
75
76static inline void set_prop(struct touch_dev_impl *x, int code, int value)
77{
78 grail_mask_set(x->mask, code);
79 x->prop[code] = value;
80}
81 33
82static void finish_touch(struct touch_dev *dev, 34static void finish_touch(struct touch_dev *dev, struct touch_frame *frame)
83 struct touch_dev_impl *x)
84{ 35{
85 if (x->status < 0 && dev->destroy) 36 struct touch *t = &frame->touch[dev->slot];
86 dev->destroy(dev, x->slot); 37 if (dev->state > 0) {
87 if (x->status > 0 && dev->create) 38 t->active = 1;
88 dev->create(dev, x->slot, x->mask, x->prop); 39 grail_mask_set(frame->touches, dev->slot);
89 if (x->status == 0 && dev->modify && 40 frame->ncreate++;
90 grail_mask_count(x->mask, sizeof(x->mask))) 41 }
91 dev->modify(dev, x->slot, x->mask, x->prop); 42 if (dev->state < 0) {
92 x->status = 0; 43 t->active = 0;
93 memset(x->mask, 0, sizeof(x->mask)); 44 grail_mask_clear(frame->touches, dev->slot);
45 frame->ndestroy++;
46 }
47 dev->state = 0;
94} 48}
95 49
96static void finish_packet(struct touch_dev *dev, 50static void finish_packet(struct touch_dev *dev,
97 const struct input_event *syn) 51 const struct input_event *syn)
98{ 52{
99 finish_touch(dev, dev->impl); 53 static const touch_time_t ms = 1000;
54 struct touch_frame *frame = &dev->frame;
55 int i, nslot = 0;
56 finish_touch(dev, frame);
57 grail_mask_foreach(i, frame->touches, DIM_TOUCH_BYTES)
58 frame->active[nslot++] = &frame->touch[i];
59 frame->nactive = nslot;
60 frame->time = syn->time.tv_usec / ms + syn->time.tv_sec * ms;
100 if (dev->sync) 61 if (dev->sync)
101 dev->sync(dev, syn); 62 dev->sync(dev, syn);
63 frame->ncreate = 0;
64 frame->nmodify = 0;
65 frame->ndestroy = 0;
102} 66}
103 67
104static int handle_abs_event(struct touch_dev *dev, 68static int handle_abs_event(struct touch_dev *dev,
105 const struct input_event *ev) 69 const struct input_event *ev)
106{ 70{
107 struct touch_dev_impl *x = dev->impl; 71 struct touch_frame *frame = &dev->frame;
72 struct touch *t = &frame->touch[dev->slot];
108 switch (ev->code) { 73 switch (ev->code) {
109 case ABS_MT_SLOT: 74 case ABS_MT_SLOT:
110 if (ev->value >= 0 && ev->value < DIM_TOUCH) { 75 if (ev->value >= 0 && ev->value < DIM_TOUCH) {
111 if (x->slot != ev->value) 76 if (dev->slot != ev->value)
112 finish_touch(dev, x); 77 finish_touch(dev, frame);
113 x->slot = ev->value; 78 dev->slot = ev->value;
79 t = &frame->touch[dev->slot];
114 } 80 }
115 return 1; 81 return 1;
116 case ABS_MT_POSITION_X: 82 case ABS_MT_POSITION_X:
117 set_prop(x, TP_POS_X, ev->value); 83 SET_PROP(x, ev->value);
118 return 1; 84 return 1;
119 case ABS_MT_POSITION_Y: 85 case ABS_MT_POSITION_Y:
120 set_prop(x, TP_POS_Y, ev->value); 86 SET_PROP(y, ev->value);
121 return 1; 87 return 1;
122 case ABS_MT_TOUCH_MAJOR: 88 case ABS_MT_TOUCH_MAJOR:
123 set_prop(x, TP_TOUCH_MAJOR, ev->value); 89 SET_PROP(touch_major, ev->value);
124 return 1; 90 return 1;
125 case ABS_MT_TOUCH_MINOR: 91 case ABS_MT_TOUCH_MINOR:
126 set_prop(x, TP_TOUCH_MINOR, ev->value); 92 SET_PROP(touch_minor, ev->value);
127 return 1; 93 return 1;
128 case ABS_MT_WIDTH_MAJOR: 94 case ABS_MT_WIDTH_MAJOR:
129 set_prop(x, TP_WIDTH_MAJOR, ev->value); 95 SET_PROP(width_major, ev->value);
130 return 1; 96 return 1;
131 case ABS_MT_WIDTH_MINOR: 97 case ABS_MT_WIDTH_MINOR:
132 set_prop(x, TP_WIDTH_MINOR, ev->value); 98 SET_PROP(width_minor, ev->value);
133 return 1; 99 return 1;
134 case ABS_MT_ORIENTATION: 100 case ABS_MT_ORIENTATION:
135 set_prop(x, TP_ORIENTATION, ev->value); 101 SET_PROP(orientation, ev->value);
136 return 1; 102 return 1;
137 case ABS_MT_PRESSURE: 103 case ABS_MT_PRESSURE:
138 set_prop(x, TP_PRESSURE, ev->value); 104 SET_PROP(pressure, ev->value);
105 return 1;
106 case ABS_MT_TOOL_TYPE:
107 SET_PROP(tool_type, ev->value);
139 return 1; 108 return 1;
140 case ABS_MT_TRACKING_ID: 109 case ABS_MT_TRACKING_ID:
141 if (x->id[x->slot] != ev->value) { 110 if (t->id != ev->value) {
142 if (x->id[x->slot] != MT_ID_NULL) { 111 if (t->id != MT_ID_NULL) {
143 x->status = -1; 112 dev->state = -1;
144 finish_touch(dev, x); 113 finish_touch(dev, frame);
145 } 114 }
146 if (ev->value != MT_ID_NULL) 115 if (ev->value != MT_ID_NULL)
147 x->status = 1; 116 dev->state = 1;
117 t->id = ev->value;
148 } 118 }
149 x->id[x->slot] = ev->value;
150 return 1; 119 return 1;
151 default: 120 default:
152 return 0; 121 return 0;
@@ -155,38 +124,35 @@ static int handle_abs_event(struct touch_dev *dev,
155 124
156int touch_dev_open(struct touch_dev *dev, int fd) 125int touch_dev_open(struct touch_dev *dev, int fd)
157{ 126{
158 struct touch_dev_impl *x; 127 struct touch_frame *frame = &dev->frame;
159 int ret, i; 128 int ret, i;
160 memset(dev, 0, sizeof(*dev)); 129 memset(dev, 0, sizeof(*dev));
161 x = calloc(1, sizeof(*x)); 130 for (i = 0; i < DIM_TOUCH; i++) {
162 if (!x) 131 struct touch *t = &frame->touch[i];
163 return -ENOMEM; 132 t->slot = i;
164 ret = mtdev_open(&x->mtdev, fd); 133 t->id = MT_ID_NULL;
165 if (!ret && !x->mtdev.caps.has_mtdata) 134 }
135 ret = mtdev_open(&dev->mtdev, fd);
136 if (!ret && !dev->mtdev.caps.has_mtdata)
166 ret = -ENODEV; 137 ret = -ENODEV;
167 if (ret) 138 if (ret)
168 goto error; 139 goto error;
169 for (i = 0; i < DIM_TOUCH; i++) 140 touch_caps_init(dev);
170 x->id[i] = MT_ID_NULL;
171 set_caps(&dev->caps, &x->mtdev.caps);
172 dev->impl = x;
173 return 0; 141 return 0;
174 error: 142 error:
175 free(x);
176 return ret; 143 return ret;
177} 144}
178 145
179int touch_dev_idle(struct touch_dev *dev, int fd, int ms) 146int touch_dev_idle(struct touch_dev *dev, int fd, int ms)
180{ 147{
181 return mtdev_idle(&dev->impl->mtdev, fd, ms); 148 return mtdev_idle(&dev->mtdev, fd, ms);
182} 149}
183 150
184int touch_dev_pull(struct touch_dev *dev, int fd) 151int touch_dev_pull(struct touch_dev *dev, int fd)
185{ 152{
186 struct touch_dev_impl *x = dev->impl;
187 struct input_event ev; 153 struct input_event ev;
188 int ret, count = 0, consumed; 154 int ret, count = 0, consumed;
189 while ((ret = mtdev_get(&x->mtdev, fd, &ev, 1)) > 0) { 155 while ((ret = mtdev_get(&dev->mtdev, fd, &ev, 1)) > 0) {
190 consumed = 0; 156 consumed = 0;
191 if (ev.type == EV_SYN) { 157 if (ev.type == EV_SYN) {
192 if (ev.code == SYN_REPORT) 158 if (ev.code == SYN_REPORT)
@@ -204,8 +170,6 @@ int touch_dev_pull(struct touch_dev *dev, int fd)
204 170
205void touch_dev_close(struct touch_dev *dev, int fd) 171void touch_dev_close(struct touch_dev *dev, int fd)
206{ 172{
207 struct touch_dev_impl *x = dev->impl; 173 mtdev_close(&dev->mtdev);
208 mtdev_close(&x->mtdev);
209 free(x);
210 memset(dev, 0, sizeof(*dev)); 174 memset(dev, 0, sizeof(*dev));
211} 175}