summaryrefslogtreecommitdiff
path: root/src/multitouch.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/multitouch.c')
-rw-r--r--src/multitouch.c369
1 files changed, 0 insertions, 369 deletions
diff --git a/src/multitouch.c b/src/multitouch.c
deleted file mode 100644
index 7e275b3..0000000
--- a/src/multitouch.c
+++ /dev/null
@@ -1,369 +0,0 @@
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 };