summaryrefslogtreecommitdiff
path: root/driver
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2010-06-16 02:27:32 +0200
committerHenrik Rydberg <rydberg@euromail.se>2010-06-16 02:27:32 +0200
commitff88de5cd38b5b51bad0e63d373d66745f1f8d31 (patch)
tree3fbf4adc8c807bc79a8272c4df1623c3677a9b2f /driver
parentad6faf6c53bc1924986e1cc10bb42e5d157cba8f (diff)
refactor: Move files
Move all headers into include, separate source files into modules match, mtdev, src and driver, move some common definitions to common.h, and include define support for the MT slot protocol. This patch does not introduce any logical changes. Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'driver')
-rw-r--r--driver/multitouch.c369
1 files changed, 369 insertions, 0 deletions
diff --git a/driver/multitouch.c b/driver/multitouch.c
new file mode 100644
index 0000000..7e275b3
--- /dev/null
+++ b/driver/multitouch.c
@@ -0,0 +1,369 @@
1/***************************************************************************
2 *
3 * Multitouch X driver
4 * Copyright (C) 2008 Henrik Rydberg <rydberg@euromail.se>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 **************************************************************************/
21
22#include "gestures.h"
23
24#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
25#include <X11/Xatom.h>
26#include <xserver-properties.h>
27#endif
28
29/* these should be user-configurable at some point */
30static const float vscroll_fraction = 0.05;
31static const float hscroll_fraction = 0.05;
32static const float vswipe_fraction = 0.25;
33static const float hswipe_fraction = 0.25;
34static const float scale_fraction = 0.05;
35static const float rot_fraction = 0.05;
36
37/* flip these to enable event debugging */
38#if 1
39#define TRACE1(format, arg1)
40#define TRACE2(format, arg1, arg2)
41#else
42#define TRACE1(format, arg1) xf86Msg(X_INFO, format, arg1)
43#define TRACE2(format, arg1, arg2) xf86Msg(X_INFO, format, arg1, arg2)
44#endif
45
46/* button mapping simplified */
47#define PROPMAP(m, x, y) m[x] = XIGetKnownProperty(y)
48
49static void pointer_control(DeviceIntPtr dev, PtrCtrl *ctrl)
50{
51 xf86Msg(X_INFO, "pointer_control\n");
52}
53
54static int pointer_property(DeviceIntPtr dev,
55 Atom property,
56 XIPropertyValuePtr prop,
57 BOOL checkonly)
58{
59 xf86Msg(X_INFO, "pointer_property\n");
60 return Success;
61}
62
63#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
64static void initAxesLabels(Atom map[2])
65{
66 memset(map, 0, 2 * sizeof(Atom));
67 PROPMAP(map, 0, AXIS_LABEL_PROP_REL_X);
68 PROPMAP(map, 1, AXIS_LABEL_PROP_REL_Y);
69}
70
71static void initButtonLabels(Atom map[DIM_BUTTON])
72{
73 memset(map, 0, DIM_BUTTON * sizeof(Atom));
74 PROPMAP(map, MT_BUTTON_LEFT, BTN_LABEL_PROP_BTN_LEFT);
75 PROPMAP(map, MT_BUTTON_MIDDLE, BTN_LABEL_PROP_BTN_MIDDLE);
76 PROPMAP(map, MT_BUTTON_RIGHT, BTN_LABEL_PROP_BTN_RIGHT);
77 PROPMAP(map, MT_BUTTON_WHEEL_UP, BTN_LABEL_PROP_BTN_WHEEL_UP);
78 PROPMAP(map, MT_BUTTON_WHEEL_DOWN, BTN_LABEL_PROP_BTN_WHEEL_DOWN);
79 PROPMAP(map, MT_BUTTON_HWHEEL_LEFT, BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
80 PROPMAP(map, MT_BUTTON_HWHEEL_RIGHT, BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
81 /* how to map swipe buttons? */
82 PROPMAP(map, MT_BUTTON_SWIPE_UP, BTN_LABEL_PROP_BTN_0);
83 PROPMAP(map, MT_BUTTON_SWIPE_DOWN, BTN_LABEL_PROP_BTN_1);
84 PROPMAP(map, MT_BUTTON_SWIPE_LEFT, BTN_LABEL_PROP_BTN_2);
85 PROPMAP(map, MT_BUTTON_SWIPE_RIGHT, BTN_LABEL_PROP_BTN_3);
86 /* how to map scale and rotate? */
87 PROPMAP(map, MT_BUTTON_SCALE_DOWN, BTN_LABEL_PROP_BTN_4);
88 PROPMAP(map, MT_BUTTON_SCALE_UP, BTN_LABEL_PROP_BTN_5);
89 PROPMAP(map, MT_BUTTON_ROTATE_LEFT, BTN_LABEL_PROP_BTN_6);
90 PROPMAP(map, MT_BUTTON_ROTATE_RIGHT, BTN_LABEL_PROP_BTN_7);
91}
92#endif
93
94static int device_init(DeviceIntPtr dev, LocalDevicePtr local)
95{
96 struct MTouch *mt = local->private;
97 unsigned char btmap[DIM_BUTTON + 1] = {
98 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
99 };
100#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
101 Atom axes_labels[2], btn_labels[DIM_BUTTON];
102 initAxesLabels(axes_labels);
103 initButtonLabels(btn_labels);
104#endif
105
106 local->fd = xf86OpenSerial(local->options);
107 if (local->fd < 0) {
108 xf86Msg(X_ERROR, "multitouch: cannot open device\n");
109 return !Success;
110 }
111 if (configure_mtouch(mt, local->fd)) {
112 xf86Msg(X_ERROR, "multitouch: cannot configure device\n");
113 return !Success;
114 }
115 xf86CloseSerial(local->fd);
116
117#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 3
118 InitPointerDeviceStruct((DevicePtr)dev,
119 btmap, DIM_BUTTON,
120 GetMotionHistory,
121 pointer_control,
122 GetMotionHistorySize(),
123 2);
124#elif GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 7
125 InitPointerDeviceStruct((DevicePtr)dev,
126 btmap, DIM_BUTTON,
127 pointer_control,
128 GetMotionHistorySize(),
129 2);
130#elif GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
131 InitPointerDeviceStruct((DevicePtr)dev,
132 btmap, DIM_BUTTON, btn_labels,
133 pointer_control,
134 GetMotionHistorySize(),
135 2, axes_labels);
136#else
137#error "Unsupported ABI_XINPUT_VERSION"
138#endif
139
140 xf86InitValuatorAxisStruct(dev, 0,
141#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
142 axes_labels[0],
143#endif
144 mt->caps.abs_position_x.minimum,
145 mt->caps.abs_position_x.maximum,
146 1, 0, 1);
147 xf86InitValuatorDefaults(dev, 0);
148 xf86InitValuatorAxisStruct(dev, 1,
149#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
150 axes_labels[1],
151#endif
152 mt->caps.abs_position_y.minimum,
153 mt->caps.abs_position_y.maximum,
154 1, 0, 1);
155 xf86InitValuatorDefaults(dev, 1);
156
157 XIRegisterPropertyHandler(dev, pointer_property, NULL, NULL);
158
159 return Success;
160}
161
162static int device_on(LocalDevicePtr local)
163{
164 struct MTouch *mt = local->private;
165 local->fd = xf86OpenSerial(local->options);
166 if (local->fd < 0) {
167 xf86Msg(X_ERROR, "multitouch: cannot open device\n");
168 return !Success;
169 }
170 if (open_mtouch(mt, local->fd)) {
171 xf86Msg(X_ERROR, "multitouch: cannot grab device\n");
172 return !Success;
173 }
174 xf86AddEnabledDevice(local);
175 return Success;
176}
177
178static int device_off(LocalDevicePtr local)
179{
180 struct MTouch *mt = local->private;
181 xf86RemoveEnabledDevice(local);
182 if (close_mtouch(mt, local->fd))
183 xf86Msg(X_WARNING, "multitouch: cannot ungrab device\n");
184 xf86CloseSerial(local->fd);
185 return Success;
186}
187
188static int device_close(LocalDevicePtr local)
189{
190 return Success;
191}
192
193static void tickle_button(LocalDevicePtr local, int id)
194{
195 xf86PostButtonEvent(local->dev, FALSE, id, 1, 0, 0);
196 xf86PostButtonEvent(local->dev, FALSE, id, 0, 0, 0);
197}
198
199static void button_scroll(LocalDevicePtr local,
200 int btdec, int btinc,
201 int *scroll, int step,
202 int delta)
203{
204 *scroll += delta;
205 while (*scroll > step) {
206 tickle_button(local, btinc);
207 *scroll -= step;
208 }
209 while (*scroll < -step) {
210 tickle_button(local, btdec);
211 *scroll += step;
212 }
213}
214
215static void handle_gestures(LocalDevicePtr local,
216 const struct Gestures *gs,
217 const struct Capabilities *caps)
218{
219 static int vscroll, hscroll, vswipe, hswipe, scale, rot;
220 int vscrollstep = 1 + vscroll_fraction * get_cap_ysize(caps);
221 int hscrollstep = 1 + hscroll_fraction * get_cap_xsize(caps);
222 int vswipestep = 1 + vswipe_fraction * get_cap_ysize(caps);
223 int hswipestep = 1 + hswipe_fraction * get_cap_xsize(caps);
224 int scalestep = 1 + scale_fraction * get_cap_xsize(caps);
225 int rotstep = 1 + rot_fraction * get_cap_xsize(caps);
226 int i;
227 if (!gs->same_fingers) {
228 vscroll = 0;
229 hscroll = 0;
230 vswipe = 0;
231 hswipe = 0;
232 }
233 for (i = 0; i < DIM_BUTTON; i++) {
234 if (GETBIT(gs->btmask, i)) {
235 xf86PostButtonEvent(local->dev, FALSE,
236 i + 1, GETBIT(gs->btdata, i), 0, 0);
237 TRACE2("button bit: %d %d\n", i, GETBIT(gs->btdata, i));
238 }
239 }
240 if (GETBIT(gs->type, GS_MOVE)) {
241 xf86PostMotionEvent(local->dev, 0, 0, 2,
242 gs->dx, gs->dy);
243 TRACE2("motion: %d %d\n", gs->dx, gs->dy);
244 }
245 if (GETBIT(gs->type, GS_VSCROLL)) {
246 button_scroll(local, 4, 5, &vscroll, vscrollstep, gs->dy);
247 TRACE1("vscroll: %d\n", gs->dy);
248 }
249 if (GETBIT(gs->type, GS_HSCROLL)) {
250 button_scroll(local, 6, 7, &hscroll, hscrollstep, gs->dx);
251 TRACE1("hscroll: %d\n", gs->dx);
252 }
253 if (GETBIT(gs->type, GS_VSWIPE)) {
254 button_scroll(local, 8, 9, &vswipe, vswipestep, gs->dy);
255 TRACE1("vswipe: %d\n", gs->dy);
256 }
257 if (GETBIT(gs->type, GS_HSWIPE)) {
258 button_scroll(local, 10, 11, &hswipe, hswipestep, gs->dx);
259 TRACE1("hswipe: %d\n", gs->dx);
260 }
261 if (GETBIT(gs->type, GS_SCALE)) {
262 button_scroll(local, 12, 13, &scale, scalestep, gs->scale);
263 TRACE1("scale: %d\n", gs->scale);
264 }
265 if (GETBIT(gs->type, GS_ROTATE)) {
266 button_scroll(local, 14, 15, &rot, rotstep, gs->rot);
267 TRACE1("rotate: %d\n", gs->rot);
268 }
269}
270
271/* called for each full received packet from the touchpad */
272static void read_input(LocalDevicePtr local)
273{
274 struct Gestures gs;
275 struct MTouch *mt = local->private;
276 while (read_synchronized_event(mt, local->fd)) {
277 parse_event(mt);
278 extract_gestures(&gs, mt);
279 handle_gestures(local, &gs, &mt->caps);
280 }
281}
282
283static Bool device_control(DeviceIntPtr dev, int mode)
284{
285 LocalDevicePtr local = dev->public.devicePrivate;
286 switch (mode) {
287 case DEVICE_INIT:
288 xf86Msg(X_INFO, "device control: init\n");
289 return device_init(dev, local);
290 case DEVICE_ON:
291 xf86Msg(X_INFO, "device control: on\n");
292 return device_on(local);
293 case DEVICE_OFF:
294 xf86Msg(X_INFO, "device control: off\n");
295 return device_off(local);
296 case DEVICE_CLOSE:
297 xf86Msg(X_INFO, "device control: close\n");
298 return device_close(local);
299 default:
300 xf86Msg(X_INFO, "device control: default\n");
301 return BadValue;
302 }
303}
304
305
306static InputInfoPtr preinit(InputDriverPtr drv, IDevPtr dev, int flags)
307{
308 struct MTouch *mt;
309 InputInfoPtr local = xf86AllocateInput(drv, 0);
310 if (!local)
311 goto error;
312 mt = xcalloc(1, sizeof(struct MTouch));
313 if (!mt)
314 goto error;
315
316 local->name = dev->identifier;
317 local->type_name = XI_TOUCHPAD;
318 local->device_control = device_control;
319 local->read_input = read_input;
320 local->private = mt;
321 local->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS;
322 local->conf_idev = dev;
323
324 xf86CollectInputOptions(local, NULL, NULL);
325 /* xf86OptionListReport(local->options); */
326 xf86ProcessCommonOptions(local, local->options);
327
328 local->flags |= XI86_CONFIGURED;
329 error:
330 return local;
331}
332
333static void uninit(InputDriverPtr drv, InputInfoPtr local, int flags)
334{
335 xfree(local->private);
336 local->private = 0;
337 xf86DeleteInput(local, 0);
338}
339
340static InputDriverRec MULTITOUCH = {
341 1,
342 "multitouch",
343 NULL,
344 preinit,
345 uninit,
346 NULL,
347 0
348};
349
350static XF86ModuleVersionInfo VERSION = {
351 "multitouch",
352 MODULEVENDORSTRING,
353 MODINFOSTRING1,
354 MODINFOSTRING2,
355 XORG_VERSION_CURRENT,
356 0, 1, 0,
357 ABI_CLASS_XINPUT,
358 ABI_XINPUT_VERSION,
359 MOD_CLASS_XINPUT,
360 {0, 0, 0, 0}
361};
362
363static pointer setup(pointer module, pointer options, int *errmaj, int *errmin)
364{
365 xf86AddInputDriver(&MULTITOUCH, module, 0);
366 return module;
367}
368
369XF86ModuleData multitouchModuleData = {&VERSION, &setup, NULL };