2d8448f8e7e5f0eafc471f8f3c12c9986ca2d8a1
[adaptation/xorg/driver/xserver-xorg-input-evdev-multitouch.git] / src / evdevmultitouch.c
1 /*
2  *
3  * xserver-xorg-input-evdev-multitouch
4  *
5  * Contact: Sung-Jin Park <sj76.park@samsung.com>
6  *          Sangjin LEE <lsj119@samsung.com>
7  *
8  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
9  *
10  * Copyright © 2004-2008 Red Hat, Inc.
11  *
12  * Permission to use, copy, modify, distribute, and sell this software
13  * and its documentation for any purpose is hereby granted without
14  * fee, provided that the above copyright notice appear in all copies
15  * and that both that copyright notice and this permission notice
16  * appear in supporting documentation, and that the name of Red Hat
17  * not be used in advertising or publicity pertaining to distribution
18  * of the software without specific, written prior permission.  Red
19  * Hat makes no representations about the suitability of this software
20  * for any purpose.  It is provided "as is" without express or implied
21  * warranty.
22  *
23  * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
24  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
25  * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
26  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
27  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
28  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
29  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
30  *
31  * Authors:
32  *      Kristian Høgsberg (krh@redhat.com)
33  *      Adam Jackson (ajax@redhat.com)
34  *      Peter Hutterer (peter.hutterer@redhat.com)
35  *      Oliver McFadden (oliver.mcfadden@nokia.com)
36  *      Benjamin Tissoires (tissoire@cena.fr)
37  */
38
39 #ifdef HAVE_CONFIG_H
40 #include "config.h"
41 #endif
42
43 #include <X11/keysym.h>
44
45 #include <sys/stat.h>
46 #include <unistd.h>
47 #include <errno.h>
48 #include <fcntl.h>
49
50 #include <xf86.h>
51 #include <xf86Xinput.h>
52 #include <exevents.h>
53 #include <xorgVersion.h>
54 #include <xkbsrv.h>
55
56 #include "evdevmultitouch.h"
57 #include "vsync_input_protocol.h"
58 #include "vsync_debug_info.h"
59
60 #ifdef HAVE_PROPERTIES
61 #include <X11/Xatom.h>
62 #include <evdevmultitouch-properties.h>
63 #include <xserver-properties.h>
64 /* 1.6 has properties, but no labels */
65 #ifdef AXIS_LABEL_PROP
66 #define HAVE_LABELS
67 #else
68 #undef HAVE_LABELS
69 #endif
70
71 #endif
72
73 #ifndef MAXDEVICES
74 #include <inputstr.h> /* for MAX_DEVICES */
75 #define MAXDEVICES MAX_DEVICES
76 #endif
77
78 /* 2.4 compatibility */
79 #ifndef EVIOCGRAB
80 #define EVIOCGRAB _IOW('E', 0x90, int)
81 #endif
82
83 #ifndef BTN_TASK
84 #define BTN_TASK 0x117
85 #endif
86
87 #ifndef EV_SYN
88 #define EV_SYN EV_RST
89 #endif
90 /* end compat */
91
92 #define ArrayLength(a) (sizeof(a) / (sizeof((a)[0])))
93
94 #ifndef True
95 #define True    TRUE
96 #endif
97 #ifndef False
98 #define False FALSE
99 #endif
100
101 #define POLL_DISABLE    '0'
102 #define POLL_ENABLE             '1'
103 #define POLL_REQUEST    '2'
104 #define SYSFS_POLL      "/sys/class/input/event2/device/poll"
105
106 #define ABS_MT_SLOT             0x2f
107 #define ABS_MT_TOUCH_MAJOR      0x30    /* Major axis of touching ellipse */
108 #define ABS_MT_TOUCH_MINOR      0x31    /* Minor axis (omit if circular) */
109 #define ABS_MT_WIDTH_MAJOR      0x32    /* Major axis of approaching ellipse */
110 #define ABS_MT_WIDTH_MINOR      0x33    /* Minor axis (omit if circular) */
111 #define ABS_MT_ORIENTATION      0x34    /* Ellipse orientation */
112 #define ABS_MT_POSITION_X       0x35    /* Center X ellipse position */
113 #define ABS_MT_POSITION_Y       0x36    /* Center Y ellipse position */
114 #define ABS_MT_TOOL_TYPE        0x37    /* Type of touching device */
115 #define ABS_MT_BLOB_ID          0x38    /* Group a set of packets as a blob */
116 #define ABS_MT_TRACKING_ID              0x39    /* Unique ID of initiated contact */
117
118 #define SYN_REPORT              0
119 #define SYN_CONFIG              1
120 #define SYN_MT_REPORT           2
121
122 /* evdevmultitouch flags */
123 #define EVDEVMULTITOUCH_KEYBOARD_EVENTS (1 << 0)
124 #define EVDEVMULTITOUCH_BUTTON_EVENTS   (1 << 1)
125 #define EVDEVMULTITOUCH_RELATIVE_EVENTS (1 << 2)
126 #define EVDEVMULTITOUCH_ABSOLUTE_EVENTS (1 << 3)
127 #define EVDEVMULTITOUCH_TOUCHPAD                (1 << 4)
128 #define EVDEVMULTITOUCH_INITIALIZED     (1 << 5) /* WheelInit etc. called already? */
129 #define EVDEVMULTITOUCH_TOUCHSCREEN     (1 << 6)
130 #define EVDEVMULTITOUCH_CALIBRATED      (1 << 7) /* run-time calibrated? */
131 #define EVDEVMULTITOUCH_TABLET          (1 << 8) /* device looks like a tablet? */
132 #define EVDEVMULTITOUCH_UNIGNORE_ABSOLUTE (1 << 9) /* explicitly unignore abs axes */
133 #define EVDEVMULTITOUCH_UNIGNORE_RELATIVE (1 << 10) /* explicitly unignore rel axes */
134 #define EVDEVMULTITOUCH_MULTITOUCH (1 << 11) /* device looks like a multi-touch screen? */
135 #define EVDEVMULTITOUCH_RESOLUTION (1 << 12) /* device has a resolution setting? */
136
137 #define MIN_KEYCODE 8
138 #define GLYPHS_PER_KEY 2
139 #define AltMask         Mod1Mask
140 #define NumLockMask     Mod2Mask
141 #define AltLangMask     Mod3Mask
142 #define KanaMask        Mod4Mask
143 #define ScrollLockMask  Mod5Mask
144
145 #define CAPSFLAG        1
146 #define NUMFLAG         2
147 #define SCROLLFLAG      4
148 #define MODEFLAG        8
149 #define COMPOSEFLAG     16
150
151 static const char *evdevmultitouchDefaults[] = {
152     "XkbRules",     "evdevmultitouch",
153     "XkbModel",     "evdevmultitouch",
154     "XkbLayout",    "us",
155     NULL
156 };
157
158 int poll_control(char cmd);
159 void sync_poll(int vsync_counter);
160 #ifdef _F_GESTURE_EXTENSION_
161 extern void mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e);
162 static void EvdevMultitouchFrameSync(InputInfoPtr pInfo, MTSyncType sync);
163 #endif//_F_GESTURE_EXTENSION_
164 static void EvdevMultitouchOff(DeviceIntPtr device);
165 static int EvdevMultitouchOn(DeviceIntPtr);
166 static int EvdevMultitouchCacheCompare(InputInfoPtr pInfo, BOOL compare);
167 static void EvdevMultitouchKbdCtrl(DeviceIntPtr device, KeybdCtrl *ctrl);
168 static void EvdevMultitouchProcessSyncEvent(InputInfoPtr pInfo, struct input_event *ev);
169 static void EvdevMultitouchCopyFromData(InputInfoPtr pInfo, EvdevMultitouchDataMTPtr pData);
170 static void EvdevMultitouchReinitPEvdevMultitouch(InputInfoPtr pInfo);
171 static void EvdevMultitouchFakeOmittedEvents(InputInfoPtr pInfo);
172 static void EvdevMultitouchProcessEvent(InputInfoPtr pInfo, struct input_event *ev);
173 static void EvdevMultitouchEndOfMultiTouch(InputInfoPtr pInfo,EvdevMultitouchDataMTPtr pData);
174 static void EvdevMultitouchSetMultitouch(InputInfoPtr pInfo, int num_multitouch);
175 static void EvdevMultitouchSetUsePoll(InputInfoPtr pInfo, BOOL use_poll);
176 static void EvdevMultitouchGetGrabInfo(InputInfoPtr pInfo, BOOL val);
177 static void EvdevMultitouchSetResolution(InputInfoPtr pInfo, int num_resolution, int resolution[4]);
178 static void EvdevMultitouchSetCalibration(InputInfoPtr pInfo, int num_calibration, int calibration[4]);
179 static InputInfoPtr EvdevMultitouchCreateSubDevice(InputInfoPtr pInfo, int id);
180 static void EvdevMultitouchDeleteSubDevice(InputInfoPtr pInfo, InputInfoPtr subdev);
181 static void EvdevMultitouchSwapAxes(EvdevMultitouchPtr pEvdevMultitouch);
182 static void EvdevMultitouchSetTransform(InputInfoPtr pInfo, int num_transform, float *tmatrix);
183
184 #ifdef HAVE_PROPERTIES
185 static void EvdevMultitouchInitAxesLabels(EvdevMultitouchPtr pEvdevMultitouch, int natoms, Atom *atoms);
186 static void EvdevMultitouchInitButtonLabels(EvdevMultitouchPtr pEvdevMultitouch, int natoms, Atom *atoms);
187 static void EvdevMultitouchInitProperty(DeviceIntPtr dev);
188 static int EvdevMultitouchSetProperty(DeviceIntPtr dev, Atom atom,
189                             XIPropertyValuePtr val, BOOL checkonly);
190 static Atom prop_invert = 0;
191 static Atom prop_reopen = 0;
192 static Atom prop_calibration = 0;
193 static Atom prop_swap = 0;
194 static Atom prop_axis_label = 0;
195 static Atom prop_btn_label = 0;
196 static Atom prop_tracking_id = 0;
197 static Atom prop_multitouch = 0;
198 static Atom prop_use_poll = 0;
199 static Atom prop_transform = 0;
200 static Atom prop_grabinfo = 0;
201 #endif
202
203 static InputInfoPtr pCreatorInfo = NULL;
204 volatile VSYNC_INPUT_DISPATCH_TABLE *vsync_input_table = NULL;
205
206 int g_syspoll_fd = -1;
207 int g_pressed = 0;
208 float transform[9];
209 BOOL use_transform = False;
210 struct pixman_transform inv_transform;
211
212 int
213 poll_control(char cmd)
214 {
215         if( g_syspoll_fd < 0 )
216                 return 0;
217
218         write(g_syspoll_fd, &cmd, 1);
219
220         return 1;
221 }
222
223 void
224 sync_poll(int vsync_counter)
225 {
226         if( g_pressed )
227         {
228                 vsync_debug_set_slot("Poll before");
229                 poll_control(POLL_REQUEST);
230                 vsync_debug_set_slot("Poll after");
231         }
232 }
233
234 /* All devices the evdevmultitouch driver has allocated and knows about.
235  * MAXDEVICES is safe as null-terminated array, as two devices (VCP and VCK)
236  * cannot be used by evdevmultitouch, leaving us with a space of 2 at the end. */
237 static EvdevMultitouchPtr evdevmultitouch_devices[MAXDEVICES] = {NULL};
238
239 static size_t CountBits(unsigned long *array, size_t nlongs)
240 {
241     unsigned int i;
242     size_t count = 0;
243
244     for (i = 0; i < nlongs; i++) {
245         unsigned long x = array[i];
246
247         while (x > 0)
248         {
249             count += (x & 0x1);
250             x >>= 1;
251         }
252     }
253     return count;
254 }
255
256 static int
257 EvdevMultitouchGetMajorMinor(InputInfoPtr pInfo)
258 {
259     struct stat st;
260
261     if (fstat(pInfo->fd, &st) == -1)
262     {
263         xf86Msg(X_ERROR, "%s: stat failed (%s). cannot check for duplicates.\n",
264                 pInfo->name, strerror(errno));
265         return 0;
266     }
267
268     return st.st_rdev;
269 }
270
271 static BOOL
272 EvdevMultitouchIsCoreDevice(InputInfoPtr pInfo) {
273     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
274     return pEvdevMultitouch->core_device == pInfo;
275 }
276
277 /**
278  * Return TRUE if one of the devices we know about has the same min/maj
279  * number.
280  */
281 static BOOL
282 EvdevMultitouchIsDuplicate(InputInfoPtr pInfo)
283 {
284     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
285     EvdevMultitouchPtr* dev   = evdevmultitouch_devices;
286
287     if (pEvdevMultitouch->min_maj)
288     {
289         while(*dev)
290         {
291             if ((*dev) != pEvdevMultitouch &&
292                 (*dev)->min_maj &&
293                 (*dev)->min_maj == pEvdevMultitouch->min_maj)
294                 return TRUE;
295             dev++;
296         }
297     }
298     return FALSE;
299 }
300
301 /**
302  * Add to internal device list.
303  */
304 static void
305 EvdevMultitouchAddDevice(InputInfoPtr pInfo)
306 {
307     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
308     EvdevMultitouchPtr* dev = evdevmultitouch_devices;
309
310     while(*dev)
311         dev++;
312
313     *dev = pEvdevMultitouch;
314 }
315
316 /**
317  * Remove from internal device list.
318  */
319 static void
320 EvdevMultitouchRemoveDevice(InputInfoPtr pInfo)
321 {
322     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
323     EvdevMultitouchPtr *dev   = evdevmultitouch_devices;
324     int count       = 0;
325
326     while(*dev)
327     {
328         count++;
329         if (*dev == pEvdevMultitouch)
330         {
331             memmove(dev, dev + 1,
332                     sizeof(evdevmultitouch_devices) - (count * sizeof(EvdevMultitouchPtr)));
333             break;
334         }
335         dev++;
336     }
337 }
338
339
340 static void
341 SetXkbOption(InputInfoPtr pInfo, char *name, char **option)
342 {
343     char *s;
344
345     if ((s = xf86SetStrOption(pInfo->options, name, NULL))) {
346         if (!s[0]) {
347             free(s);
348             *option = NULL;
349         } else {
350             *option = s;
351         }
352     }
353 }
354
355 static int wheel_up_button = 4;
356 static int wheel_down_button = 5;
357 static int wheel_left_button = 6;
358 static int wheel_right_button = 7;
359
360 void
361 EvdevMultitouchQueueKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
362 {
363     int code = ev->code + MIN_KEYCODE;
364     static char warned[KEY_CNT];
365     EventQueuePtr pQueue;
366     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
367
368     /* Filter all repeated events from device.
369        We'll do softrepeat in the server, but only since 1.6 */
370     if (value == 2
371 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) <= 2
372         && (ev->code == KEY_LEFTCTRL || ev->code == KEY_RIGHTCTRL ||
373             ev->code == KEY_LEFTSHIFT || ev->code == KEY_RIGHTSHIFT ||
374             ev->code == KEY_LEFTALT || ev->code == KEY_RIGHTALT ||
375             ev->code == KEY_LEFTMETA || ev->code == KEY_RIGHTMETA ||
376             ev->code == KEY_CAPSLOCK || ev->code == KEY_NUMLOCK ||
377             ev->code == KEY_SCROLLLOCK) /* XXX windows keys? */
378 #endif
379             )
380         return;
381
382     if (code > 255)
383     {
384         if (ev->code <= KEY_MAX && !warned[ev->code])
385         {
386             xf86Msg(X_WARNING, "%s: unable to handle keycode %d\n",
387                     pInfo->name, ev->code);
388             warned[ev->code] = 1;
389         }
390
391         /* The X server can't handle keycodes > 255. */
392         return;
393     }
394
395     if (pEvdevMultitouch->num_queue >= EVDEVMULTITOUCH_MAXQUEUE)
396     {
397         xf86Msg(X_NONE, "%s: dropping event due to full queue!\n", pInfo->name);
398         return;
399     }
400
401     pQueue = &pEvdevMultitouch->queue[pEvdevMultitouch->num_queue];
402     pQueue->type = EV_QUEUE_KEY;
403     pQueue->key = code;
404     pQueue->val = value;
405     pEvdevMultitouch->num_queue++;
406 }
407
408 void
409 EvdevMultitouchQueueButtonEvent(InputInfoPtr pInfo, int button, int value)
410 {
411     EventQueuePtr pQueue;
412     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
413
414     if (pEvdevMultitouch->num_queue >= EVDEVMULTITOUCH_MAXQUEUE)
415     {
416         xf86Msg(X_NONE, "%s: dropping event due to full queue!\n", pInfo->name);
417         return;
418     }
419
420     pQueue = &pEvdevMultitouch->queue[pEvdevMultitouch->num_queue];
421     pQueue->type = EV_QUEUE_BTN;
422     pQueue->key = button;
423     pQueue->val = value;
424     pEvdevMultitouch->num_queue++;
425 }
426
427 /**
428  * Post button event right here, right now.
429  * Interface for MB emulation since these need to post immediately.
430  */
431 void
432 EvdevMultitouchPostButtonEvent(InputInfoPtr pInfo, int button, int value)
433 {
434     xf86PostButtonEvent(pInfo->dev, 0, button, value, 0, 0);
435 }
436
437 void
438 EvdevMultitouchQueueButtonClicks(InputInfoPtr pInfo, int button, int count)
439 {
440     int i;
441
442     for (i = 0; i < count; i++) {
443         EvdevMultitouchQueueButtonEvent(pInfo, button, 1);
444         EvdevMultitouchQueueButtonEvent(pInfo, button, 0);
445     }
446 }
447
448 /**
449  * 
450  */
451 static CARD32
452 EvdevMultitouchSubdevTimer(OsTimerPtr timer, CARD32 time, pointer arg)
453 {
454     InputInfoPtr pInfo = (InputInfoPtr)arg;
455     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
456     int i;
457     
458     for (i=0;i<pEvdevMultitouch->num_multitouch;i++) {
459         if (pEvdevMultitouch->vals_mt[i].containsValues) {
460             EvdevMultitouchEndOfMultiTouch(pInfo, &(pEvdevMultitouch->vals_mt[i]));
461         }
462     }
463     
464     return 0;
465     //return pEvdevMultitouch->timeout; /* come back in 100 ms */
466 }
467
468 /**
469  * Coming back from resume may leave us with a file descriptor that can be
470  * opened but fails on the first read (ENODEV).
471  * In this case, try to open the device until it becomes available or until
472  * the predefined count expires.
473  */
474 static CARD32
475 EvdevMultitouchReopenTimer(OsTimerPtr timer, CARD32 time, pointer arg)
476 {
477     InputInfoPtr pInfo = (InputInfoPtr)arg;
478     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
479
480     do {
481         pInfo->fd = open(pEvdevMultitouch->device, O_RDWR | O_NONBLOCK, 0);
482     } while (pInfo->fd < 0 && errno == EINTR);
483
484     if (pInfo->fd != -1)
485     {
486         if (EvdevMultitouchCacheCompare(pInfo, TRUE) == Success)
487         {
488             xf86Msg(X_INFO, "%s: Device reopened after %d attempts.\n", pInfo->name,
489                     pEvdevMultitouch->reopen_attempts - pEvdevMultitouch->reopen_left + 1);
490             EvdevMultitouchOn(pInfo->dev);
491         } else
492         {
493             xf86Msg(X_ERROR, "%s: Device has changed - disabling.\n",
494                     pInfo->name);
495             xf86DisableDevice(pInfo->dev, FALSE);
496             close(pInfo->fd);
497             pInfo->fd = -1;
498             pEvdevMultitouch->min_maj = 0; /* don't hog the device */
499         }
500         pEvdevMultitouch->reopen_left = 0;
501         return 0;
502     }
503
504     pEvdevMultitouch->reopen_left--;
505
506     if (!pEvdevMultitouch->reopen_left)
507     {
508         xf86Msg(X_ERROR, "%s: Failed to reopen device after %d attempts.\n",
509                 pInfo->name, pEvdevMultitouch->reopen_attempts);
510         xf86DisableDevice(pInfo->dev, FALSE);
511         pEvdevMultitouch->min_maj = 0; /* don't hog the device */
512         return 0;
513     }
514
515     return 100; /* come back in 100 ms */
516 }
517
518 static CARD32
519 EvdevMultitouchMultitouchSettingTimer(OsTimerPtr timer, CARD32 time, pointer arg)
520 {
521     InputInfoPtr pInfo = (InputInfoPtr)arg;
522     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
523
524     int n_multitouch = xf86SetIntOption(pInfo->options, "MultiTouch", 0);
525
526     if( n_multitouch >= 2 )
527             EvdevMultitouchSetMultitouch(pInfo, n_multitouch);
528     pEvdevMultitouch->multitouch_setting_timer = TimerSet(pEvdevMultitouch->multitouch_setting_timer, 0, 0, NULL, NULL);
529         
530     return 0;
531 }
532
533 #define ABS_X_VALUE 0x1
534 #define ABS_Y_VALUE 0x2
535 #define ABS_VALUE   0x4
536 #define ABS_MT_X_VALUE   0x8
537 #define ABS_MT_Y_VALUE   0x10
538 #define ABS_MT_TOUCH_MAJOR_VALUE 0x20
539 /**
540  * Take the valuators and process them accordingly.
541  */
542 static void
543 EvdevMultitouchProcessValuators(InputInfoPtr pInfo, int v[MAX_VALUATORS], int *num_v,
544                       int *first_v)
545 {
546     int tmp;
547     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
548     pixman_vector_t p;
549
550     *num_v = *first_v = 0;
551
552     /* convert to relative motion for touchpads */
553     if (pEvdevMultitouch->abs && (pEvdevMultitouch->flags & EVDEVMULTITOUCH_TOUCHPAD)) {
554         if (pEvdevMultitouch->tool) { /* meaning, touch is active */
555             if (pEvdevMultitouch->old_vals[0] != -1)
556                 pEvdevMultitouch->delta[REL_X] = pEvdevMultitouch->vals[0] - pEvdevMultitouch->old_vals[0];
557             if (pEvdevMultitouch->old_vals[1] != -1)
558                 pEvdevMultitouch->delta[REL_Y] = pEvdevMultitouch->vals[1] - pEvdevMultitouch->old_vals[1];
559             if (pEvdevMultitouch->abs & ABS_X_VALUE)
560                 pEvdevMultitouch->old_vals[0] = pEvdevMultitouch->vals[0];
561             if (pEvdevMultitouch->abs & ABS_Y_VALUE)
562                 pEvdevMultitouch->old_vals[1] = pEvdevMultitouch->vals[1];
563         } else {
564             pEvdevMultitouch->old_vals[0] = pEvdevMultitouch->old_vals[1] = -1;
565         }
566         pEvdevMultitouch->abs = 0;
567         pEvdevMultitouch->rel = 1;
568     }
569
570     if (pEvdevMultitouch->rel) {
571         int first = REL_CNT, last = 0;
572         int i;
573
574         if (pEvdevMultitouch->swap_axes) {
575             tmp = pEvdevMultitouch->delta[REL_X];
576             pEvdevMultitouch->delta[REL_X] = pEvdevMultitouch->delta[REL_Y];
577             pEvdevMultitouch->delta[REL_Y] = tmp;
578         }
579         if (pEvdevMultitouch->invert_x)
580             pEvdevMultitouch->delta[REL_X] *= -1;
581         if (pEvdevMultitouch->invert_y)
582             pEvdevMultitouch->delta[REL_Y] *= -1;
583
584         for (i = 0; i < REL_CNT; i++)
585         {
586             int map = pEvdevMultitouch->axis_map[i];
587             if (map != -1)
588             {
589                 v[map] = pEvdevMultitouch->delta[i];
590                 if (map < first)
591                     first = map;
592                 if (map > last)
593                     last = map;
594             }
595         }
596
597         *num_v = (last - first + 1);
598         *first_v = first;
599     }
600     /*
601      * Some devices only generate valid abs coords when BTN_DIGI is
602      * pressed.  On wacom tablets, this means that the pen is in
603      * proximity of the tablet.  After the pen is removed, BTN_DIGI is
604      * released, and a (0, 0) absolute event is generated.  Checking
605      * pEvdevMultitouch->digi here, lets us ignore that event.  pEvdevMultitouch is
606      * initialized to 1 so devices that doesn't use this scheme still
607      * just works.
608      */
609     else if (pEvdevMultitouch->abs && pEvdevMultitouch->tool) {
610         memcpy(v, pEvdevMultitouch->vals, sizeof(int) * pEvdevMultitouch->num_vals);
611         if (pEvdevMultitouch->flags & EVDEVMULTITOUCH_CALIBRATED)
612         {
613             v[0] = xf86ScaleAxis(v[0],
614                     pEvdevMultitouch->absinfo[ABS_X].maximum,
615                     pEvdevMultitouch->absinfo[ABS_X].minimum,
616                     pEvdevMultitouch->calibration.max_x, pEvdevMultitouch->calibration.min_x);
617             v[1] = xf86ScaleAxis(v[1],
618                     pEvdevMultitouch->absinfo[ABS_Y].maximum,
619                     pEvdevMultitouch->absinfo[ABS_Y].minimum,
620                     pEvdevMultitouch->calibration.max_y, pEvdevMultitouch->calibration.min_y);
621         }
622
623         if (pEvdevMultitouch->swap_axes) {
624             int tmp = v[0];
625             v[0] = v[1];
626             v[1] = tmp;
627         }
628
629         if (pEvdevMultitouch->invert_x)
630             v[0] = (pEvdevMultitouch->absinfo[ABS_X].maximum - v[0] +
631                     pEvdevMultitouch->absinfo[ABS_X].minimum);
632         if (pEvdevMultitouch->invert_y)
633             v[1] = (pEvdevMultitouch->absinfo[ABS_Y].maximum - v[1] +
634                     pEvdevMultitouch->absinfo[ABS_Y].minimum);
635
636         if( use_transform )
637         {
638                 p.vector[0] = pixman_int_to_fixed(v[0]);
639                 p.vector[1] = pixman_int_to_fixed(v[1]);
640                 p.vector[2] = pixman_int_to_fixed(1);
641
642                 pixman_transform_point(&inv_transform, &p);
643
644                 v[0] = pixman_fixed_to_int(p.vector[0]);
645                 v[1] = pixman_fixed_to_int(p.vector[1]);
646         }
647
648         *num_v = pEvdevMultitouch->num_vals;
649         *first_v = 0;
650     }
651 }
652
653 /**
654  * Take a button input event and process it accordingly.
655  */
656 static void
657 EvdevMultitouchProcessButtonEvent(InputInfoPtr pInfo, struct input_event *ev)
658 {
659     unsigned int button;
660     int value;
661     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
662
663     button = EvdevMultitouchUtilButtonEventToButtonNumber(pEvdevMultitouch, ev->code);
664
665     /* Get the signed value, earlier kernels had this as unsigned */
666     value = ev->value;
667
668     /* Handle drag lock */
669     if (EvdevMultitouchDragLockFilterEvent(pInfo, button, value))
670         return;
671
672     if (EvdevMultitouchWheelEmuFilterButton(pInfo, button, value))
673         return;
674
675     if (pEvdevMultitouch->num_multitouch)
676         return;
677     
678     if (EvdevMultitouchMBEmuFilterEvent(pInfo, button, value))
679         return;
680
681     if (button)
682         EvdevMultitouchQueueButtonEvent(pInfo, button, value);
683     else
684         EvdevMultitouchQueueKbdEvent(pInfo, ev, value);
685 }
686
687 /**
688  * Take the relative motion input event and process it accordingly.
689  */
690 static void
691 EvdevMultitouchProcessRelativeMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
692 {
693     static int value;
694     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
695
696     /* Get the signed value, earlier kernels had this as unsigned */
697     value = ev->value;
698
699     pEvdevMultitouch->rel = 1;
700
701     switch (ev->code) {
702         case REL_WHEEL:
703             if (value > 0)
704                 EvdevMultitouchQueueButtonClicks(pInfo, wheel_up_button, value);
705             else if (value < 0)
706                 EvdevMultitouchQueueButtonClicks(pInfo, wheel_down_button, -value);
707             break;
708
709         case REL_DIAL:
710         case REL_HWHEEL:
711             if (value > 0)
712                 EvdevMultitouchQueueButtonClicks(pInfo, wheel_right_button, value);
713             else if (value < 0)
714                 EvdevMultitouchQueueButtonClicks(pInfo, wheel_left_button, -value);
715             break;
716
717         /* We don't post wheel events as axis motion. */
718         default:
719             /* Ignore EV_REL events if we never set up for them. */
720             if (!(pEvdevMultitouch->flags & EVDEVMULTITOUCH_RELATIVE_EVENTS))
721                 return;
722
723             /* Handle mouse wheel emulation */
724             if (EvdevMultitouchWheelEmuFilterMotion(pInfo, ev))
725                 return;
726
727             pEvdevMultitouch->delta[ev->code] += value;
728             break;
729     }
730 }
731
732 /**
733  * Take the absolute motion input event and process it accordingly.
734  */
735 static void
736 EvdevMultitouchProcessAbsoluteMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
737 {
738     static int value;
739     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
740
741     /* Get the signed value, earlier kernels had this as unsigned */
742     value = ev->value;
743
744     /* Ignore EV_ABS events if we never set up for them. */
745     if (!(pEvdevMultitouch->flags & EVDEVMULTITOUCH_ABSOLUTE_EVENTS))
746         return;
747
748     if (ev->code > ABS_MAX)
749         return;
750
751     pEvdevMultitouch->vals[pEvdevMultitouch->axis_map[ev->code]] = value;
752
753     if(pEvdevMultitouch->flags & EVDEVMULTITOUCH_MULTITOUCH)
754     {
755         if(ev->code == ABS_MT_TOUCH_MAJOR)
756          {
757 #ifdef _DEBUG_MT_SEQUENCE_
758              ErrorF("[AbsoluteMotionEvent] ABS_MT_TOUCH_MAJOR (value=%d)\n", value);
759 #endif
760             pEvdevMultitouch->abs |= ABS_MT_TOUCH_MAJOR_VALUE;
761          }
762         else if (ev->code == ABS_MT_POSITION_X)
763          {
764 #ifdef _DEBUG_MT_SEQUENCE_
765              ErrorF("[AbsoluteMotionEvent] ABS_MT_POSITION_X (value=%d)\n", value);
766 #endif
767              EvdevMultitouchFakeOmittedEvents(pInfo);
768             pEvdevMultitouch->abs |= ABS_MT_X_VALUE;
769          }
770         else if (ev->code == ABS_MT_POSITION_Y)
771          {
772 #ifdef _DEBUG_MT_SEQUENCE_
773              ErrorF("[AbsoluteMotionEvent] ABS_MT_POSITION_Y (value=%d)\n", value);
774 #endif
775              EvdevMultitouchFakeOmittedEvents(pInfo);
776             pEvdevMultitouch->abs |= ABS_MT_Y_VALUE;
777          }
778         else
779             pEvdevMultitouch->abs |= ABS_VALUE;
780     }
781     else
782     {
783         if (ev->code == ABS_X)
784          {
785 #ifdef _DEBUG_MT_SEQUENCE_
786              ErrorF("[AbsoluteMotionEvent] ABS_X (value=%d)\n", value);
787 #endif
788             pEvdevMultitouch->abs |= ABS_X_VALUE;
789          }
790         else if (ev->code == ABS_Y)
791          {
792 #ifdef _DEBUG_MT_SEQUENCE_
793              ErrorF("[AbsoluteMotionEvent] ABS_Y (value=%d)\n", value);
794 #endif
795             pEvdevMultitouch->abs |= ABS_Y_VALUE;
796          }
797         else
798             pEvdevMultitouch->abs |= ABS_VALUE;
799     }        
800 }
801
802 /**
803  * Take the key press/release input event and process it accordingly.
804  */
805 static void
806 EvdevMultitouchProcessKeyEvent(InputInfoPtr pInfo, struct input_event *ev)
807 {
808     static int value;
809     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
810
811     if(pEvdevMultitouch->flags & EVDEVMULTITOUCH_MULTITOUCH)
812         return;
813
814     /* Get the signed value, earlier kernels had this as unsigned */
815     value = ev->value;
816
817     /* don't repeat mouse buttons */
818     if (ev->code >= BTN_MOUSE && ev->code < KEY_OK)
819         if (value == 2)
820             return;
821
822 #ifdef _DEBUG_MT_SEQUENCE_
823         if( ev->code == BTN_TOUCH || ev->code == BTN_LEFT )
824                 ErrorF("[KeyEvent] BTN_TOUCH (value=%d)\n", value);
825 #endif
826
827     switch (ev->code) {
828         case BTN_TOUCH:
829         case BTN_TOOL_PEN:
830         case BTN_TOOL_RUBBER:
831         case BTN_TOOL_BRUSH:
832         case BTN_TOOL_PENCIL:
833         case BTN_TOOL_AIRBRUSH:
834         case BTN_TOOL_FINGER:
835         case BTN_TOOL_MOUSE:
836         case BTN_TOOL_LENS:
837             pEvdevMultitouch->tool = value ? ev->code : 0;
838             if (!(pEvdevMultitouch->flags & EVDEVMULTITOUCH_TOUCHSCREEN || pEvdevMultitouch->flags & EVDEVMULTITOUCH_MULTITOUCH))
839                 break;
840             /* Treat BTN_TOUCH from devices that only have BTN_TOUCH as
841              * BTN_LEFT. */
842             ev->code = BTN_LEFT;
843             /* Intentional fallthrough! */
844
845         default:
846             EvdevMultitouchProcessButtonEvent(pInfo, ev);
847             break;
848     }
849 }
850
851 static void EvdevMultitouchEndOfMultiTouch(InputInfoPtr pInfo,EvdevMultitouchDataMTPtr pData)
852 {
853     InputInfoPtr pSubdev = pData->pInfo;
854     EvdevMultitouchPtr pEvdevMultitouchSubdev = pSubdev->private;
855     pEvdevMultitouchSubdev->id = -1;
856     pData->containsValues = FALSE;
857     pData->id = -1;
858 }
859
860 #ifdef _F_GESTURE_EXTENSION_
861 static void EvdevMultitouchFrameSync(InputInfoPtr pInfo, MTSyncType sync)
862 {
863         AnyEvent event;
864
865         memset(&event, 0, sizeof(event));
866         event.header = ET_Internal;
867         event.type = ET_MTSync;
868         event.length = sizeof(event);
869         event.time = GetTimeInMillis();
870         event.deviceid = pInfo->dev->id;
871         event.sync = sync;
872         mieqEnqueue (pInfo->dev, (InternalEvent*)&event);
873 }
874 #endif//_F_GESTURE_EXTENSION_
875
876 /**
877  * Post the multtouch motion events.
878  */
879 static void
880 EvdevMultitouchPostMTMotionEvents(InputInfoPtr pInfo,struct input_event *ev)
881 {
882     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private, pEvdevMultitouchSubdev;
883     EvdevMultitouchDataMTPtr pData;
884     InputInfoPtr pSubdev;
885     int i;
886     static int num_of_pressed = 0;
887
888     for (i=0;i<pEvdevMultitouch->num_multitouch;++i) {
889         pData = &(pEvdevMultitouch->vals_mt[i]);
890         if (!pData->containsValues) {
891             continue;
892         }
893         pSubdev = pData->pInfo;
894         if (!pSubdev)
895             continue;
896
897         pData->containsValues = FALSE;
898         EvdevMultitouchCopyFromData(pSubdev, pData);
899         pEvdevMultitouchSubdev = pSubdev->private;
900         pEvdevMultitouchSubdev->mt = 0;
901         pEvdevMultitouchSubdev->abs = pData->abs;
902         pEvdevMultitouchSubdev->rel = 0;
903         pEvdevMultitouchSubdev->tool = 1;
904         /* droping of the pressed/released events */
905         memset(pEvdevMultitouchSubdev->queue, 0, sizeof(pEvdevMultitouchSubdev->queue));
906         pEvdevMultitouchSubdev->num_queue = 0;
907
908         /* generate button press/release event */
909         if(pEvdevMultitouchSubdev->abs & ABS_MT_TOUCH_MAJOR_VALUE)
910         {
911             if(pEvdevMultitouchSubdev->vals[pEvdevMultitouchSubdev->axis_map[ABS_MT_TOUCH_MAJOR]] )
912             {
913                 if(pEvdevMultitouchSubdev->touch_state == 0)
914                 {
915                         num_of_pressed += (pData->id+1);
916                         if( num_of_pressed && !g_pressed )
917                         {
918                            g_pressed = 1;
919 #ifdef _F_GESTURE_EXTENSION_
920                            EvdevMultitouchFrameSync(pInfo, MTOUCH_FRAME_SYNC_BEGIN);
921 #endif//_F_GESTURE_EXTENSION_
922                           if(vsync_input_table)
923                          {
924                                 vsync_input_table->start_sync(vsync_input_table->sync_arg);
925                                 vsync_debug_start();
926                             }
927                         }
928                     EvdevMultitouchQueueButtonEvent(pSubdev, 1, 1);
929                     pEvdevMultitouchSubdev->touch_state = 1;
930                 }
931             }
932             else
933             {
934                   num_of_pressed -= (pData->id+1);
935                   /* last finger release */
936                   if( !num_of_pressed )
937                   {
938                         g_pressed = 0;
939                        if(vsync_input_table)
940                         {
941                                 vsync_input_table->stop_sync(vsync_input_table->sync_arg);
942                                 vsync_debug_stop();
943                         }
944                   }
945                 EvdevMultitouchQueueButtonEvent(pSubdev, 1, 0);
946                 pEvdevMultitouchSubdev->touch_state = 0;
947                 pEvdevMultitouchSubdev->evtime = 0;
948             }
949         }
950         EvdevMultitouchProcessSyncEvent(pSubdev, ev);
951         
952     }
953 }
954
955 static void
956 EvdevMultitouchPostMTMotionEventsBySingle(InputInfoPtr pInfo,struct input_event *ev)
957 {
958     EvdevMultitouchPtr pEvdevMultitouch, pEvdevMultitouchSubdev;
959     EvdevMultitouchDataMTPtr pData;
960     InputInfoPtr pSubdev;
961
962     if( !pInfo || !pInfo->private )
963         return;
964
965     pEvdevMultitouch = pInfo->private;
966
967     pData = &(pEvdevMultitouch->vals_mt[0]);
968
969     if (!pData->containsValues) {
970         return;
971     }
972     
973     pSubdev = pInfo;
974     pData->containsValues = FALSE;
975     EvdevMultitouchCopyFromData(pSubdev, pData);
976     pEvdevMultitouchSubdev = pSubdev->private;
977     pEvdevMultitouchSubdev->mt = 0;
978     pEvdevMultitouchSubdev->abs = pData->abs;
979     pEvdevMultitouchSubdev->rel = 0;
980     pEvdevMultitouchSubdev->tool = 1;
981     /* droping of the pressed/released events */
982     memset(pEvdevMultitouchSubdev->queue, 0, sizeof(pEvdevMultitouchSubdev->queue));
983     pEvdevMultitouchSubdev->num_queue = 0;
984
985     /* generate button press/release event */
986     if(pEvdevMultitouchSubdev->abs & ABS_MT_TOUCH_MAJOR_VALUE)
987     {
988         if(pEvdevMultitouchSubdev->vals[pEvdevMultitouchSubdev->axis_map[ABS_MT_TOUCH_MAJOR]] )
989         {
990             if(pEvdevMultitouchSubdev->touch_state == 0)
991             {
992                 EvdevMultitouchQueueButtonEvent(pSubdev, 1, 1);
993                 pEvdevMultitouchSubdev->touch_state = 1;
994                   g_pressed = 1;
995 #ifdef _F_GESTURE_EXTENSION_
996                   EvdevMultitouchFrameSync(pInfo, MTOUCH_FRAME_SYNC_BEGIN);
997 #endif//_F_GESTURE_EXTENSION_
998                   if(vsync_input_table)
999                 {
1000                         vsync_input_table->start_sync(vsync_input_table->sync_arg);
1001                         vsync_debug_start();
1002                    }
1003             }
1004         }
1005         else
1006         {
1007              g_pressed = 0;
1008              if(vsync_input_table)
1009              {
1010                    vsync_input_table->stop_sync(vsync_input_table->sync_arg);
1011                    vsync_debug_stop();
1012              }
1013             EvdevMultitouchQueueButtonEvent(pSubdev, 1, 0);
1014             pEvdevMultitouchSubdev->touch_state = 0;
1015             pEvdevMultitouchSubdev->evtime = 0;
1016         }
1017     }
1018
1019     EvdevMultitouchProcessSyncEvent(pSubdev, ev);
1020 }
1021
1022 /**
1023  * Post the relative motion events.
1024  */
1025 void
1026 EvdevMultitouchPostRelativeMotionEvents(InputInfoPtr pInfo, int *num_v, int *first_v,
1027                               int v[MAX_VALUATORS])
1028 {
1029     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
1030
1031     if (pEvdevMultitouch->rel) {
1032         xf86PostMotionEventP(pInfo->dev, FALSE, *first_v, *num_v, v + *first_v);
1033     }
1034 }
1035
1036 /**
1037  * Post the absolute motion events.
1038  */
1039 void
1040 EvdevMultitouchPostAbsoluteMotionEvents(InputInfoPtr pInfo, int *num_v, int *first_v,
1041                               int v[MAX_VALUATORS])
1042 {
1043     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
1044
1045     /*
1046      * Some devices only generate valid abs coords when BTN_DIGI is
1047      * pressed.  On wacom tablets, this means that the pen is in
1048      * proximity of the tablet.  After the pen is removed, BTN_DIGI is
1049      * released, and a (0, 0) absolute event is generated.  Checking
1050      * pEvdevMultitouch->digi here, lets us ignore that event.  pEvdevMultitouch is
1051      * initialized to 1 so devices that doesn't use this scheme still
1052      * just works.
1053      */
1054     if (pEvdevMultitouch->abs && pEvdevMultitouch->tool) {
1055         xf86PostMotionEventP(pInfo->dev, TRUE, *first_v, *num_v, v);
1056     }
1057 }
1058
1059 /**
1060  * Post the queued key/button events.
1061  */
1062 static void EvdevMultitouchPostQueuedEvents(InputInfoPtr pInfo, int *num_v, int *first_v,
1063                                   int v[MAX_VALUATORS])
1064 {
1065     int i;
1066     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
1067
1068     for (i = 0; i < pEvdevMultitouch->num_queue; i++) {
1069         switch (pEvdevMultitouch->queue[i].type) {
1070         case EV_QUEUE_KEY:
1071             xf86PostKeyboardEvent(pInfo->dev, pEvdevMultitouch->queue[i].key,
1072                                   pEvdevMultitouch->queue[i].val);
1073             break;
1074         case EV_QUEUE_BTN:
1075             /* FIXME: Add xf86PostButtonEventP to the X server so that we may
1076              * pass the valuators on ButtonPress/Release events, too.  Currently
1077              * only MotionNotify events contain the pointer position. */
1078             xf86PostButtonEvent(pInfo->dev, 0, pEvdevMultitouch->queue[i].key,
1079                                 pEvdevMultitouch->queue[i].val, 0, 0);
1080             break;
1081         }
1082     }
1083 }
1084 static void
1085 EvdevMultitouchCopyFromData(InputInfoPtr pInfo, EvdevMultitouchDataMTPtr pData) {
1086     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
1087     memcpy(pEvdevMultitouch->vals, pData->vals, MAX_VALUATORS * sizeof(int));
1088     /* we drop the buttons/key events */
1089 }
1090
1091 static void
1092 EvdevMultitouchStoreMTData(InputInfoPtr pInfo, EvdevMultitouchDataMTPtr pData) {
1093     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
1094     int id,x,y;
1095     Time currentTime = GetTimeInMillis();
1096
1097     id = pEvdevMultitouch->current_id;
1098
1099     if(pEvdevMultitouch->abs & ABS_MT_X_VALUE)
1100         x = pEvdevMultitouch->vals[pEvdevMultitouch->axis_map[ABS_MT_POSITION_X]];
1101     else
1102         x = pData->vals[pEvdevMultitouch->axis_map[ABS_X]]; 
1103         
1104     if(pEvdevMultitouch->abs & ABS_MT_Y_VALUE)    
1105         y = pEvdevMultitouch->vals[pEvdevMultitouch->axis_map[ABS_MT_POSITION_Y]];
1106     else
1107         y = pData->vals[pEvdevMultitouch->axis_map[ABS_Y]];
1108
1109     {
1110         EvdevMultitouchPtr pEvdevMultitouchSub = pData->pInfo->private;
1111         pEvdevMultitouchSub->evtime = currentTime;
1112     }
1113
1114     pData->id = id;
1115     memcpy(pData->vals, pEvdevMultitouch->vals, MAX_VALUATORS * sizeof(int));
1116     pData->vals[pEvdevMultitouch->axis_map[ABS_X]] = x;
1117     pData->vals[pEvdevMultitouch->axis_map[ABS_Y]] = y;
1118     pData->containsValues = TRUE;
1119     pData->expires = currentTime + pEvdevMultitouch->timeout;
1120     pData->abs = pEvdevMultitouch->abs;
1121
1122     return;
1123 }
1124
1125 /**
1126  * Take the synchronization input event and process it accordingly; the motion
1127  * notify events are sent first, then any button/key press/release events.
1128  */
1129 static void
1130 EvdevMultitouchProcessMTSyncReport(InputInfoPtr pInfo, struct input_event *ev)
1131 {
1132     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
1133     int id;
1134
1135     id = pEvdevMultitouch->current_id;
1136     
1137     if (id < 0) {
1138         EvdevMultitouchReinitPEvdevMultitouch(pInfo);
1139         return;
1140     }
1141
1142     if(pEvdevMultitouch->num_multitouch == 0) //Single mode
1143     {
1144         if(id != 0)
1145         {
1146             EvdevMultitouchReinitPEvdevMultitouch(pInfo);
1147             return;
1148         }
1149     }
1150     else
1151     {
1152         if (id > pEvdevMultitouch->num_multitouch-1)
1153         {
1154             EvdevMultitouchReinitPEvdevMultitouch(pInfo);
1155             return;
1156         }      
1157     }
1158
1159     EvdevMultitouchStoreMTData(pInfo, &(pEvdevMultitouch->vals_mt[id]));
1160     EvdevMultitouchReinitPEvdevMultitouch(pInfo);
1161     pEvdevMultitouch->mt = 1;
1162     pEvdevMultitouch->sync_mt = 1;
1163 }
1164
1165 static void
1166 EvdevMultitouchReinitPEvdevMultitouch(InputInfoPtr pInfo) {
1167     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
1168
1169     memset(pEvdevMultitouch->delta, 0, sizeof(pEvdevMultitouch->delta));
1170     memset(pEvdevMultitouch->queue, 0, sizeof(pEvdevMultitouch->queue));
1171     pEvdevMultitouch->num_queue = 0;
1172     pEvdevMultitouch->abs = 0;
1173     pEvdevMultitouch->rel = 0;
1174     pEvdevMultitouch->mt = 0;
1175     pEvdevMultitouch->num_mt = 0;
1176     pEvdevMultitouch->current_id = -1;
1177     pEvdevMultitouch->sync_mt = 0;
1178 }
1179
1180 /**
1181  * Take the synchronization input event and process it accordingly; the motion
1182  * notify events are sent first, then any button/key press/release events.
1183  */
1184 static void
1185 EvdevMultitouchProcessSyncEvent(InputInfoPtr pInfo, struct input_event *ev)
1186 {
1187     int num_v = 0, first_v = 0;
1188     int v[MAX_VALUATORS];
1189     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
1190     
1191     if (ev->code == SYN_MT_REPORT) {
1192         EvdevMultitouchProcessMTSyncReport(pInfo, ev);
1193         return;
1194     }
1195
1196     if( 0 <= pEvdevMultitouch->current_id && !pEvdevMultitouch->sync_mt )
1197     {
1198 #ifdef _DEBUG_MT_SEQUENCE_
1199         if( pEvdevMultitouch->vals[pEvdevMultitouch->axis_map[ABS_MT_TOUCH_MAJOR]] )
1200                 ErrorF("[SyncEvent] Press or Motion !(current->id=%d)\n", pEvdevMultitouch->current_id);
1201         else
1202                 ErrorF("[SyncEvent] Release!(current->id=%d)\n\n", pEvdevMultitouch->current_id);
1203 #endif
1204
1205         EvdevMultitouchProcessMTSyncReport(pInfo, ev);
1206     }
1207
1208     if (pEvdevMultitouch->mt) {
1209         if(pEvdevMultitouch->num_multitouch > 1)
1210          {
1211             EvdevMultitouchPostMTMotionEvents(pInfo, ev);
1212          }
1213         else
1214         {
1215             EvdevMultitouchPostMTMotionEventsBySingle(pInfo, ev);
1216         }
1217     } else {
1218         EvdevMultitouchProcessValuators(pInfo, v, &num_v, &first_v);
1219
1220          vsync_debug_set_slot("Input %d %d %d", 1, v[0], v[1]);
1221
1222         EvdevMultitouchPostRelativeMotionEvents(pInfo, &num_v, &first_v, v);
1223         EvdevMultitouchPostAbsoluteMotionEvents(pInfo, &num_v, &first_v, v);
1224         EvdevMultitouchPostQueuedEvents(pInfo, &num_v, &first_v, v);
1225 #ifdef _F_GESTURE_EXTENSION_
1226         if( !g_pressed )
1227             EvdevMultitouchFrameSync(pInfo, MTOUCH_FRAME_SYNC_END);
1228 #endif//_F_GESTURE_EXTENSION_
1229     }
1230     
1231     EvdevMultitouchReinitPEvdevMultitouch(pInfo);
1232 }
1233
1234 /**
1235  * Take the trackingID input event and process it accordingly.
1236  */
1237 static void
1238 EvdevMultitouchProcessTrackingIDEvent(InputInfoPtr pInfo, struct input_event *ev)
1239 {
1240     // begining of a new touch
1241     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
1242
1243     pEvdevMultitouch->last_slot = pEvdevMultitouch->current_id = ev->value;
1244 #ifdef _DEBUG_MT_SEQUENCE_
1245     ErrorF("[TrackingIDEvent] current_id=%d, last_slot=%d\n", pEvdevMultitouch->current_id, pEvdevMultitouch->last_slot);
1246 #endif
1247 }
1248
1249 /**
1250  * Process the events from the device; nothing is actually posted to the server
1251  * until an EV_SYN event is received.
1252  */
1253 static char* ev_name(int type, int code, int value)
1254 {
1255    static char ename[100];
1256
1257    char *stype = NULL;
1258    char *scode = NULL;
1259    char *svalue = NULL;
1260
1261    char ttype[50];
1262    char tcode[50];
1263    char tvalue[50];
1264    
1265    switch(type)
1266    {
1267    case EV_SYN:
1268       stype = "EV_SYNC";
1269       switch(code)
1270       {
1271       case SYN_REPORT:
1272          scode = "SYN_REPORT";
1273          break;
1274       case SYN_CONFIG:
1275          scode = "SYN_CONFIG";
1276          break;
1277       case SYN_MT_REPORT:
1278          scode = "SYN_MT_REPORT";
1279          break;
1280       }
1281       break;
1282    case EV_KEY:
1283       stype = "EV_KEY";
1284       break;
1285    case EV_REL:
1286       stype = "EV_REL";
1287       break;
1288    case EV_ABS:
1289       stype = "EV_ABS";
1290       switch(code)
1291       {
1292       case ABS_X:
1293          scode =  "ABS_X";
1294          break;
1295       case ABS_Y:
1296          scode =  "ABS_Y";
1297          break;
1298       case ABS_PRESSURE:
1299          scode =  "ABS_PRESSURE";
1300          break;
1301       case ABS_MT_TOUCH_MAJOR:
1302          scode =  "ABS_MT_TOUCH_MAJOR";
1303          break;
1304       case ABS_MT_TOUCH_MINOR:
1305          scode =  "ABS_MT_TOUCH_MINOR";
1306          break;
1307       case ABS_MT_WIDTH_MAJOR:
1308          scode =  "ABS_MT_WIDTH_MAJOR";
1309          break;
1310       case ABS_MT_WIDTH_MINOR:
1311          scode =  "ABS_MT_WIDTH_MINOR";
1312          break;
1313       case ABS_MT_ORIENTATION:
1314          scode =  "ABS_MT_ORIENTATION";
1315          break;
1316       case ABS_MT_POSITION_X:
1317          scode =  "ABS_MT_POSITION_X";
1318          break;
1319       case ABS_MT_POSITION_Y:
1320          scode =  "ABS_MT_POSITION_Y";
1321          break;
1322       case ABS_MT_TOOL_TYPE:
1323          scode =  "ABS_MT_TOOL_TYPE";
1324          break;
1325       case ABS_MT_BLOB_ID:
1326          scode =  "ABS_MT_BLOB_ID";
1327          break;
1328       case ABS_MT_TRACKING_ID:
1329          scode =  "ABS_MT_TRACKING_ID";
1330          break;
1331       case ABS_MT_SLOT:
1332          scode =  "ABS_MT_SLOT";
1333          break;
1334       }
1335    default:
1336       break;
1337    }
1338
1339    if(!stype)
1340    {
1341       sprintf(ttype, "T(0x%x)", type);
1342       stype = ttype;
1343    }
1344
1345    if(!scode)
1346    {
1347       sprintf(tcode, "C(0x%x)", code);
1348       scode = tcode;
1349    }
1350
1351    if(!svalue)
1352    {
1353       sprintf(tvalue, "V(%d)",value);
1354       svalue = tvalue;
1355    }
1356
1357    sprintf(ename, "%s : %s : %s", stype, scode, svalue);
1358    return ename;
1359 }
1360
1361 static void EvdevMultitouchFakeOmittedEvents(InputInfoPtr pInfo)
1362 {
1363         EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
1364
1365         if( !(pEvdevMultitouch->abs & ABS_MT_TOUCH_MAJOR_VALUE) )
1366         {
1367                 pEvdevMultitouch->vals[pEvdevMultitouch->axis_map[ABS_MT_TOUCH_MAJOR]] = 1;
1368                 pEvdevMultitouch->abs |= ABS_MT_TOUCH_MAJOR_VALUE;
1369 #ifdef _DEBUG_MT_SEQUENCE_
1370                 ErrorF("\t...Fake ABS_MT_TOUCH_MAJOR\n");
1371 #endif
1372         }
1373
1374         if( pEvdevMultitouch->current_id < 0 )
1375         {
1376                 pEvdevMultitouch->current_id = pEvdevMultitouch->last_slot;
1377 #ifdef _DEBUG_MT_SEQUENCE_
1378                 ErrorF("\t...Fake ABS_MT_SLOT (current_id=%d)\n", pEvdevMultitouch->current_id);
1379 #endif
1380         }
1381 }
1382
1383 static void
1384 EvdevMultitouchProcessEvent(InputInfoPtr pInfo, struct input_event *ev)
1385 {
1386     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
1387         
1388     switch (ev->type) {
1389         case EV_REL:
1390             return;
1391             EvdevMultitouchProcessRelativeMotionEvent(pInfo, ev);
1392             break;
1393         case EV_ABS:
1394             switch(ev->code)
1395             {
1396             case ABS_X:
1397             case ABS_Y:
1398             case ABS_PRESSURE:
1399                 return;
1400             }
1401                         
1402              if( ev->code == ABS_MT_TRACKING_ID )
1403              {
1404 #ifdef _DEBUG_MT_SEQUENCE_
1405                   ErrorF("[ProcessEvent] ABS_MT_TRACKING_ID (value=%d)\n", ev->value);
1406 #endif
1407
1408                   if( pEvdevMultitouch->mt_slot_supported )
1409                   {//MT protocol B Type
1410                          if( pEvdevMultitouch->current_id < 0 )
1411                          {
1412                                 pEvdevMultitouch->current_id = pEvdevMultitouch->last_slot;
1413                          }
1414                           
1415                          if( 0 > ev->value )//ABS_MT_TRACKING_ID == -1
1416                           {
1417 #ifdef _DEBUG_MT_SEQUENCE_
1418                               ErrorF("\t...Fake ABS_MT_TOUCH_MAJOR\n");
1419 #endif
1420                                 pEvdevMultitouch->vals[pEvdevMultitouch->axis_map[ABS_MT_TOUCH_MAJOR]] = 0;
1421                                 pEvdevMultitouch->abs |= ABS_MT_TOUCH_MAJOR_VALUE;
1422                           }
1423                   }
1424                   else
1425                   {//MT protocol A Type
1426                           EvdevMultitouchProcessTrackingIDEvent(pInfo, ev);
1427                   }
1428              }
1429                  
1430             if (ev->code == ABS_MT_SLOT)
1431              {
1432 #ifdef _DEBUG_MT_SEQUENCE_
1433                   ErrorF("[ProcessEvent] ABS_MT_SLOT (value=%d)\n", ev->value);
1434 #endif
1435                   if( pEvdevMultitouch->last_slot != ev->value )
1436                  {
1437                         ev->code = SYN_REPORT;
1438                         EvdevMultitouchProcessSyncEvent(pInfo, ev);
1439                         ev->code = ABS_MT_SLOT;
1440                  }
1441
1442                 EvdevMultitouchProcessTrackingIDEvent(pInfo, ev);
1443             }
1444              else
1445              {
1446                 EvdevMultitouchProcessAbsoluteMotionEvent(pInfo, ev);
1447             }
1448             break;
1449         case EV_KEY:
1450             return;
1451             EvdevMultitouchProcessKeyEvent(pInfo, ev);
1452             break;
1453         case EV_SYN:
1454 #ifdef _DEBUG_MT_SEQUENCE_
1455              if( ev->code == SYN_MT_REPORT )
1456                 ErrorF("[ProcessEvent] SYN_MT_REPORT (value=%d)\n", ev->value);
1457              else
1458                 ErrorF("[ProcessEvent] SYN_REPORT (value=%d)\n", ev->value);
1459 #endif
1460             EvdevMultitouchProcessSyncEvent(pInfo, ev);
1461             break;
1462     }
1463 }
1464
1465 #undef ABS_X_VALUE
1466 #undef ABS_Y_VALUE
1467 #undef ABS_VALUE
1468
1469 /* just a magic number to reduce the number of reads */
1470 #define NUM_EVENTS 16
1471
1472 /**
1473  * Empty callback for subdevice.
1474  */
1475 static void
1476 EvdevMultitouchSubdevReadInput(InputInfoPtr pInfo) {
1477     return;
1478 }
1479
1480 static void
1481 EvdevMultitouchReadInput(InputInfoPtr pInfo)
1482 {
1483     struct input_event ev[NUM_EVENTS];
1484     int i, len = sizeof(ev);
1485     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
1486
1487     while (len == sizeof(ev))
1488     {
1489         len = read(pInfo->fd, &ev, sizeof(ev));
1490         if (len <= 0)
1491         {
1492             if (errno == ENODEV) /* May happen after resume */
1493             {
1494                 EvdevMultitouchMBEmuFinalize(pInfo);
1495                 xf86RemoveEnabledDevice(pInfo);
1496                 close(pInfo->fd);
1497                 pInfo->fd = -1;
1498                 if (pEvdevMultitouch->reopen_timer)
1499                 {
1500                     pEvdevMultitouch->reopen_left = pEvdevMultitouch->reopen_attempts;
1501                     pEvdevMultitouch->reopen_timer = TimerSet(pEvdevMultitouch->reopen_timer, 0, 100, EvdevMultitouchReopenTimer, pInfo);
1502                 }
1503             } else if (errno != EAGAIN)
1504             {
1505                 /* We use X_NONE here because it doesn't alloc */
1506                 xf86MsgVerb(X_NONE, 0, "%s: Read error: %s\n", pInfo->name,
1507                         strerror(errno));
1508             }
1509             break;
1510         }
1511
1512         /* The kernel promises that we always only read a complete
1513          * event, so len != sizeof ev is an error. */
1514         if (len % sizeof(ev[0])) {
1515             /* We use X_NONE here because it doesn't alloc */
1516             xf86MsgVerb(X_NONE, 0, "%s: Read error: %s\n", pInfo->name, strerror(errno));
1517             break;
1518         }
1519
1520         for (i = 0; i < len/sizeof(ev[0]); i++)
1521             EvdevMultitouchProcessEvent(pInfo, &ev[i]);
1522     }
1523 }
1524
1525 #define TestBit(bit, array) ((array[(bit) / LONG_BITS]) & (1L << ((bit) % LONG_BITS)))
1526
1527 static void
1528 EvdevMultitouchPtrCtrlProc(DeviceIntPtr device, PtrCtrl *ctrl)
1529 {
1530     /* Nothing to do, dix handles all settings */
1531 }
1532
1533 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 5
1534 static KeySym map[] = {
1535     /* 0x00 */  NoSymbol,       NoSymbol,
1536     /* 0x01 */  XK_Escape,      NoSymbol,
1537     /* 0x02 */  XK_1,           XK_exclam,
1538     /* 0x03 */  XK_2,           XK_at,
1539     /* 0x04 */  XK_3,           XK_numbersign,
1540     /* 0x05 */  XK_4,           XK_dollar,
1541     /* 0x06 */  XK_5,           XK_percent,
1542     /* 0x07 */  XK_6,           XK_asciicircum,
1543     /* 0x08 */  XK_7,           XK_ampersand,
1544     /* 0x09 */  XK_8,           XK_asterisk,
1545     /* 0x0a */  XK_9,           XK_parenleft,
1546     /* 0x0b */  XK_0,           XK_parenright,
1547     /* 0x0c */  XK_minus,       XK_underscore,
1548     /* 0x0d */  XK_equal,       XK_plus,
1549     /* 0x0e */  XK_BackSpace,   NoSymbol,
1550     /* 0x0f */  XK_Tab,         XK_ISO_Left_Tab,
1551     /* 0x10 */  XK_Q,           NoSymbol,
1552     /* 0x11 */  XK_W,           NoSymbol,
1553     /* 0x12 */  XK_E,           NoSymbol,
1554     /* 0x13 */  XK_R,           NoSymbol,
1555     /* 0x14 */  XK_T,           NoSymbol,
1556     /* 0x15 */  XK_Y,           NoSymbol,
1557     /* 0x16 */  XK_U,           NoSymbol,
1558     /* 0x17 */  XK_I,           NoSymbol,
1559     /* 0x18 */  XK_O,           NoSymbol,
1560     /* 0x19 */  XK_P,           NoSymbol,
1561     /* 0x1a */  XK_bracketleft, XK_braceleft,
1562     /* 0x1b */  XK_bracketright,XK_braceright,
1563     /* 0x1c */  XK_Return,      NoSymbol,
1564     /* 0x1d */  XK_Control_L,   NoSymbol,
1565     /* 0x1e */  XK_A,           NoSymbol,
1566     /* 0x1f */  XK_S,           NoSymbol,
1567     /* 0x20 */  XK_D,           NoSymbol,
1568     /* 0x21 */  XK_F,           NoSymbol,
1569     /* 0x22 */  XK_G,           NoSymbol,
1570     /* 0x23 */  XK_H,           NoSymbol,
1571     /* 0x24 */  XK_J,           NoSymbol,
1572     /* 0x25 */  XK_K,           NoSymbol,
1573     /* 0x26 */  XK_L,           NoSymbol,
1574     /* 0x27 */  XK_semicolon,   XK_colon,
1575     /* 0x28 */  XK_quoteright,  XK_quotedbl,
1576     /* 0x29 */  XK_quoteleft,   XK_asciitilde,
1577     /* 0x2a */  XK_Shift_L,     NoSymbol,
1578     /* 0x2b */  XK_backslash,   XK_bar,
1579     /* 0x2c */  XK_Z,           NoSymbol,
1580     /* 0x2d */  XK_X,           NoSymbol,
1581     /* 0x2e */  XK_C,           NoSymbol,
1582     /* 0x2f */  XK_V,           NoSymbol,
1583     /* 0x30 */  XK_B,           NoSymbol,
1584     /* 0x31 */  XK_N,           NoSymbol,
1585     /* 0x32 */  XK_M,           NoSymbol,
1586     /* 0x33 */  XK_comma,       XK_less,
1587     /* 0x34 */  XK_period,      XK_greater,
1588     /* 0x35 */  XK_slash,       XK_question,
1589     /* 0x36 */  XK_Shift_R,     NoSymbol,
1590     /* 0x37 */  XK_KP_Multiply, NoSymbol,
1591     /* 0x38 */  XK_Alt_L,       XK_Meta_L,
1592     /* 0x39 */  XK_space,       NoSymbol,
1593     /* 0x3a */  XK_Caps_Lock,   NoSymbol,
1594     /* 0x3b */  XK_F1,          NoSymbol,
1595     /* 0x3c */  XK_F2,          NoSymbol,
1596     /* 0x3d */  XK_F3,          NoSymbol,
1597     /* 0x3e */  XK_F4,          NoSymbol,
1598     /* 0x3f */  XK_F5,          NoSymbol,
1599     /* 0x40 */  XK_F6,          NoSymbol,
1600     /* 0x41 */  XK_F7,          NoSymbol,
1601     /* 0x42 */  XK_F8,          NoSymbol,
1602     /* 0x43 */  XK_F9,          NoSymbol,
1603     /* 0x44 */  XK_F10,         NoSymbol,
1604     /* 0x45 */  XK_Num_Lock,    NoSymbol,
1605     /* 0x46 */  XK_Scroll_Lock, NoSymbol,
1606     /* These KP keys should have the KP_7 keysyms in the numlock
1607      * modifer... ? */
1608     /* 0x47 */  XK_KP_Home,     XK_KP_7,
1609     /* 0x48 */  XK_KP_Up,       XK_KP_8,
1610     /* 0x49 */  XK_KP_Prior,    XK_KP_9,
1611     /* 0x4a */  XK_KP_Subtract, NoSymbol,
1612     /* 0x4b */  XK_KP_Left,     XK_KP_4,
1613     /* 0x4c */  XK_KP_Begin,    XK_KP_5,
1614     /* 0x4d */  XK_KP_Right,    XK_KP_6,
1615     /* 0x4e */  XK_KP_Add,      NoSymbol,
1616     /* 0x4f */  XK_KP_End,      XK_KP_1,
1617     /* 0x50 */  XK_KP_Down,     XK_KP_2,
1618     /* 0x51 */  XK_KP_Next,     XK_KP_3,
1619     /* 0x52 */  XK_KP_Insert,   XK_KP_0,
1620     /* 0x53 */  XK_KP_Delete,   XK_KP_Decimal,
1621     /* 0x54 */  NoSymbol,       NoSymbol,
1622     /* 0x55 */  XK_F13,         NoSymbol,
1623     /* 0x56 */  XK_less,        XK_greater,
1624     /* 0x57 */  XK_F11,         NoSymbol,
1625     /* 0x58 */  XK_F12,         NoSymbol,
1626     /* 0x59 */  XK_F14,         NoSymbol,
1627     /* 0x5a */  XK_F15,         NoSymbol,
1628     /* 0x5b */  XK_F16,         NoSymbol,
1629     /* 0x5c */  XK_F17,         NoSymbol,
1630     /* 0x5d */  XK_F18,         NoSymbol,
1631     /* 0x5e */  XK_F19,         NoSymbol,
1632     /* 0x5f */  XK_F20,         NoSymbol,
1633     /* 0x60 */  XK_KP_Enter,    NoSymbol,
1634     /* 0x61 */  XK_Control_R,   NoSymbol,
1635     /* 0x62 */  XK_KP_Divide,   NoSymbol,
1636     /* 0x63 */  XK_Print,       XK_Sys_Req,
1637     /* 0x64 */  XK_Alt_R,       XK_Meta_R,
1638     /* 0x65 */  NoSymbol,       NoSymbol, /* KEY_LINEFEED */
1639     /* 0x66 */  XK_Home,        NoSymbol,
1640     /* 0x67 */  XK_Up,          NoSymbol,
1641     /* 0x68 */  XK_Prior,       NoSymbol,
1642     /* 0x69 */  XK_Left,        NoSymbol,
1643     /* 0x6a */  XK_Right,       NoSymbol,
1644     /* 0x6b */  XK_End,         NoSymbol,
1645     /* 0x6c */  XK_Down,        NoSymbol,
1646     /* 0x6d */  XK_Next,        NoSymbol,
1647     /* 0x6e */  XK_Insert,      NoSymbol,
1648     /* 0x6f */  XK_Delete,      NoSymbol,
1649     /* 0x70 */  NoSymbol,       NoSymbol, /* KEY_MACRO */
1650     /* 0x71 */  NoSymbol,       NoSymbol,
1651     /* 0x72 */  NoSymbol,       NoSymbol,
1652     /* 0x73 */  NoSymbol,       NoSymbol,
1653     /* 0x74 */  NoSymbol,       NoSymbol,
1654     /* 0x75 */  XK_KP_Equal,    NoSymbol,
1655     /* 0x76 */  NoSymbol,       NoSymbol,
1656     /* 0x77 */  NoSymbol,       NoSymbol,
1657     /* 0x78 */  XK_F21,         NoSymbol,
1658     /* 0x79 */  XK_F22,         NoSymbol,
1659     /* 0x7a */  XK_F23,         NoSymbol,
1660     /* 0x7b */  XK_F24,         NoSymbol,
1661     /* 0x7c */  XK_KP_Separator, NoSymbol,
1662     /* 0x7d */  XK_Meta_L,      NoSymbol,
1663     /* 0x7e */  XK_Meta_R,      NoSymbol,
1664     /* 0x7f */  XK_Multi_key,   NoSymbol,
1665     /* 0x80 */  NoSymbol,       NoSymbol,
1666     /* 0x81 */  NoSymbol,       NoSymbol,
1667     /* 0x82 */  NoSymbol,       NoSymbol,
1668     /* 0x83 */  NoSymbol,       NoSymbol,
1669     /* 0x84 */  NoSymbol,       NoSymbol,
1670     /* 0x85 */  NoSymbol,       NoSymbol,
1671     /* 0x86 */  NoSymbol,       NoSymbol,
1672     /* 0x87 */  NoSymbol,       NoSymbol,
1673     /* 0x88 */  NoSymbol,       NoSymbol,
1674     /* 0x89 */  NoSymbol,       NoSymbol,
1675     /* 0x8a */  NoSymbol,       NoSymbol,
1676     /* 0x8b */  NoSymbol,       NoSymbol,
1677     /* 0x8c */  NoSymbol,       NoSymbol,
1678     /* 0x8d */  NoSymbol,       NoSymbol,
1679     /* 0x8e */  NoSymbol,       NoSymbol,
1680     /* 0x8f */  NoSymbol,       NoSymbol,
1681     /* 0x90 */  NoSymbol,       NoSymbol,
1682     /* 0x91 */  NoSymbol,       NoSymbol,
1683     /* 0x92 */  NoSymbol,       NoSymbol,
1684     /* 0x93 */  NoSymbol,       NoSymbol,
1685     /* 0x94 */  NoSymbol,       NoSymbol,
1686     /* 0x95 */  NoSymbol,       NoSymbol,
1687     /* 0x96 */  NoSymbol,       NoSymbol,
1688     /* 0x97 */  NoSymbol,       NoSymbol,
1689     /* 0x98 */  NoSymbol,       NoSymbol,
1690     /* 0x99 */  NoSymbol,       NoSymbol,
1691     /* 0x9a */  NoSymbol,       NoSymbol,
1692     /* 0x9b */  NoSymbol,       NoSymbol,
1693     /* 0x9c */  NoSymbol,       NoSymbol,
1694     /* 0x9d */  NoSymbol,       NoSymbol,
1695     /* 0x9e */  NoSymbol,       NoSymbol,
1696     /* 0x9f */  NoSymbol,       NoSymbol,
1697     /* 0xa0 */  NoSymbol,       NoSymbol,
1698     /* 0xa1 */  NoSymbol,       NoSymbol,
1699     /* 0xa2 */  NoSymbol,       NoSymbol,
1700     /* 0xa3 */  NoSymbol,       NoSymbol,
1701     /* 0xa4 */  NoSymbol,       NoSymbol,
1702     /* 0xa5 */  NoSymbol,       NoSymbol,
1703     /* 0xa6 */  NoSymbol,       NoSymbol,
1704     /* 0xa7 */  NoSymbol,       NoSymbol,
1705     /* 0xa8 */  NoSymbol,       NoSymbol,
1706     /* 0xa9 */  NoSymbol,       NoSymbol,
1707     /* 0xaa */  NoSymbol,       NoSymbol,
1708     /* 0xab */  NoSymbol,       NoSymbol,
1709     /* 0xac */  NoSymbol,       NoSymbol,
1710     /* 0xad */  NoSymbol,       NoSymbol,
1711     /* 0xae */  NoSymbol,       NoSymbol,
1712     /* 0xaf */  NoSymbol,       NoSymbol,
1713     /* 0xb0 */  NoSymbol,       NoSymbol,
1714     /* 0xb1 */  NoSymbol,       NoSymbol,
1715     /* 0xb2 */  NoSymbol,       NoSymbol,
1716     /* 0xb3 */  NoSymbol,       NoSymbol,
1717     /* 0xb4 */  NoSymbol,       NoSymbol,
1718     /* 0xb5 */  NoSymbol,       NoSymbol,
1719     /* 0xb6 */  NoSymbol,       NoSymbol,
1720     /* 0xb7 */  NoSymbol,       NoSymbol,
1721     /* 0xb8 */  NoSymbol,       NoSymbol,
1722     /* 0xb9 */  NoSymbol,       NoSymbol,
1723     /* 0xba */  NoSymbol,       NoSymbol,
1724     /* 0xbb */  NoSymbol,       NoSymbol,
1725     /* 0xbc */  NoSymbol,       NoSymbol,
1726     /* 0xbd */  NoSymbol,       NoSymbol,
1727     /* 0xbe */  NoSymbol,       NoSymbol,
1728     /* 0xbf */  NoSymbol,       NoSymbol,
1729     /* 0xc0 */  NoSymbol,       NoSymbol,
1730     /* 0xc1 */  NoSymbol,       NoSymbol,
1731     /* 0xc2 */  NoSymbol,       NoSymbol,
1732     /* 0xc3 */  NoSymbol,       NoSymbol,
1733     /* 0xc4 */  NoSymbol,       NoSymbol,
1734     /* 0xc5 */  NoSymbol,       NoSymbol,
1735     /* 0xc6 */  NoSymbol,       NoSymbol,
1736     /* 0xc7 */  NoSymbol,       NoSymbol,
1737     /* 0xc8 */  NoSymbol,       NoSymbol,
1738     /* 0xc9 */  NoSymbol,       NoSymbol,
1739     /* 0xca */  NoSymbol,       NoSymbol,
1740     /* 0xcb */  NoSymbol,       NoSymbol,
1741     /* 0xcc */  NoSymbol,       NoSymbol,
1742     /* 0xcd */  NoSymbol,       NoSymbol,
1743     /* 0xce */  NoSymbol,       NoSymbol,
1744     /* 0xcf */  NoSymbol,       NoSymbol,
1745     /* 0xd0 */  NoSymbol,       NoSymbol,
1746     /* 0xd1 */  NoSymbol,       NoSymbol,
1747     /* 0xd2 */  NoSymbol,       NoSymbol,
1748     /* 0xd3 */  NoSymbol,       NoSymbol,
1749     /* 0xd4 */  NoSymbol,       NoSymbol,
1750     /* 0xd5 */  NoSymbol,       NoSymbol,
1751     /* 0xd6 */  NoSymbol,       NoSymbol,
1752     /* 0xd7 */  NoSymbol,       NoSymbol,
1753     /* 0xd8 */  NoSymbol,       NoSymbol,
1754     /* 0xd9 */  NoSymbol,       NoSymbol,
1755     /* 0xda */  NoSymbol,       NoSymbol,
1756     /* 0xdb */  NoSymbol,       NoSymbol,
1757     /* 0xdc */  NoSymbol,       NoSymbol,
1758     /* 0xdd */  NoSymbol,       NoSymbol,
1759     /* 0xde */  NoSymbol,       NoSymbol,
1760     /* 0xdf */  NoSymbol,       NoSymbol,
1761     /* 0xe0 */  NoSymbol,       NoSymbol,
1762     /* 0xe1 */  NoSymbol,       NoSymbol,
1763     /* 0xe2 */  NoSymbol,       NoSymbol,
1764     /* 0xe3 */  NoSymbol,       NoSymbol,
1765     /* 0xe4 */  NoSymbol,       NoSymbol,
1766     /* 0xe5 */  NoSymbol,       NoSymbol,
1767     /* 0xe6 */  NoSymbol,       NoSymbol,
1768     /* 0xe7 */  NoSymbol,       NoSymbol,
1769     /* 0xe8 */  NoSymbol,       NoSymbol,
1770     /* 0xe9 */  NoSymbol,       NoSymbol,
1771     /* 0xea */  NoSymbol,       NoSymbol,
1772     /* 0xeb */  NoSymbol,       NoSymbol,
1773     /* 0xec */  NoSymbol,       NoSymbol,
1774     /* 0xed */  NoSymbol,       NoSymbol,
1775     /* 0xee */  NoSymbol,       NoSymbol,
1776     /* 0xef */  NoSymbol,       NoSymbol,
1777     /* 0xf0 */  NoSymbol,       NoSymbol,
1778     /* 0xf1 */  NoSymbol,       NoSymbol,
1779     /* 0xf2 */  NoSymbol,       NoSymbol,
1780     /* 0xf3 */  NoSymbol,       NoSymbol,
1781     /* 0xf4 */  NoSymbol,       NoSymbol,
1782     /* 0xf5 */  NoSymbol,       NoSymbol,
1783     /* 0xf6 */  NoSymbol,       NoSymbol,
1784     /* 0xf7 */  NoSymbol,       NoSymbol,
1785 };
1786
1787 static struct { KeySym keysym; CARD8 mask; } modifiers[] = {
1788     { XK_Shift_L,               ShiftMask },
1789     { XK_Shift_R,               ShiftMask },
1790     { XK_Control_L,             ControlMask },
1791     { XK_Control_R,             ControlMask },
1792     { XK_Caps_Lock,             LockMask },
1793     { XK_Alt_L,         AltMask },
1794     { XK_Alt_R,         AltMask },
1795     { XK_Meta_L,                Mod4Mask },
1796     { XK_Meta_R,                Mod4Mask },
1797     { XK_Num_Lock,              NumLockMask },
1798     { XK_Scroll_Lock,   ScrollLockMask },
1799     { XK_Mode_switch,   AltLangMask }
1800 };
1801
1802 /* Server 1.6 and earlier */
1803 static int
1804 EvdevMultitouchInitKeysyms(DeviceIntPtr device)
1805 {
1806     InputInfoPtr pInfo;
1807     EvdevMultitouchPtr pEvdevMultitouch;
1808     KeySymsRec keySyms;
1809     CARD8 modMap[MAP_LENGTH];
1810     KeySym sym;
1811     int i, j;
1812
1813     pInfo = device->public.devicePrivate;
1814     pEvdevMultitouch = pInfo->private;
1815
1816      /* Compute the modifier map */
1817     memset(modMap, 0, sizeof modMap);
1818
1819     for (i = 0; i < ArrayLength(map) / GLYPHS_PER_KEY; i++) {
1820         sym = map[i * GLYPHS_PER_KEY];
1821         for (j = 0; j < ArrayLength(modifiers); j++) {
1822             if (modifiers[j].keysym == sym)
1823                 modMap[i + MIN_KEYCODE] = modifiers[j].mask;
1824         }
1825     }
1826
1827     keySyms.map        = map;
1828     keySyms.mapWidth   = GLYPHS_PER_KEY;
1829     keySyms.minKeyCode = MIN_KEYCODE;
1830     keySyms.maxKeyCode = MIN_KEYCODE + ArrayLength(map) / GLYPHS_PER_KEY - 1;
1831
1832     XkbSetRulesDflts(pEvdevMultitouch->rmlvo.rules, pEvdevMultitouch->rmlvo.model,
1833             pEvdevMultitouch->rmlvo.layout, pEvdevMultitouch->rmlvo.variant,
1834             pEvdevMultitouch->rmlvo.options);
1835     if (!XkbInitKeyboardDeviceStruct(device, &pEvdevMultitouch->xkbnames,
1836                 &keySyms, modMap, NULL,
1837                 EvdevMultitouchKbdCtrl))
1838         return 0;
1839
1840     return 1;
1841 }
1842 #endif
1843
1844 static void
1845 EvdevMultitouchKbdCtrl(DeviceIntPtr device, KeybdCtrl *ctrl)
1846 {
1847     static struct { int xbit, code; } bits[] = {
1848         { CAPSFLAG,     LED_CAPSL },
1849         { NUMFLAG,      LED_NUML },
1850         { SCROLLFLAG,   LED_SCROLLL },
1851         { MODEFLAG,     LED_KANA },
1852         { COMPOSEFLAG,  LED_COMPOSE }
1853     };
1854
1855     InputInfoPtr pInfo;
1856     struct input_event ev[ArrayLength(bits)];
1857     int i;
1858
1859     memset(ev, 0, sizeof(ev));
1860
1861     pInfo = device->public.devicePrivate;
1862     for (i = 0; i < ArrayLength(bits); i++) {
1863         ev[i].type = EV_LED;
1864         ev[i].code = bits[i].code;
1865         ev[i].value = (ctrl->leds & bits[i].xbit) > 0;
1866     }
1867
1868     write(pInfo->fd, ev, sizeof ev);
1869 }
1870
1871 static int
1872 EvdevMultitouchAddKeyClass(DeviceIntPtr device)
1873 {
1874     InputInfoPtr pInfo;
1875     EvdevMultitouchPtr pEvdevMultitouch;
1876
1877     pInfo = device->public.devicePrivate;
1878     pEvdevMultitouch = pInfo->private;
1879
1880     /* sorry, no rules change allowed for you */
1881     xf86ReplaceStrOption(pInfo->options, "xkb_rules", "evdevmultitouch");
1882     SetXkbOption(pInfo, "xkb_rules", &pEvdevMultitouch->rmlvo.rules);
1883     SetXkbOption(pInfo, "xkb_model", &pEvdevMultitouch->rmlvo.model);
1884     if (!pEvdevMultitouch->rmlvo.model)
1885         SetXkbOption(pInfo, "XkbModel", &pEvdevMultitouch->rmlvo.model);
1886     SetXkbOption(pInfo, "xkb_layout", &pEvdevMultitouch->rmlvo.layout);
1887     if (!pEvdevMultitouch->rmlvo.layout)
1888         SetXkbOption(pInfo, "XkbLayout", &pEvdevMultitouch->rmlvo.layout);
1889     SetXkbOption(pInfo, "xkb_variant", &pEvdevMultitouch->rmlvo.variant);
1890     if (!pEvdevMultitouch->rmlvo.variant)
1891         SetXkbOption(pInfo, "XkbVariant", &pEvdevMultitouch->rmlvo.variant);
1892     SetXkbOption(pInfo, "xkb_options", &pEvdevMultitouch->rmlvo.options);
1893     if (!pEvdevMultitouch->rmlvo.options)
1894         SetXkbOption(pInfo, "XkbOptions", &pEvdevMultitouch->rmlvo.options);
1895
1896 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 5
1897     if (!InitKeyboardDeviceStruct(device, &pEvdevMultitouch->rmlvo, NULL, EvdevMultitouchKbdCtrl))
1898         return !Success;
1899 #else
1900     if (!EvdevMultitouchInitKeysyms(device))
1901         return !Success;
1902
1903 #endif
1904
1905     pInfo->flags |= XI86_KEYBOARD_CAPABLE;
1906
1907     return Success;
1908 }
1909
1910 static int
1911 EvdevMultitouchAddAbsClass(DeviceIntPtr device)
1912 {
1913     InputInfoPtr pInfo;
1914     EvdevMultitouchPtr pEvdevMultitouch;
1915     EvdevMultitouchPtr g_pEvdevMultitouch;
1916     int num_axes, axis, i = 0;
1917     Atom *atoms;
1918
1919     pInfo = device->public.devicePrivate;
1920     pEvdevMultitouch = pInfo->private;
1921
1922     g_pEvdevMultitouch = pEvdevMultitouch->core_device->private;
1923
1924     if (!TestBit(EV_ABS, g_pEvdevMultitouch->bitmask))
1925             return !Success;
1926
1927     num_axes = CountBits(g_pEvdevMultitouch->abs_bitmask, NLONGS(ABS_MAX));
1928     if (num_axes < 1)
1929         return !Success;
1930     pEvdevMultitouch->num_vals = num_axes;
1931     memset(pEvdevMultitouch->vals, 0, num_axes * sizeof(int));
1932     memset(pEvdevMultitouch->old_vals, -1, num_axes * sizeof(int));
1933     atoms = malloc(pEvdevMultitouch->num_vals * sizeof(Atom));
1934
1935     if( !atoms )
1936     {
1937         ErrorF("[X11][EvdevMultitouchAddAbsClass] Failed to allocate memory !\n", __FUNCTION__);
1938          return !Success;
1939     }
1940
1941     for (axis = ABS_X; axis <= ABS_MAX; axis++) {
1942         pEvdevMultitouch->axis_map[axis] = -1;
1943         if (!TestBit(axis, pEvdevMultitouch->abs_bitmask))
1944             continue;
1945         pEvdevMultitouch->axis_map[axis] = i;
1946         i++;
1947     }
1948
1949     EvdevMultitouchInitAxesLabels(g_pEvdevMultitouch, g_pEvdevMultitouch->num_vals, atoms);
1950
1951     if (!InitValuatorClassDeviceStruct(device, num_axes,
1952 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
1953                                        atoms,
1954 #endif
1955 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 3
1956                                        GetMotionHistory,
1957 #endif
1958                                        GetMotionHistorySize(), Absolute))
1959         return !Success;
1960
1961     for (axis = ABS_X; axis <= ABS_MAX; axis++) {
1962         int axnum = g_pEvdevMultitouch->axis_map[axis];
1963         if (axnum == -1)
1964             continue;
1965         xf86InitValuatorAxisStruct(device, axnum,
1966 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
1967                                    atoms[axnum],
1968 #endif
1969                                    pEvdevMultitouch->absinfo[axis].minimum,
1970                                    pEvdevMultitouch->absinfo[axis].maximum,
1971                                    10000, 0, 10000);
1972         xf86InitValuatorDefaults(device, axnum);
1973         pEvdevMultitouch->old_vals[axnum] = -1;
1974     }
1975
1976     free(atoms);
1977
1978     if (!InitPtrFeedbackClassDeviceStruct(device, EvdevMultitouchPtrCtrlProc))
1979         return !Success;
1980
1981     if ((TestBit(ABS_X, pEvdevMultitouch->abs_bitmask) &&
1982          TestBit(ABS_Y, pEvdevMultitouch->abs_bitmask)) ||
1983         (TestBit(ABS_RX, pEvdevMultitouch->abs_bitmask) &&
1984          TestBit(ABS_RY, pEvdevMultitouch->abs_bitmask)) ||
1985         (TestBit(ABS_HAT0X, pEvdevMultitouch->abs_bitmask) &&
1986          TestBit(ABS_HAT0Y, pEvdevMultitouch->abs_bitmask)) ||
1987         (TestBit(ABS_HAT1X, pEvdevMultitouch->abs_bitmask) &&
1988          TestBit(ABS_HAT1Y, pEvdevMultitouch->abs_bitmask)) ||
1989         (TestBit(ABS_HAT2X, pEvdevMultitouch->abs_bitmask) &&
1990          TestBit(ABS_HAT2Y, pEvdevMultitouch->abs_bitmask)) ||
1991         (TestBit(ABS_HAT3X, pEvdevMultitouch->abs_bitmask) &&
1992          TestBit(ABS_HAT3Y, pEvdevMultitouch->abs_bitmask)) ||
1993         (TestBit(ABS_TILT_X, pEvdevMultitouch->abs_bitmask) &&
1994          TestBit(ABS_TILT_Y, pEvdevMultitouch->abs_bitmask)))
1995         pInfo->flags |= XI86_POINTER_CAPABLE;
1996
1997     return Success;
1998 }
1999
2000 static int
2001 EvdevMultitouchAddRelClass(DeviceIntPtr device)
2002 {
2003     InputInfoPtr pInfo;
2004     EvdevMultitouchPtr pEvdevMultitouch;
2005     int num_axes, axis, i = 0;
2006     Atom *atoms;
2007
2008     pInfo = device->public.devicePrivate;
2009     pEvdevMultitouch = pInfo->private;
2010
2011     if (!TestBit(EV_REL, pEvdevMultitouch->bitmask))
2012         return !Success;
2013
2014     num_axes = CountBits(pEvdevMultitouch->rel_bitmask, NLONGS(REL_MAX));
2015     if (num_axes < 1)
2016         return !Success;
2017
2018     /* Wheels are special, we post them as button events. So let's ignore them
2019      * in the axes list too */
2020     if (TestBit(REL_WHEEL, pEvdevMultitouch->rel_bitmask))
2021         num_axes--;
2022     if (TestBit(REL_HWHEEL, pEvdevMultitouch->rel_bitmask))
2023         num_axes--;
2024     if (TestBit(REL_DIAL, pEvdevMultitouch->rel_bitmask))
2025         num_axes--;
2026
2027     if (num_axes <= 0)
2028         return !Success;
2029
2030     pEvdevMultitouch->num_vals = num_axes;
2031     memset(pEvdevMultitouch->vals, 0, num_axes * sizeof(int));
2032     atoms = malloc(pEvdevMultitouch->num_vals * sizeof(Atom));
2033
2034     if( !atoms )
2035     {
2036         ErrorF("[X11][EvdevMultitouchAddRelClass] Failed to allocate memory !\n", __FUNCTION__);
2037          return !Success;
2038     }
2039
2040     for (axis = REL_X; axis <= REL_MAX; axis++)
2041     {
2042         pEvdevMultitouch->axis_map[axis] = -1;
2043         /* We don't post wheel events, so ignore them here too */
2044         if (axis == REL_WHEEL || axis == REL_HWHEEL || axis == REL_DIAL)
2045             continue;
2046         if (!TestBit(axis, pEvdevMultitouch->rel_bitmask))
2047             continue;
2048         pEvdevMultitouch->axis_map[axis] = i;
2049         i++;
2050     }
2051
2052     EvdevMultitouchInitAxesLabels(pEvdevMultitouch, pEvdevMultitouch->num_vals, atoms);
2053
2054     if (!InitValuatorClassDeviceStruct(device, num_axes,
2055 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
2056                                        atoms,
2057 #endif
2058 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 3
2059                                        GetMotionHistory,
2060 #endif
2061                                        GetMotionHistorySize(), Relative))
2062         return !Success;
2063
2064     for (axis = REL_X; axis <= REL_MAX; axis++)
2065     {
2066         int axnum = pEvdevMultitouch->axis_map[axis];
2067
2068         if (axnum == -1)
2069             continue;
2070         xf86InitValuatorAxisStruct(device, axnum,
2071 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
2072                 atoms[axnum],
2073 #endif
2074                 -1, -1, 1, 0, 1);
2075         xf86InitValuatorDefaults(device, axnum);
2076     }
2077
2078     free(atoms);
2079
2080     if (!InitPtrFeedbackClassDeviceStruct(device, EvdevMultitouchPtrCtrlProc))
2081         return !Success;
2082
2083     pInfo->flags |= XI86_POINTER_CAPABLE;
2084
2085     return Success;
2086 }
2087
2088 static int
2089 EvdevMultitouchAddButtonClass(DeviceIntPtr device)
2090 {
2091     InputInfoPtr pInfo;
2092     EvdevMultitouchPtr pEvdevMultitouch;
2093     Atom *labels;
2094
2095     pInfo = device->public.devicePrivate;
2096     pEvdevMultitouch = pInfo->private;
2097
2098     labels = malloc(pEvdevMultitouch->num_buttons * sizeof(Atom));
2099
2100     if( !labels )
2101         return !Success;
2102
2103     EvdevMultitouchInitButtonLabels(pEvdevMultitouch, pEvdevMultitouch->num_buttons, labels);
2104
2105     if (!InitButtonClassDeviceStruct(device, pEvdevMultitouch->num_buttons,
2106 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
2107                                      labels,
2108 #endif
2109                                      pEvdevMultitouch->btnmap))
2110         return !Success;
2111
2112     free(labels);
2113     return Success;
2114 }
2115
2116 /**
2117  * Init the button mapping for the device. By default, this is a 1:1 mapping,
2118  * i.e. Button 1 maps to Button 1, Button 2 to 2, etc.
2119  *
2120  * If a mapping has been specified, the mapping is the default, with the
2121  * user-defined ones overwriting the defaults.
2122  * i.e. a user-defined mapping of "3 2 1" results in a mapping of 3 2 1 4 5 6 ...
2123  *
2124  * Invalid button mappings revert to the default.
2125  *
2126  * Note that index 0 is unused, button 0 does not exist.
2127  * This mapping is initialised for all devices, but only applied if the device
2128  * has buttons (in EvdevMultitouchAddButtonClass).
2129  */
2130 static void
2131 EvdevMultitouchInitButtonMapping(InputInfoPtr pInfo)
2132 {
2133     int         i, nbuttons     = 1;
2134     char       *mapping         = NULL;
2135     EvdevMultitouchPtr    pEvdevMultitouch          = pInfo->private;
2136
2137     /* Check for user-defined button mapping */
2138     if ((mapping = xf86CheckStrOption(pInfo->options, "ButtonMapping", NULL)))
2139     {
2140         char    *s  = " ";
2141         int     btn = 0;
2142
2143         xf86Msg(X_CONFIG, "%s: ButtonMapping '%s'\n", pInfo->name, mapping);
2144         while (s && *s != '\0' && nbuttons < EVDEVMULTITOUCH_MAXBUTTONS)
2145         {
2146             btn = strtol(mapping, &s, 10);
2147
2148             if (s == mapping || btn < 0 || btn > EVDEVMULTITOUCH_MAXBUTTONS)
2149             {
2150                 xf86Msg(X_ERROR,
2151                         "%s: ... Invalid button mapping. Using defaults\n",
2152                         pInfo->name);
2153                 nbuttons = 1; /* ensure defaults start at 1 */
2154                 break;
2155             }
2156
2157             pEvdevMultitouch->btnmap[nbuttons++] = btn;
2158             mapping = s;
2159         }
2160     }
2161
2162     for (i = nbuttons; i < ArrayLength(pEvdevMultitouch->btnmap); i++)
2163         pEvdevMultitouch->btnmap[i] = i;
2164
2165 }
2166
2167 static void
2168 EvdevMultitouchInitAnyClass(DeviceIntPtr device, EvdevMultitouchPtr pEvdevMultitouch)
2169 {
2170     if (pEvdevMultitouch->flags & EVDEVMULTITOUCH_RELATIVE_EVENTS &&
2171         EvdevMultitouchAddRelClass(device) == Success)
2172         xf86Msg(X_INFO, "%s: initialized for relative axes.\n", device->name);
2173     if (pEvdevMultitouch->flags & EVDEVMULTITOUCH_ABSOLUTE_EVENTS &&
2174         EvdevMultitouchAddAbsClass(device) == Success)
2175         xf86Msg(X_INFO, "%s: initialized for absolute axes.\n", device->name);
2176 }
2177
2178 static void
2179 EvdevMultitouchInitAbsClass(DeviceIntPtr device, EvdevMultitouchPtr pEvdevMultitouch)
2180 {
2181     if (EvdevMultitouchAddAbsClass(device) == Success) {
2182
2183         xf86Msg(X_INFO,"%s: initialized for absolute axes.\n", device->name);
2184
2185     } else {
2186
2187         xf86Msg(X_ERROR,"%s: failed to initialize for absolute axes.\n",
2188                 device->name);
2189
2190         pEvdevMultitouch->flags &= ~EVDEVMULTITOUCH_ABSOLUTE_EVENTS;
2191
2192     }
2193 }
2194
2195 static void
2196 EvdevMultitouchInitRelClass(DeviceIntPtr device, EvdevMultitouchPtr pEvdevMultitouch)
2197 {
2198     int has_abs_axes = pEvdevMultitouch->flags & EVDEVMULTITOUCH_ABSOLUTE_EVENTS;
2199
2200     if (EvdevMultitouchAddRelClass(device) == Success) {
2201
2202         xf86Msg(X_INFO,"%s: initialized for relative axes.\n", device->name);
2203
2204         if (has_abs_axes) {
2205
2206             xf86Msg(X_WARNING,"%s: ignoring absolute axes.\n", device->name);
2207             pEvdevMultitouch->flags &= ~EVDEVMULTITOUCH_ABSOLUTE_EVENTS;
2208         }
2209
2210     } else {
2211
2212         xf86Msg(X_ERROR,"%s: failed to initialize for relative axes.\n",
2213                 device->name);
2214
2215         pEvdevMultitouch->flags &= ~EVDEVMULTITOUCH_RELATIVE_EVENTS;
2216
2217         if (has_abs_axes)
2218             EvdevMultitouchInitAbsClass(device, pEvdevMultitouch);
2219     }
2220 }
2221
2222 static void
2223 EvdevMultitouchInitTouchDevice(DeviceIntPtr device, EvdevMultitouchPtr pEvdevMultitouch)
2224 {
2225     if (pEvdevMultitouch->flags & EVDEVMULTITOUCH_RELATIVE_EVENTS) {
2226
2227         xf86Msg(X_WARNING,"%s: touchpads, tablets and (multi)touchscreens ignore "
2228                 "relative axes.\n", device->name);
2229
2230         pEvdevMultitouch->flags &= ~EVDEVMULTITOUCH_RELATIVE_EVENTS;
2231     }
2232
2233     EvdevMultitouchInitAbsClass(device, pEvdevMultitouch);
2234 }
2235
2236 static int
2237 EvdevMultitouchInit(DeviceIntPtr device)
2238 {
2239     int i;
2240     InputInfoPtr pInfo;
2241     EvdevMultitouchPtr pEvdevMultitouch;
2242
2243     pInfo = device->public.devicePrivate;
2244     pEvdevMultitouch = pInfo->private;
2245
2246     /* clear all axis_map entries */
2247     for(i = 0; i < max(ABS_CNT,REL_CNT); i++)
2248       pEvdevMultitouch->axis_map[i]=-1;
2249
2250     if (pEvdevMultitouch->flags & EVDEVMULTITOUCH_KEYBOARD_EVENTS)
2251         EvdevMultitouchAddKeyClass(device);
2252     if (pEvdevMultitouch->flags & EVDEVMULTITOUCH_BUTTON_EVENTS)
2253         EvdevMultitouchAddButtonClass(device);
2254
2255     /* We don't allow relative and absolute axes on the same device. The
2256      * reason is that some devices (MS Optical Desktop 2000) register both
2257      * rel and abs axes for x/y.
2258      *
2259      * The abs axes register min/max; this min/max then also applies to the
2260      * relative device (the mouse) and caps it at 0..255 for both axes.
2261      * So, unless you have a small screen, you won't be enjoying it much;
2262      * consequently, absolute axes are generally ignored.
2263      *
2264      * However, currenly only a device with absolute axes can be registered
2265      * as a touch{pad,screen}. Thus, given such a device, absolute axes are
2266      * used and relative axes are ignored.
2267      */
2268
2269     if (pEvdevMultitouch->flags & (EVDEVMULTITOUCH_UNIGNORE_RELATIVE | EVDEVMULTITOUCH_UNIGNORE_ABSOLUTE))
2270         EvdevMultitouchInitAnyClass(device, pEvdevMultitouch);
2271     else if (pEvdevMultitouch->flags & (EVDEVMULTITOUCH_TOUCHPAD | EVDEVMULTITOUCH_TOUCHSCREEN | EVDEVMULTITOUCH_TABLET | EVDEVMULTITOUCH_MULTITOUCH))
2272         EvdevMultitouchInitTouchDevice(device, pEvdevMultitouch);
2273     else if (pEvdevMultitouch->flags & EVDEVMULTITOUCH_RELATIVE_EVENTS)
2274         EvdevMultitouchInitRelClass(device, pEvdevMultitouch);
2275     else if (pEvdevMultitouch->flags & EVDEVMULTITOUCH_ABSOLUTE_EVENTS)
2276         EvdevMultitouchInitAbsClass(device, pEvdevMultitouch);
2277
2278 #ifdef HAVE_PROPERTIES
2279     /* We drop the return value, the only time we ever want the handlers to
2280      * unregister is when the device dies. In which case we don't have to
2281      * unregister anyway */
2282     EvdevMultitouchInitProperty(device);
2283     XIRegisterPropertyHandler(device, EvdevMultitouchSetProperty, NULL, NULL);
2284     EvdevMultitouchMBEmuInitProperty(device);
2285     EvdevMultitouchWheelEmuInitProperty(device);
2286     EvdevMultitouchDragLockInitProperty(device);
2287 #endif
2288
2289     return Success;
2290 }
2291
2292 /**
2293  * Init all extras (wheel emulation, etc.) and grab the device.
2294  *
2295  * Coming from a resume, the grab may fail with ENODEV. In this case, we set a
2296  * timer to wake up and try to reopen the device later.
2297  */
2298 static int
2299 EvdevMultitouchOn(DeviceIntPtr device)
2300 {
2301     InputInfoPtr pInfo;
2302     EvdevMultitouchPtr pEvdevMultitouch;
2303     int rc = 0;
2304     BOOL finish = False;
2305
2306
2307     pInfo = device->public.devicePrivate;
2308     pEvdevMultitouch = pInfo->private;
2309
2310     /* If this is an object device,
2311      * just add device to subdev list */
2312     if (!EvdevMultitouchIsCoreDevice(pInfo)) {
2313         finish = True;
2314     } else {
2315        if (pInfo->fd != -1 && pEvdevMultitouch->grabDevice &&
2316             (rc = ioctl(pInfo->fd, EVIOCGRAB, (void *)1)))
2317         {
2318             xf86Msg(X_WARNING, "%s: Grab failed (%s)\n", pInfo->name,
2319                     strerror(errno));
2320
2321             /* ENODEV - device has disappeared after resume */
2322             if (rc && errno == ENODEV)
2323             {
2324                 close(pInfo->fd);
2325                 pInfo->fd = -1;
2326             }
2327         }
2328
2329         if (pInfo->fd == -1)
2330         {
2331             pEvdevMultitouch->reopen_left = pEvdevMultitouch->reopen_attempts;
2332             pEvdevMultitouch->reopen_timer = TimerSet(pEvdevMultitouch->reopen_timer, 0, 100, EvdevMultitouchReopenTimer, pInfo);
2333         } else
2334         {
2335             pEvdevMultitouch->min_maj = EvdevMultitouchGetMajorMinor(pInfo);
2336             if (EvdevMultitouchIsDuplicate(pInfo))
2337             {
2338                 xf86Msg(X_WARNING, "%s: Refusing to enable duplicate device.\n",
2339                         pInfo->name);
2340                 
2341                 return !Success;
2342             }
2343
2344             pEvdevMultitouch->reopen_timer = TimerSet(pEvdevMultitouch->reopen_timer, 0, 0, NULL, NULL);
2345
2346             xf86FlushInput(pInfo->fd);
2347             
2348             EvdevMultitouchSetMultitouch(pInfo, pEvdevMultitouch->num_multitouch);
2349             
2350             finish = True;
2351         }
2352     }
2353
2354     if (finish) {
2355          if( !strstr(pInfo->name, "subdev" ) )
2356         {
2357                 xf86AddEnabledDevice(pInfo);
2358                 pEvdevMultitouch->last_slot = 0;
2359                 EvdevMultitouchReinitPEvdevMultitouch(pInfo);
2360         }
2361         EvdevMultitouchMBEmuOn(pInfo);
2362         pEvdevMultitouch->flags |= EVDEVMULTITOUCH_INITIALIZED;
2363         device->public.on = TRUE;
2364
2365          pEvdevMultitouch->multitouch_setting_timer = TimerSet(pEvdevMultitouch->multitouch_setting_timer, 0, 100, EvdevMultitouchMultitouchSettingTimer, pInfo);
2366     }
2367
2368     if( pEvdevMultitouch->use_poll != TRUE )
2369                 return Success;
2370
2371     EvdevMultitouchSetUsePoll(pInfo, TRUE);
2372
2373     return Success;
2374 }
2375
2376 static void
2377 EvdevMultitouchOff(DeviceIntPtr device)
2378 {
2379         InputInfoPtr pInfo;
2380         EvdevMultitouchPtr pEvdevMultitouch;
2381
2382         pInfo = device->public.devicePrivate;
2383         pEvdevMultitouch = pInfo->private;
2384
2385     if( pEvdevMultitouch->use_poll != TRUE )
2386                 return;
2387
2388     EvdevMultitouchSetUsePoll(pInfo, FALSE);
2389 }
2390
2391 static int
2392 EvdevMultitouchProc(DeviceIntPtr device, int what)
2393 {
2394     InputInfoPtr pInfo;
2395     EvdevMultitouchPtr pEvdevMultitouch, g_pEvdevMultitouch;
2396     int i;
2397
2398
2399     pInfo = device->public.devicePrivate;
2400     pEvdevMultitouch = pInfo->private;
2401
2402     switch (what)
2403     {
2404     case DEVICE_INIT:
2405         return EvdevMultitouchInit(device);
2406
2407     case DEVICE_ON:
2408         return EvdevMultitouchOn(device);
2409
2410     case DEVICE_OFF:
2411          EvdevMultitouchOff(device);
2412         if (pEvdevMultitouch->flags & EVDEVMULTITOUCH_INITIALIZED)
2413             EvdevMultitouchMBEmuFinalize(pInfo);
2414         if (EvdevMultitouchIsCoreDevice(pInfo)){
2415             EvdevMultitouchSetMultitouch(pInfo, 0);
2416             if (pInfo->fd != -1)
2417             {
2418                 if (pEvdevMultitouch->grabDevice && ioctl(pInfo->fd, EVIOCGRAB, (void *)0))
2419                     xf86Msg(X_WARNING, "%s: Release failed (%s)\n", pInfo->name,
2420                             strerror(errno));
2421                 xf86RemoveEnabledDevice(pInfo);
2422                 close(pInfo->fd);
2423                 pInfo->fd = -1;
2424             }
2425              if( pEvdevMultitouch->multitouch_setting_timer )
2426              {
2427                   TimerFree(pEvdevMultitouch->multitouch_setting_timer);
2428                  pEvdevMultitouch->multitouch_setting_timer = NULL;
2429              }
2430             if (pEvdevMultitouch->reopen_timer)
2431             {
2432                 TimerFree(pEvdevMultitouch->reopen_timer);
2433                 pEvdevMultitouch->reopen_timer = NULL;
2434             }
2435         } else {
2436             /* removing it in the list of the core device */
2437             g_pEvdevMultitouch = pEvdevMultitouch->core_device->private;
2438             for (i=0; i<MAX_VALUATORS_MT; ++i) {
2439                 if (g_pEvdevMultitouch->vals_mt[i].pInfo == pInfo) {
2440                     g_pEvdevMultitouch->vals_mt[i].pInfo = NULL;
2441                     break;
2442                 }
2443             }
2444             xf86RemoveEnabledDevice(pInfo);
2445         }
2446         pEvdevMultitouch->min_maj = 0;
2447         pEvdevMultitouch->flags &= ~EVDEVMULTITOUCH_INITIALIZED;
2448         device->public.on = FALSE;
2449     break;
2450
2451     case DEVICE_CLOSE:
2452         xf86Msg(X_INFO, "%s: Close\n", pInfo->name);
2453         if (EvdevMultitouchIsCoreDevice(pInfo)) { // master only
2454             //EvdevMultitouchDeleteAllSubdevices(pInfo);
2455             
2456             if (pInfo->fd != -1) {
2457                 close(pInfo->fd);
2458                 pInfo->fd = -1;
2459             }
2460             EvdevMultitouchRemoveDevice(pInfo);
2461         }
2462         pEvdevMultitouch->min_maj = 0;
2463     break;
2464     }
2465
2466     return Success;
2467 }
2468
2469 /**
2470  * Get as much information as we can from the fd and cache it.
2471  * If compare is True, then the information retrieved will be compared to the
2472  * one already cached. If the information does not match, then this function
2473  * returns an error.
2474  *
2475  * @return Success if the information was cached, or !Success otherwise.
2476  */
2477 static int
2478 EvdevMultitouchCacheCompare(InputInfoPtr pInfo, BOOL compare)
2479 {
2480     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
2481     size_t len;
2482
2483     char name[1024]                  = {0};
2484     unsigned long bitmask[NLONGS(EV_CNT)]      = {0};
2485     unsigned long key_bitmask[NLONGS(KEY_CNT)] = {0};
2486     unsigned long rel_bitmask[NLONGS(REL_CNT)] = {0};
2487     unsigned long abs_bitmask[NLONGS(ABS_CNT)] = {0};
2488     unsigned long led_bitmask[NLONGS(LED_CNT)] = {0};
2489
2490     if (ioctl(pInfo->fd, EVIOCGNAME(sizeof(name) - 1), name) < 0) {
2491         xf86Msg(X_ERROR, "ioctl EVIOCGNAME failed: %s\n", strerror(errno));
2492         goto error;
2493     }
2494
2495     if (!compare) {
2496         strcpy(pEvdevMultitouch->name, name);
2497     } else if (strcmp(pEvdevMultitouch->name, name)) {
2498         xf86Msg(X_ERROR, "%s: device name changed: %s != %s\n",
2499                 pInfo->name, pEvdevMultitouch->name, name);
2500         goto error;
2501     }
2502
2503     len = ioctl(pInfo->fd, EVIOCGBIT(0, sizeof(bitmask)), bitmask);
2504     if (len < 0) {
2505         xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n",
2506                 pInfo->name, strerror(errno));
2507         goto error;
2508     }
2509
2510     if (!compare) {
2511         memcpy(pEvdevMultitouch->bitmask, bitmask, len);
2512     } else if (memcmp(pEvdevMultitouch->bitmask, bitmask, len)) {
2513         xf86Msg(X_ERROR, "%s: device bitmask has changed\n", pInfo->name);
2514         goto error;
2515     }
2516
2517     len = ioctl(pInfo->fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask);
2518     if (len < 0) {
2519         xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n",
2520                 pInfo->name, strerror(errno));
2521         goto error;
2522     }
2523
2524     if (!compare) {
2525         memcpy(pEvdevMultitouch->rel_bitmask, rel_bitmask, len);
2526     } else if (memcmp(pEvdevMultitouch->rel_bitmask, rel_bitmask, len)) {
2527         xf86Msg(X_ERROR, "%s: device rel_bitmask has changed\n", pInfo->name);
2528         goto error;
2529     }
2530
2531     len = ioctl(pInfo->fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask);
2532     if (len < 0) {
2533         xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n",
2534                 pInfo->name, strerror(errno));
2535         goto error;
2536     }
2537
2538 #if 1//ABS_MT_SLOT
2539     if( TestBit(ABS_MT_SLOT, abs_bitmask) && TestBit(ABS_MT_TRACKING_ID, abs_bitmask) )
2540     {
2541          ErrorF("[X11] MT Protocol B Type : ABS_MT_SLOT is supported : \n");
2542           pEvdevMultitouch->mt_slot_supported = (BOOL)1;
2543     }
2544     else
2545     {
2546          ErrorF("[X11] MT Protocol A Type : ABS_MT_SLOT is NOT supported\n");
2547           pEvdevMultitouch->mt_slot_supported = (BOOL)0;
2548     }
2549 #endif
2550
2551     if (!compare) {
2552         memcpy(pEvdevMultitouch->abs_bitmask, abs_bitmask, len);
2553     } else if (memcmp(pEvdevMultitouch->abs_bitmask, abs_bitmask, len)) {
2554         xf86Msg(X_ERROR, "%s: device abs_bitmask has changed\n", pInfo->name);
2555         goto error;
2556     }
2557
2558     len = ioctl(pInfo->fd, EVIOCGBIT(EV_LED, sizeof(led_bitmask)), led_bitmask);
2559     if (len < 0) {
2560         xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n",
2561                 pInfo->name, strerror(errno));
2562         goto error;
2563     }
2564
2565     if (!compare) {
2566         memcpy(pEvdevMultitouch->led_bitmask, led_bitmask, len);
2567     } else if (memcmp(pEvdevMultitouch->led_bitmask, led_bitmask, len)) {
2568         xf86Msg(X_ERROR, "%s: device led_bitmask has changed\n", pInfo->name);
2569         goto error;
2570     }
2571
2572     /*
2573      * Do not try to validate absinfo data since it is not expected
2574      * to be static, always refresh it in evdevmultitouch structure.
2575      */
2576         if( !xf86CheckStrOption(pInfo->options, "Resolution", NULL) )
2577         {
2578 #ifdef _F_IGNORE_TSP_RESOLUTION_
2579             pEvdevMultitouch->absinfo[ABS_X].maximum = 0;
2580             pEvdevMultitouch->absinfo[ABS_X].minimum = 0;
2581             pEvdevMultitouch->absinfo[ABS_Y].maximum = 0;
2582             pEvdevMultitouch->absinfo[ABS_Y].minimum = 0;
2583 #else//_F_IGNORE_TSP_RESOLUTION_
2584             for (i = ABS_X; i <= ABS_MAX; i++) {
2585                 if (TestBit(i, abs_bitmask)) {
2586                     len = ioctl(pInfo->fd, EVIOCGABS(i), &pEvdevMultitouch->absinfo[i]);
2587                     if (len < 0) {
2588                         xf86Msg(X_ERROR, "%s: ioctl EVIOCGABSi(%d) failed: %s\n",
2589                                 pInfo->name, i, strerror(errno));
2590                         goto error;
2591                     }
2592                 }
2593             }
2594 #endif//_F_IGNORE_TSP_RESOLUTION_
2595         }
2596
2597     len = ioctl(pInfo->fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask);
2598     if (len < 0) {
2599         xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n",
2600                 pInfo->name, strerror(errno));
2601         goto error;
2602     }
2603
2604     if (compare) {
2605         /*
2606          * Keys are special as user can adjust keymap at any time (on
2607          * devices that support EVIOCSKEYCODE. However we do not expect
2608          * buttons reserved for mice/tablets/digitizers and so on to
2609          * appear/disappear so we will check only those in
2610          * [BTN_MISC, KEY_OK) range.
2611          */
2612         size_t start_word = BTN_MISC / LONG_BITS;
2613         size_t start_byte = start_word * sizeof(unsigned long);
2614         size_t end_word = KEY_OK / LONG_BITS;
2615         size_t end_byte = end_word * sizeof(unsigned long);
2616
2617         if (len >= start_byte &&
2618             memcmp(&pEvdevMultitouch->key_bitmask[start_word], &key_bitmask[start_word],
2619                    min(len, end_byte) - start_byte + 1)) {
2620             xf86Msg(X_ERROR, "%s: device key_bitmask has changed\n", pInfo->name);
2621             goto error;
2622         }
2623     }
2624
2625     /* Copy the data so we have reasonably up-to-date info */
2626     memcpy(pEvdevMultitouch->key_bitmask, key_bitmask, len);
2627
2628     return Success;
2629
2630 error:
2631     return !Success;
2632
2633 }
2634
2635 static int
2636 EvdevMultitouchProbe(InputInfoPtr pInfo)
2637 {
2638     int i, has_rel_axes, has_abs_axes, has_keys, num_buttons, has_scroll;
2639     int kernel24 = 0;
2640     int ignore_abs = 0, ignore_rel = 0;
2641     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
2642
2643     if (pEvdevMultitouch->grabDevice && ioctl(pInfo->fd, EVIOCGRAB, (void *)1)) {
2644         if (errno == EINVAL) {
2645             /* keyboards are unsafe in 2.4 */
2646             kernel24 = 1;
2647             pEvdevMultitouch->grabDevice = 0;
2648         } else {
2649             xf86Msg(X_ERROR, "Grab failed. Device already configured?\n");
2650             return 1;
2651         }
2652     } else if (pEvdevMultitouch->grabDevice) {
2653         ioctl(pInfo->fd, EVIOCGRAB, (void *)0);
2654     }
2655
2656     /* Trinary state for ignoring axes:
2657        - unset: do the normal thing.
2658        - TRUE: explicitly ignore them.
2659        - FALSE: unignore axes, use them at all cost if they're present.
2660      */
2661     if (xf86FindOption(pInfo->options, "IgnoreRelativeAxes"))
2662     {
2663         if (xf86SetBoolOption(pInfo->options, "IgnoreRelativeAxes", FALSE))
2664             ignore_rel = TRUE;
2665         else
2666             pEvdevMultitouch->flags |= EVDEVMULTITOUCH_UNIGNORE_RELATIVE;
2667
2668     }
2669     if (xf86FindOption(pInfo->options, "IgnoreAbsoluteAxes"))
2670     {
2671         if (xf86SetBoolOption(pInfo->options, "IgnoreAbsoluteAxes", FALSE))
2672            ignore_abs = TRUE;
2673         else
2674             pEvdevMultitouch->flags |= EVDEVMULTITOUCH_UNIGNORE_ABSOLUTE;
2675     }
2676
2677     has_rel_axes = FALSE;
2678     has_abs_axes = FALSE;
2679     has_keys = FALSE;
2680     has_scroll = FALSE;
2681     num_buttons = 0;
2682
2683     /* count all buttons */
2684     for (i = BTN_MISC; i < BTN_JOYSTICK; i++)
2685     {
2686         int mapping = 0;
2687         if (TestBit(i, pEvdevMultitouch->key_bitmask))
2688         {
2689             mapping = EvdevMultitouchUtilButtonEventToButtonNumber(pEvdevMultitouch, i);
2690             if (mapping > num_buttons)
2691                 num_buttons = mapping;
2692         }
2693     }
2694
2695     if (num_buttons)
2696     {
2697         pEvdevMultitouch->flags |= EVDEVMULTITOUCH_BUTTON_EVENTS;
2698         pEvdevMultitouch->num_buttons = num_buttons;
2699         xf86Msg(X_INFO, "%s: Found %d mouse buttons\n", pInfo->name,
2700                 num_buttons);
2701     }
2702
2703     for (i = 0; i < REL_MAX; i++) {
2704         if (TestBit(i, pEvdevMultitouch->rel_bitmask)) {
2705             has_rel_axes = TRUE;
2706             break;
2707         }
2708     }
2709
2710     if (has_rel_axes) {
2711         if (TestBit(REL_WHEEL, pEvdevMultitouch->rel_bitmask) ||
2712             TestBit(REL_HWHEEL, pEvdevMultitouch->rel_bitmask) ||
2713             TestBit(REL_DIAL, pEvdevMultitouch->rel_bitmask)) {
2714             xf86Msg(X_INFO, "%s: Found scroll wheel(s)\n", pInfo->name);
2715             has_scroll = TRUE;
2716             if (!num_buttons)
2717                 xf86Msg(X_INFO, "%s: Forcing buttons for scroll wheel(s)\n",
2718                         pInfo->name);
2719             num_buttons = (num_buttons < 3) ? 7 : num_buttons + 4;
2720             pEvdevMultitouch->num_buttons = num_buttons;
2721         }
2722
2723         if (!ignore_rel)
2724         {
2725             xf86Msg(X_INFO, "%s: Found relative axes\n", pInfo->name);
2726             pEvdevMultitouch->flags |= EVDEVMULTITOUCH_RELATIVE_EVENTS;
2727
2728             if (TestBit(REL_X, pEvdevMultitouch->rel_bitmask) &&
2729                 TestBit(REL_Y, pEvdevMultitouch->rel_bitmask)) {
2730                 xf86Msg(X_INFO, "%s: Found x and y relative axes\n", pInfo->name);
2731             }
2732         } else {
2733             xf86Msg(X_INFO, "%s: Relative axes present but ignored.\n", pInfo->name);
2734             has_rel_axes = FALSE;
2735         }
2736     }
2737
2738     for (i = 0; i < ABS_MAX; i++) {
2739         if (TestBit(i, pEvdevMultitouch->abs_bitmask)) {
2740             has_abs_axes = TRUE;
2741             break;
2742         }
2743     }
2744
2745     if (ignore_abs && has_abs_axes)
2746     {
2747         xf86Msg(X_INFO, "%s: Absolute axes present but ignored.\n", pInfo->name);
2748         has_abs_axes = FALSE;
2749     } else if (has_abs_axes) {
2750         xf86Msg(X_INFO, "%s: Found absolute axes\n", pInfo->name);
2751         pEvdevMultitouch->flags |= EVDEVMULTITOUCH_ABSOLUTE_EVENTS;
2752
2753         if ((TestBit(ABS_X, pEvdevMultitouch->abs_bitmask) &&
2754              TestBit(ABS_Y, pEvdevMultitouch->abs_bitmask))) {
2755             xf86Msg(X_INFO, "%s: Found x and y absolute axes\n", pInfo->name);
2756             if (TestBit(BTN_TOOL_PEN, pEvdevMultitouch->key_bitmask))
2757             {
2758                 xf86Msg(X_INFO, "%s: Found absolute tablet.\n", pInfo->name);
2759                 pEvdevMultitouch->flags |= EVDEVMULTITOUCH_TABLET;
2760             } else if ((TestBit(ABS_MT_POSITION_X, pEvdevMultitouch->abs_bitmask) &&
2761                         TestBit(ABS_MT_POSITION_Y, pEvdevMultitouch->abs_bitmask))) {
2762                 xf86Msg(X_INFO, "%s: Found absolute multitouch tablet.\n", pInfo->name);
2763                 pEvdevMultitouch->flags |= EVDEVMULTITOUCH_MULTITOUCH;
2764             } else if (TestBit(ABS_PRESSURE, pEvdevMultitouch->abs_bitmask) ||
2765                 TestBit(BTN_TOUCH, pEvdevMultitouch->key_bitmask)) {
2766                 if (num_buttons || TestBit(BTN_TOOL_FINGER, pEvdevMultitouch->key_bitmask)) {
2767                     xf86Msg(X_INFO, "%s: Found absolute touchpad.\n", pInfo->name);
2768                     pEvdevMultitouch->flags |= EVDEVMULTITOUCH_TOUCHPAD;
2769                     memset(pEvdevMultitouch->old_vals, -1, sizeof(int) * pEvdevMultitouch->num_vals);
2770                 } else {
2771                     xf86Msg(X_INFO, "%s: Found absolute touchscreen\n", pInfo->name);
2772                     pEvdevMultitouch->flags |= EVDEVMULTITOUCH_TOUCHSCREEN;
2773                     pEvdevMultitouch->flags |= EVDEVMULTITOUCH_BUTTON_EVENTS;
2774                 }
2775             }
2776         }
2777     }
2778
2779     for (i = 0; i < BTN_MISC; i++) {
2780         if (TestBit(i, pEvdevMultitouch->key_bitmask)) {
2781             xf86Msg(X_INFO, "%s: Found keys\n", pInfo->name);
2782             pEvdevMultitouch->flags |= EVDEVMULTITOUCH_KEYBOARD_EVENTS;
2783             has_keys = TRUE;
2784             break;
2785         }
2786     }
2787
2788     if (has_rel_axes || has_abs_axes || num_buttons) {
2789         pInfo->flags |= XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS |
2790                         XI86_CONFIGURED;
2791         if (pEvdevMultitouch->flags & EVDEVMULTITOUCH_TOUCHPAD) {
2792             xf86Msg(X_INFO, "%s: Configuring as touchpad\n", pInfo->name);
2793             pInfo->type_name = XI_TOUCHPAD;
2794         } else if (pEvdevMultitouch->flags & EVDEVMULTITOUCH_TABLET) {
2795             xf86Msg(X_INFO, "%s: Configuring as tablet\n", pInfo->name);
2796             pInfo->type_name = XI_TABLET;
2797         } else if (pEvdevMultitouch->flags & EVDEVMULTITOUCH_TOUCHSCREEN) {
2798             xf86Msg(X_INFO, "%s: Configuring as touchscreen\n", pInfo->name);
2799             pInfo->type_name = XI_TOUCHSCREEN;
2800         } else if (pEvdevMultitouch->flags & EVDEVMULTITOUCH_MULTITOUCH) {
2801             xf86Msg(X_INFO, "%s: Configuring as multitouch screen\n", pInfo->name);
2802             pInfo->type_name = "MULTITOUCHSCREEN";
2803         } else {
2804             xf86Msg(X_INFO, "%s: Configuring as mouse\n", pInfo->name);
2805             pInfo->type_name = XI_MOUSE;
2806         }
2807     }
2808
2809     if (has_keys) {
2810         if (kernel24) {
2811             xf86Msg(X_INFO, "%s: Kernel < 2.6 is too old, ignoring keyboard\n",
2812                     pInfo->name);
2813         } else {
2814             xf86Msg(X_INFO, "%s: Configuring as keyboard\n", pInfo->name);
2815             pInfo->flags |= XI86_KEYBOARD_CAPABLE | XI86_CONFIGURED;
2816             pInfo->type_name = XI_KEYBOARD;
2817         }
2818     }
2819
2820     if (has_scroll && (pInfo->flags & XI86_CONFIGURED) &&
2821         (pInfo->flags & XI86_POINTER_CAPABLE) == 0)
2822     {
2823         xf86Msg(X_INFO, "%s: Adding scrollwheel support\n", pInfo->name);
2824         pInfo->flags  |= XI86_POINTER_CAPABLE;
2825         pEvdevMultitouch->flags |= EVDEVMULTITOUCH_BUTTON_EVENTS;
2826         pEvdevMultitouch->flags |= EVDEVMULTITOUCH_RELATIVE_EVENTS;
2827     }
2828
2829     if ((pInfo->flags & XI86_CONFIGURED) == 0) {
2830         xf86Msg(X_WARNING, "%s: Don't know how to use device\n",
2831                 pInfo->name);
2832         return 1;
2833     }
2834
2835     return 0;
2836 }
2837
2838 static void
2839 EvdevMultitouchSetCalibration(InputInfoPtr pInfo, int num_calibration, int calibration[4])
2840 {
2841     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
2842
2843     if (num_calibration == 0) {
2844         pEvdevMultitouch->flags &= ~EVDEVMULTITOUCH_CALIBRATED;
2845         pEvdevMultitouch->calibration.min_x = 0;
2846         pEvdevMultitouch->calibration.max_x = 0;
2847         pEvdevMultitouch->calibration.min_y = 0;
2848         pEvdevMultitouch->calibration.max_y = 0;
2849     } else if (num_calibration == 4) {
2850         pEvdevMultitouch->flags |= EVDEVMULTITOUCH_CALIBRATED;
2851         pEvdevMultitouch->calibration.min_x = calibration[0];
2852         pEvdevMultitouch->calibration.max_x = calibration[1];
2853         pEvdevMultitouch->calibration.min_y = calibration[2];
2854         pEvdevMultitouch->calibration.max_y = calibration[3];
2855     }
2856 }
2857
2858 static void
2859 EvdevMultitouchSetResolution(InputInfoPtr pInfo, int num_resolution, int resolution[4])
2860 {
2861     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
2862
2863     if (num_resolution == 0) {
2864         pEvdevMultitouch->flags &= ~EVDEVMULTITOUCH_RESOLUTION;
2865         pEvdevMultitouch->resolution.min_x = 0;
2866         pEvdevMultitouch->resolution.max_x = 0;
2867         pEvdevMultitouch->resolution.min_y = 0;
2868         pEvdevMultitouch->resolution.max_y = 0;
2869     } else if (num_resolution == 4) {
2870         pEvdevMultitouch->flags |= EVDEVMULTITOUCH_RESOLUTION;
2871         pEvdevMultitouch->resolution.min_x = resolution[0];
2872         pEvdevMultitouch->resolution.max_x = resolution[1];
2873         pEvdevMultitouch->resolution.min_y = resolution[2];
2874         pEvdevMultitouch->resolution.max_y = resolution[3];
2875     }
2876 }
2877
2878 static void EvdevMultitouchSetTransform(InputInfoPtr pInfo, int num_transform, float *tmatrix)
2879 {
2880         int x, y;
2881         struct pixman_transform tr;
2882
2883         if( num_transform != 9 )
2884         {
2885                 use_transform = False;
2886                 return;
2887         }
2888         use_transform = True;
2889
2890         memcpy(transform, tmatrix, sizeof(transform));
2891         for (y=0; y<3; y++)
2892                 for (x=0; x<3; x++)
2893                         tr.matrix[y][x] = pixman_double_to_fixed((double)*tmatrix++);
2894
2895         pixman_transform_invert(&inv_transform, &tr);
2896 }
2897
2898 static void
2899 EvdevMultitouchSetMultitouch(InputInfoPtr pInfo, int num_multitouch) {
2900     EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
2901     int i, rc;
2902
2903     if( !(pEvdevMultitouch->flags & EVDEVMULTITOUCH_MULTITOUCH) ) 
2904     { 
2905             ErrorF("[X11][%s] Device is not a multitouch screen !(flags=%d)\n", __FUNCTION__, pEvdevMultitouch->flags); 
2906             return; 
2907     }
2908
2909     if (num_multitouch > MAX_VALUATORS_MT)
2910         num_multitouch = MAX_VALUATORS_MT;
2911     if (num_multitouch < 0)
2912         num_multitouch = 0;
2913
2914     for (i=0;i<num_multitouch;++i) {
2915         if (pEvdevMultitouch->vals_mt[i].pInfo == NULL){
2916             pEvdevMultitouch->vals_mt[i].containsValues = FALSE;
2917             pEvdevMultitouch->vals_mt[i].id = -1;
2918             pEvdevMultitouch->vals_mt[i].pInfo = EvdevMultitouchCreateSubDevice(pInfo, i);
2919         }
2920     }
2921     for (i=num_multitouch;i<MAX_VALUATORS_MT;++i) {
2922         pEvdevMultitouch->vals_mt[i].containsValues = FALSE;
2923         pEvdevMultitouch->vals_mt[i].id = -1;
2924         if (pEvdevMultitouch->vals_mt[i].pInfo && pEvdevMultitouch->vals_mt[i].pInfo != pInfo) {
2925             EvdevMultitouchDeleteSubDevice(pInfo, pEvdevMultitouch->vals_mt[i].pInfo);
2926             pEvdevMultitouch->vals_mt[i].pInfo = NULL;
2927         }
2928     }
2929     
2930     pEvdevMultitouch->num_multitouch = num_multitouch;
2931
2932     rc = XIChangeDeviceProperty(pInfo->dev, prop_multitouch, XA_INTEGER, 8, 
2933                 PropModeReplace, 1, &pEvdevMultitouch->num_multitouch, FALSE);
2934
2935     if (rc != Success)
2936             ErrorF("[X11][%s] Failed to Change device property !\n", __FUNCTION__);
2937 }
2938
2939 static void
2940 EvdevMultitouchSetUsePoll(InputInfoPtr pInfo, BOOL use_poll)
2941 {
2942         EvdevMultitouchPtr pEvdevMultitouch = pInfo->private;
2943         
2944         if( use_poll == TRUE )
2945         {
2946                 if( !EvdevMultitouchIsCoreDevice(pInfo) )//master only
2947                         goto out;
2948         
2949                 if( !vsync_input_table)
2950                 {
2951                         vsync_input_table = vsync_input_init();
2952                         if( !vsync_input_table )
2953                         {
2954                                 ErrorF("[SetUsePoll] Failed to init vsync input ...\n");
2955                                 goto out;
2956                         }
2957                 }
2958                 
2959                 g_syspoll_fd = open(SYSFS_POLL, O_WRONLY);
2960                 if( g_syspoll_fd < 0 )
2961                 {
2962                         g_syspoll_fd = -1;
2963                         ErrorF("[SetUsePoll] Failed to open %s ...\n", SYSFS_POLL);
2964                         goto out;
2965                 }
2966                 
2967                 vsync_input_table->sync = sync_poll;
2968                 vsync_input_table->stop_sync(vsync_input_table->sync_arg);
2969                 poll_control(POLL_ENABLE);
2970                 pEvdevMultitouch->use_poll = use_poll;
2971         }
2972         else if( use_poll == FALSE )
2973         {
2974                 if( !EvdevMultitouchIsCoreDevice(pInfo) )//master only
2975                         goto out;
2976                 
2977                 if( !vsync_input_table)
2978                         goto out;
2979                 
2980                 vsync_input_table->stop_sync(vsync_input_table->sync_arg);
2981                 vsync_input_table->sync = NULL;
2982                 vsync_input_close(vsync_input_table);
2983                 vsync_input_table = NULL;
2984                 poll_control(POLL_DISABLE);
2985                 close(g_syspoll_fd);
2986                 g_syspoll_fd = -1;
2987                 pEvdevMultitouch->use_poll = use_poll;
2988         }
2989         else
2990                 ErrorF("\n[SetUsePoll] Unknown value for use_poll (%d)\n", use_poll);
2991
2992 out:
2993         return;
2994 }
2995
2996 Bool
2997 IsMaster(DeviceIntPtr dev)
2998 {
2999     return dev->type == MASTER_POINTER || dev->type == MASTER_KEYBOARD;
3000 }
3001
3002 DeviceIntPtr
3003 GetPairedDevice(DeviceIntPtr dev)
3004 {
3005     if (!IsMaster(dev) && dev->u.master)
3006         dev = dev->u.master;
3007
3008     return dev->spriteInfo->paired;
3009 }
3010
3011 DeviceIntPtr
3012 GetMaster(DeviceIntPtr dev, int which)
3013 {
3014     DeviceIntPtr master;
3015
3016     if (IsMaster(dev))
3017         master = dev;
3018     else
3019         master = dev->u.master;
3020
3021     if (master)
3022     {
3023         if (which == MASTER_KEYBOARD)
3024         {
3025             if (master->type != MASTER_KEYBOARD)
3026                 master = GetPairedDevice(master);
3027         } else
3028         {
3029             if (master->type != MASTER_POINTER)
3030                 master = GetPairedDevice(master);
3031         }
3032     }
3033
3034     return master;
3035 }
3036
3037 static void
3038 EvdevMultitouchGetGrabInfo(InputInfoPtr pInfo, BOOL  val)
3039 {
3040         DeviceIntPtr master_pointer;
3041
3042         if( val == 1 )
3043         {
3044                 if( pInfo->dev->deviceGrab.grab )
3045                 {
3046                         ErrorF("[X11][EvdevMultitouchGetGrabInfo] Device id=%d (grabbed) !\n", pInfo->dev->id);
3047                         ErrorF("[X11][EvdevMultitouchGetGrabInfo]  (event) type=%d\n", pInfo->dev->deviceGrab.grab->type);
3048                         ErrorF("[X11][EvdevMultitouchGetGrabInfo]  grabtype=%d\n", pInfo->dev->deviceGrab.grab->grabtype);
3049                         ErrorF("[X11][EvdevMultitouchGetGrabInfo]  resource=0x%x\n", (unsigned int)pInfo->dev->deviceGrab.grab->resource);
3050                         ErrorF("[X11][EvdevMultitouchGetGrabInfo]  keyboardMode=%d\n", pInfo->dev->deviceGrab.grab->keyboardMode);
3051                         ErrorF("[X11][EvdevMultitouchGetGrabInfo]  pointerMode=%d\n", pInfo->dev->deviceGrab.grab->pointerMode);
3052                         ErrorF("[X11][EvdevMultitouchGetGrabInfo]  sync.frozen=%d\n", pInfo->dev->deviceGrab.sync.frozen);
3053                         ErrorF("[X11][EvdevMultitouchGetGrabInfo]  fromPassiveGrab=%d\n", pInfo->dev->deviceGrab.fromPassiveGrab);
3054                         ErrorF("[X11][EvdevMultitouchGetGrabInfo]  implicitGrab=%d\n", pInfo->dev->deviceGrab.implicitGrab);
3055                 }
3056                 else if( (master_pointer = GetMaster(pInfo->dev, MASTER_POINTER)) && master_pointer->deviceGrab.grab )
3057                 {
3058                         ErrorF("[X11][EvdevMultitouchGetGrabInfo] Device id=%d (master_pointer, grabbed) !\n", master_pointer->id);
3059                         ErrorF("[X11][EvdevMultitouchGetGrabInfo]  (event) type=%d\n", master_pointer->deviceGrab.grab->type);
3060                         ErrorF("[X11][EvdevMultitouchGetGrabInfo]  grabtype=%d\n", master_pointer->deviceGrab.grab->grabtype);
3061                         ErrorF("[X11][EvdevMultitouchGetGrabInfo]  resource=0x%x\n", (unsigned int)master_pointer->deviceGrab.grab->resource);
3062                         ErrorF("[X11][EvdevMultitouchGetGrabInfo]  keyboardMode=%d\n", master_pointer->deviceGrab.grab->keyboardMode);
3063                         ErrorF("[X11][EvdevMultitouchGetGrabInfo]  pointerMode=%d\n", master_pointer->deviceGrab.grab->pointerMode);
3064                         ErrorF("[X11][EvdevMultitouchGetGrabInfo]  sync.frozen=%d\n", master_pointer->deviceGrab.sync.frozen);
3065                         ErrorF("[X11][EvdevMultitouchGetGrabInfo]  fromPassiveGrab=%d\n", master_pointer->deviceGrab.fromPassiveGrab);
3066                         ErrorF("[X11][EvdevMultitouchGetGrabInfo]  implicitGrab=%d\n", master_pointer->deviceGrab.implicitGrab);
3067                 }
3068                 else
3069                         ErrorF("[X11][EvdevMultitouchGetGrabInfo] Device id=%d (ungrabbed) !\n", pInfo->dev->id);
3070         }
3071 }
3072
3073 static InputInfoPtr
3074 EvdevMultitouchPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
3075 {
3076     InputInfoPtr pInfo;
3077     const char *device, *str;
3078     int num_calibration = 0, calibration[4] = { 0, 0, 0, 0 };
3079     int num_resolution = 0, resolution[4] = { 0, 0, 0, 0 };
3080     int num_transform = 0; float tr[9];
3081     EvdevMultitouchPtr pEvdevMultitouch;
3082     char *type;
3083
3084     if (!(pInfo = xf86AllocateInput(drv, 0)))
3085         return NULL;
3086
3087     /* Initialise the InputInfoRec. */
3088     pInfo->name = dev->identifier;
3089     pInfo->flags = 0;
3090     pInfo->type_name = "UNKNOWN";
3091     pInfo->device_control = EvdevMultitouchProc;
3092     pInfo->history_size = 0;
3093     pInfo->control_proc = NULL;
3094     pInfo->close_proc = NULL;
3095     pInfo->switch_mode = NULL;
3096     pInfo->conversion_proc = NULL;
3097     pInfo->reverse_conversion_proc = NULL;
3098     pInfo->dev = NULL;
3099     pInfo->private_flags = 0;
3100     pInfo->always_core_feedback = NULL;
3101     pInfo->conf_idev = dev;
3102
3103     if (!(pEvdevMultitouch = calloc(sizeof(EvdevMultitouchRec), 1)))
3104         return pInfo;
3105
3106     pInfo->private = pEvdevMultitouch;
3107
3108     xf86CollectInputOptions(pInfo, evdevmultitouchDefaults, NULL);
3109     xf86ProcessCommonOptions(pInfo, pInfo->options);
3110     pEvdevMultitouch->id = -1;
3111  
3112  
3113      /* If Type == Object, this is a device for an object to use */
3114     type = xf86CheckStrOption(dev->commonOptions, "Type", NULL);
3115
3116     xf86Msg(X_INFO, "%s: EvdevMultitouch Type %s found\n", dev->identifier,type);
3117        
3118     if (type != NULL && strcmp(type, "Object") == 0) {
3119         EvdevMultitouchPtr pCreatorEvdevMultitouch;
3120         if (!pCreatorInfo){
3121             return pInfo;
3122         }
3123         pCreatorEvdevMultitouch = pCreatorInfo->private;
3124         xf86Msg(X_INFO, "%s: EvdevMultitouch subdevice found\n", dev->identifier);
3125         memcpy(pEvdevMultitouch, pCreatorEvdevMultitouch, sizeof(EvdevMultitouchRec));
3126         pInfo->read_input = EvdevMultitouchSubdevReadInput;
3127         pInfo->flags |= XI86_CONFIGURED;
3128         pEvdevMultitouch->associated = FALSE;
3129         pInfo->type_name = pCreatorInfo->type_name;
3130         pEvdevMultitouch->num_multitouch = 1;
3131         //EvdevMultitouchInitButtonMapping(pInfo);
3132    } else {
3133         pInfo->read_input = EvdevMultitouchReadInput;
3134
3135         pEvdevMultitouch->core_device = pInfo;
3136         pEvdevMultitouch->associated = FALSE;
3137
3138         memset(pEvdevMultitouch->vals, 0, MAX_VALUATORS * sizeof(int));
3139         memset(pEvdevMultitouch->old_vals, -1, MAX_VALUATORS * sizeof(int));
3140         
3141         /*
3142          * We initialize pEvdevMultitouch->tool to 1 so that device that doesn't use
3143          * proximity will still report events.
3144          */
3145         pEvdevMultitouch->tool = 1;
3146
3147         device = xf86CheckStrOption(dev->commonOptions, "Device", NULL);
3148         if (!device) {
3149             xf86Msg(X_ERROR, "%s: No device specified.\n", pInfo->name);
3150         xf86DeleteInput(pInfo, 0);
3151             return NULL;
3152         }
3153
3154         pEvdevMultitouch->device = device;
3155
3156         xf86Msg(X_CONFIG, "%s: Device: \"%s\"\n", pInfo->name, device);
3157         do {
3158             pInfo->fd = open(device, O_RDWR | O_NONBLOCK, 0);
3159         } while (pInfo->fd < 0 && errno == EINTR);
3160
3161         if (pInfo->fd < 0) {
3162             xf86Msg(X_ERROR, "Unable to open evdevmultitouch device \"%s\".\n", device);
3163         xf86DeleteInput(pInfo, 0);
3164             return NULL;
3165         }
3166
3167         /* Check major/minor of device node to avoid adding duplicate devices. */
3168         pEvdevMultitouch->min_maj = EvdevMultitouchGetMajorMinor(pInfo);
3169         if (EvdevMultitouchIsDuplicate(pInfo))
3170         {
3171             xf86Msg(X_WARNING, "%s: device file already in use. Ignoring.\n",
3172                     pInfo->name);
3173             close(pInfo->fd);
3174             xf86DeleteInput(pInfo, 0);
3175             return NULL;
3176         }
3177
3178         pEvdevMultitouch->reopen_attempts = xf86SetIntOption(pInfo->options, "ReopenAttempts", 10);
3179         pEvdevMultitouch->invert_x = xf86SetBoolOption(pInfo->options, "InvertX", FALSE);
3180         pEvdevMultitouch->invert_y = xf86SetBoolOption(pInfo->options, "InvertY", FALSE);
3181         pEvdevMultitouch->num_multitouch = xf86SetIntOption(pInfo->options, "MultiTouch", 0);
3182         pEvdevMultitouch->swap_axes = xf86SetBoolOption(pInfo->options, "SwapAxes", FALSE);
3183         pEvdevMultitouch->use_poll = xf86SetBoolOption(pInfo->options, "UsePoll", FALSE);
3184
3185         str = xf86CheckStrOption(pInfo->options, "Calibration", NULL);
3186         if (str) {
3187             num_calibration = sscanf(str, "%d %d %d %d",
3188                                      &calibration[0], &calibration[1],
3189                                      &calibration[2], &calibration[3]);
3190             if (num_calibration == 4)
3191                 EvdevMultitouchSetCalibration(pInfo, num_calibration, calibration);
3192             else
3193                 xf86Msg(X_ERROR,
3194                         "%s: Insufficient calibration factors (%d). Ignoring calibration\n",
3195                         pInfo->name, num_calibration);
3196         }
3197
3198         str = xf86CheckStrOption(pInfo->options, "Resolution", NULL);
3199         if (str) {
3200             num_resolution = sscanf(str, "%d %d %d %d",
3201                                      &resolution[0], &resolution[1],
3202                                      &resolution[2], &resolution[3]);
3203             if (num_resolution == 4)
3204                 EvdevMultitouchSetResolution(pInfo, num_resolution, resolution);
3205             else
3206                 xf86Msg(X_ERROR,
3207                         "%s: Insufficient resolution factors (%d). Ignoring resolution\n",
3208                         pInfo->name, num_resolution);
3209         }
3210
3211          use_transform = False;
3212         str = xf86CheckStrOption(pInfo->options, "Transform", NULL);
3213         if (str) {
3214             num_transform = sscanf(str, "%f %f %f %f %f %f %f %f %f",
3215                                      &tr[0], &tr[1], &tr[2],
3216                                      &tr[3], &tr[4], &tr[5], 
3217                                      &tr[6], &tr[7], &tr[8]);
3218             if (num_transform == 9)
3219                 EvdevMultitouchSetTransform(pInfo, num_transform, tr);
3220             else
3221             {
3222                 xf86Msg(X_ERROR,
3223                         "%s: Insufficient transform factors (%d). Ignoring transform\n",
3224                         pInfo->name, num_transform);
3225             }
3226         }
3227
3228         /* Grabbing the event device stops in-kernel event forwarding. In other
3229            words, it disables rfkill and the "Macintosh mouse button emulation".
3230            Note that this needs a server that sets the console to RAW mode. */
3231         pEvdevMultitouch->grabDevice = xf86CheckBoolOption(dev->commonOptions, "GrabDevice", 0);
3232
3233         /* Get setting for checking wether a point is still alive */
3234         pEvdevMultitouch->timeout = xf86CheckIntOption(dev->commonOptions,
3235                 "SubdevTimeout", DEFAULT_TIMEOUT);
3236         if (pEvdevMultitouch->timeout < 1) {
3237             pEvdevMultitouch->timeout = 1;
3238         }
3239         xf86Msg(X_INFO, "%s: SubdevTimeout set to %d\n",
3240                 dev->identifier, (int)pEvdevMultitouch->timeout);
3241
3242         EvdevMultitouchInitButtonMapping(pInfo);
3243
3244         if (EvdevMultitouchCacheCompare(pInfo, FALSE) ||
3245             EvdevMultitouchProbe(pInfo)) {
3246             close(pInfo->fd);
3247             xf86DeleteInput(pInfo, 0);
3248             return NULL;
3249         }
3250         
3251         if ((pEvdevMultitouch->flags & EVDEVMULTITOUCH_MULTITOUCH) && !pEvdevMultitouch->num_buttons) {
3252             /* absolute multitouch screen :
3253              * forcing num_buttons = 1
3254              */
3255             pEvdevMultitouch->num_buttons = 1;
3256             pEvdevMultitouch->flags |= EVDEVMULTITOUCH_BUTTON_EVENTS;
3257         }
3258
3259         if(pEvdevMultitouch->flags & EVDEVMULTITOUCH_MULTITOUCH)
3260         {
3261             pEvdevMultitouch->num_multitouch = 1;
3262             pEvdevMultitouch->vals_mt[0].pInfo = pInfo;
3263         }
3264
3265         if(pEvdevMultitouch->flags & EVDEVMULTITOUCH_RESOLUTION)
3266         {
3267                 EvdevMultitouchSwapAxes(pEvdevMultitouch);
3268         }
3269 #ifdef _F_IGNORE_TSP_RESOLUTION_
3270         else
3271         {
3272                 pEvdevMultitouch->absinfo[ABS_X].maximum = 0;
3273                 pEvdevMultitouch->absinfo[ABS_X].minimum = 0;
3274                 pEvdevMultitouch->absinfo[ABS_Y].maximum = 0;
3275                 pEvdevMultitouch->absinfo[ABS_Y].minimum = 0;
3276         }
3277 #endif//_F_IGNORE_TSP_RESOLUTION_
3278
3279         // register only the core device
3280         EvdevMultitouchAddDevice(pInfo);
3281     }
3282
3283     if (pEvdevMultitouch->flags & EVDEVMULTITOUCH_BUTTON_EVENTS)
3284     {
3285         EvdevMultitouchMBEmuPreInit(pInfo);
3286         EvdevMultitouchWheelEmuPreInit(pInfo);
3287         EvdevMultitouchDragLockPreInit(pInfo);
3288     }
3289
3290     return pInfo;
3291 }
3292
3293 _X_EXPORT InputDriverRec EVDEVMULTITOUCHh = {
3294     1,
3295     "evdevmultitouch",
3296     NULL,
3297     EvdevMultitouchPreInit,
3298     NULL,
3299     NULL,
3300     0
3301 };
3302
3303 static void
3304 EvdevMultitouchUnplug(pointer   p)
3305 {
3306 }
3307
3308 static pointer
3309 EvdevMultitouchPlug(pointer     module,
3310           pointer       options,
3311           int           *errmaj,
3312           int           *errmin)
3313 {
3314     xf86AddInputDriver(&EVDEVMULTITOUCHh, module, 0);
3315     return module;
3316 }
3317
3318 static XF86ModuleVersionInfo EvdevMultitouchVersionRec =
3319 {
3320     "evdevmultitouch",
3321     MODULEVENDORSTRING,
3322     MODINFOSTRING1,
3323     MODINFOSTRING2,
3324     XORG_VERSION_CURRENT,
3325     PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
3326     ABI_CLASS_XINPUT,
3327     ABI_XINPUT_VERSION,
3328     MOD_CLASS_XINPUT,
3329     {0, 0, 0, 0}
3330 };
3331
3332 _X_EXPORT XF86ModuleData evdevmultitouchModuleData =
3333 {
3334     &EvdevMultitouchVersionRec,
3335     EvdevMultitouchPlug,
3336     EvdevMultitouchUnplug
3337 };
3338
3339
3340 /* Return an index value for a given button event code
3341  * returns 0 on non-button event.
3342  */
3343 unsigned int
3344 EvdevMultitouchUtilButtonEventToButtonNumber(EvdevMultitouchPtr pEvdevMultitouch, int code)
3345 {
3346     unsigned int button = 0;
3347
3348     switch(code) {
3349     case BTN_LEFT:
3350         button = 1;
3351         break;
3352
3353     case BTN_RIGHT:
3354         button = 3;
3355         break;
3356
3357     case BTN_MIDDLE:
3358         button = 2;
3359         break;
3360
3361         /* Treat BTN_[0-2] as LMR buttons on devices that do not advertise
3362            BTN_LEFT, BTN_MIDDLE, BTN_RIGHT.
3363            Otherwise, treat BTN_[0+n] as button 5+n.
3364            XXX: This causes duplicate mappings for BTN_0 + n and BTN_SIDE + n
3365          */
3366     case BTN_0:
3367         button = (TestBit(BTN_LEFT, pEvdevMultitouch->key_bitmask)) ?  8 : 1;
3368         break;
3369     case BTN_1:
3370         button = (TestBit(BTN_MIDDLE, pEvdevMultitouch->key_bitmask)) ?  9 : 2;
3371         break;
3372     case BTN_2:
3373         button = (TestBit(BTN_RIGHT, pEvdevMultitouch->key_bitmask)) ?  10 : 3;
3374         break;
3375
3376         /* FIXME: BTN_3.. and BTN_SIDE.. have the same button mapping */
3377     case BTN_3:
3378     case BTN_4:
3379     case BTN_5:
3380     case BTN_6:
3381     case BTN_7:
3382     case BTN_8:
3383     case BTN_9:
3384         button = (code - BTN_0 + 5);
3385         break;
3386
3387     case BTN_SIDE:
3388     case BTN_EXTRA:
3389     case BTN_FORWARD:
3390     case BTN_BACK:
3391     case BTN_TASK:
3392         button = (code - BTN_LEFT + 5);
3393         break;
3394
3395     default:
3396         if ((code > BTN_TASK) && (code < KEY_OK)) {
3397             if (code < BTN_JOYSTICK) {
3398                 if (code < BTN_MOUSE)
3399                     button = (code - BTN_0 + 5);
3400                 else
3401                     button = (code - BTN_LEFT + 5);
3402             }
3403         }
3404     }
3405
3406     if (button > EVDEVMULTITOUCH_MAXBUTTONS)
3407         return 0;
3408
3409     return button;
3410 }
3411
3412 #ifdef HAVE_PROPERTIES
3413 #ifdef HAVE_LABELS
3414 /* Aligned with linux/input.h.
3415    Note that there are holes in the ABS_ range, these are simply replaced with
3416    MISC here */
3417 static char* abs_labels[] = {
3418     AXIS_LABEL_PROP_ABS_X,              /* 0x00 */
3419     AXIS_LABEL_PROP_ABS_Y,              /* 0x01 */
3420     AXIS_LABEL_PROP_ABS_Z,              /* 0x02 */
3421     AXIS_LABEL_PROP_ABS_RX,             /* 0x03 */
3422     AXIS_LABEL_PROP_ABS_RY,             /* 0x04 */
3423     AXIS_LABEL_PROP_ABS_RZ,             /* 0x05 */
3424     AXIS_LABEL_PROP_ABS_THROTTLE,       /* 0x06 */
3425     AXIS_LABEL_PROP_ABS_RUDDER,         /* 0x07 */
3426     AXIS_LABEL_PROP_ABS_WHEEL,          /* 0x08 */
3427     AXIS_LABEL_PROP_ABS_GAS,            /* 0x09 */
3428     AXIS_LABEL_PROP_ABS_BRAKE,          /* 0x0a */
3429     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
3430     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
3431     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
3432     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
3433     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
3434     AXIS_LABEL_PROP_ABS_HAT0X,          /* 0x10 */
3435     AXIS_LABEL_PROP_ABS_HAT0Y,          /* 0x11 */
3436     AXIS_LABEL_PROP_ABS_HAT1X,          /* 0x12 */
3437     AXIS_LABEL_PROP_ABS_HAT1Y,          /* 0x13 */
3438     AXIS_LABEL_PROP_ABS_HAT2X,          /* 0x14 */
3439     AXIS_LABEL_PROP_ABS_HAT2Y,          /* 0x15 */
3440     AXIS_LABEL_PROP_ABS_HAT3X,          /* 0x16 */
3441     AXIS_LABEL_PROP_ABS_HAT3Y,          /* 0x17 */
3442     AXIS_LABEL_PROP_ABS_PRESSURE,       /* 0x18 */
3443     AXIS_LABEL_PROP_ABS_DISTANCE,       /* 0x19 */
3444     AXIS_LABEL_PROP_ABS_TILT_X,         /* 0x1a */
3445     AXIS_LABEL_PROP_ABS_TILT_Y,         /* 0x1b */
3446     AXIS_LABEL_PROP_ABS_TOOL_WIDTH,     /* 0x1c */
3447     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
3448     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
3449     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
3450     AXIS_LABEL_PROP_ABS_VOLUME          /* 0x20 */
3451 };
3452
3453 static char* rel_labels[] = {
3454     AXIS_LABEL_PROP_REL_X,
3455     AXIS_LABEL_PROP_REL_Y,
3456     AXIS_LABEL_PROP_REL_Z,
3457     AXIS_LABEL_PROP_REL_RX,
3458     AXIS_LABEL_PROP_REL_RY,
3459     AXIS_LABEL_PROP_REL_RZ,
3460     AXIS_LABEL_PROP_REL_HWHEEL,
3461     AXIS_LABEL_PROP_REL_DIAL,
3462     AXIS_LABEL_PROP_REL_WHEEL,
3463     AXIS_LABEL_PROP_REL_MISC
3464 };
3465
3466 static char* btn_labels[][16] = {
3467     { /* BTN_MISC group                 offset 0x100*/
3468         BTN_LABEL_PROP_BTN_0,           /* 0x00 */
3469         BTN_LABEL_PROP_BTN_1,           /* 0x01 */
3470         BTN_LABEL_PROP_BTN_2,           /* 0x02 */
3471         BTN_LABEL_PROP_BTN_3,           /* 0x03 */
3472         BTN_LABEL_PROP_BTN_4,           /* 0x04 */
3473         BTN_LABEL_PROP_BTN_5,           /* 0x05 */
3474         BTN_LABEL_PROP_BTN_6,           /* 0x06 */
3475         BTN_LABEL_PROP_BTN_7,           /* 0x07 */
3476         BTN_LABEL_PROP_BTN_8,           /* 0x08 */
3477         BTN_LABEL_PROP_BTN_9            /* 0x09 */
3478     },
3479     { /* BTN_MOUSE group                offset 0x110 */
3480         BTN_LABEL_PROP_BTN_LEFT,        /* 0x00 */
3481         BTN_LABEL_PROP_BTN_RIGHT,       /* 0x01 */
3482         BTN_LABEL_PROP_BTN_MIDDLE,      /* 0x02 */
3483         BTN_LABEL_PROP_BTN_SIDE,        /* 0x03 */
3484         BTN_LABEL_PROP_BTN_EXTRA,       /* 0x04 */
3485         BTN_LABEL_PROP_BTN_FORWARD,     /* 0x05 */
3486         BTN_LABEL_PROP_BTN_BACK,        /* 0x06 */
3487         BTN_LABEL_PROP_BTN_TASK         /* 0x07 */
3488     },
3489     { /* BTN_JOYSTICK group             offset 0x120 */
3490         BTN_LABEL_PROP_BTN_TRIGGER,     /* 0x00 */
3491         BTN_LABEL_PROP_BTN_THUMB,       /* 0x01 */
3492         BTN_LABEL_PROP_BTN_THUMB2,      /* 0x02 */
3493         BTN_LABEL_PROP_BTN_TOP,         /* 0x03 */
3494         BTN_LABEL_PROP_BTN_TOP2,        /* 0x04 */
3495         BTN_LABEL_PROP_BTN_PINKIE,      /* 0x05 */
3496         BTN_LABEL_PROP_BTN_BASE,        /* 0x06 */
3497         BTN_LABEL_PROP_BTN_BASE2,       /* 0x07 */
3498         BTN_LABEL_PROP_BTN_BASE3,       /* 0x08 */
3499         BTN_LABEL_PROP_BTN_BASE4,       /* 0x09 */
3500         BTN_LABEL_PROP_BTN_BASE5,       /* 0x0a */
3501         BTN_LABEL_PROP_BTN_BASE6,       /* 0x0b */
3502         NULL,
3503         NULL,
3504         NULL,
3505         BTN_LABEL_PROP_BTN_DEAD         /* 0x0f */
3506     },
3507     { /* BTN_GAMEPAD group              offset 0x130 */
3508         BTN_LABEL_PROP_BTN_A,           /* 0x00 */
3509         BTN_LABEL_PROP_BTN_B,           /* 0x01 */
3510         BTN_LABEL_PROP_BTN_C,           /* 0x02 */
3511         BTN_LABEL_PROP_BTN_X,           /* 0x03 */
3512         BTN_LABEL_PROP_BTN_Y,           /* 0x04 */
3513         BTN_LABEL_PROP_BTN_Z,           /* 0x05 */
3514         BTN_LABEL_PROP_BTN_TL,          /* 0x06 */
3515         BTN_LABEL_PROP_BTN_TR,          /* 0x07 */
3516         BTN_LABEL_PROP_BTN_TL2,         /* 0x08 */
3517         BTN_LABEL_PROP_BTN_TR2,         /* 0x09 */
3518         BTN_LABEL_PROP_BTN_SELECT,      /* 0x0a */
3519         BTN_LABEL_PROP_BTN_START,       /* 0x0b */
3520         BTN_LABEL_PROP_BTN_MODE,        /* 0x0c */
3521         BTN_LABEL_PROP_BTN_THUMBL,      /* 0x0d */
3522         BTN_LABEL_PROP_BTN_THUMBR       /* 0x0e */
3523     },
3524     { /* BTN_DIGI group                         offset 0x140 */
3525         BTN_LABEL_PROP_BTN_TOOL_PEN,            /* 0x00 */
3526         BTN_LABEL_PROP_BTN_TOOL_RUBBER,         /* 0x01 */
3527         BTN_LABEL_PROP_BTN_TOOL_BRUSH,          /* 0x02 */
3528         BTN_LABEL_PROP_BTN_TOOL_PENCIL,         /* 0x03 */
3529         BTN_LABEL_PROP_BTN_TOOL_AIRBRUSH,       /* 0x04 */
3530         BTN_LABEL_PROP_BTN_TOOL_FINGER,         /* 0x05 */
3531         BTN_LABEL_PROP_BTN_TOOL_MOUSE,          /* 0x06 */
3532         BTN_LABEL_PROP_BTN_TOOL_LENS,           /* 0x07 */
3533         NULL,
3534         NULL,
3535         BTN_LABEL_PROP_BTN_TOUCH,               /* 0x0a */
3536         BTN_LABEL_PROP_BTN_STYLUS,              /* 0x0b */
3537         BTN_LABEL_PROP_BTN_STYLUS2,             /* 0x0c */
3538         BTN_LABEL_PROP_BTN_TOOL_DOUBLETAP,      /* 0x0d */
3539         BTN_LABEL_PROP_BTN_TOOL_TRIPLETAP       /* 0x0e */
3540     },
3541     { /* BTN_WHEEL group                        offset 0x150 */
3542         BTN_LABEL_PROP_BTN_GEAR_DOWN,           /* 0x00 */
3543         BTN_LABEL_PROP_BTN_GEAR_UP              /* 0x01 */
3544     }
3545 };
3546
3547 #endif /* HAVE_LABELS */
3548
3549 static void EvdevMultitouchInitAxesLabels(EvdevMultitouchPtr pEvdevMultitouch, int natoms, Atom *atoms)
3550 {
3551 #ifdef HAVE_LABELS
3552     Atom atom;
3553     int axis;
3554     char **labels;
3555     int labels_len = 0;
3556     char *misc_label;
3557
3558     if (pEvdevMultitouch->flags & EVDEVMULTITOUCH_ABSOLUTE_EVENTS)
3559     {
3560         labels     = abs_labels;
3561         labels_len = ArrayLength(abs_labels);
3562         misc_label = AXIS_LABEL_PROP_ABS_MISC;
3563     } else if ((pEvdevMultitouch->flags & EVDEVMULTITOUCH_RELATIVE_EVENTS))
3564     {
3565         labels     = rel_labels;
3566         labels_len = ArrayLength(rel_labels);
3567         misc_label = AXIS_LABEL_PROP_REL_MISC;
3568     }
3569
3570     memset(atoms, 0, natoms * sizeof(Atom));
3571
3572     /* Now fill the ones we know */
3573     for (axis = 0; axis < labels_len; axis++)
3574     {
3575         if (pEvdevMultitouch->axis_map[axis] == -1)
3576             continue;
3577
3578         atom = XIGetKnownProperty(labels[axis]);
3579         if (!atom) /* Should not happen */
3580             continue;
3581
3582         atoms[pEvdevMultitouch->axis_map[axis]] = atom;
3583     }
3584 #endif
3585 }
3586
3587 static void EvdevMultitouchInitButtonLabels(EvdevMultitouchPtr pEvdevMultitouch, int natoms, Atom *atoms)
3588 {
3589 #ifdef HAVE_LABELS
3590     Atom atom;
3591     int button, bmap;
3592
3593     /* First, make sure all atoms are initialized */
3594     atom = XIGetKnownProperty(BTN_LABEL_PROP_BTN_UNKNOWN);
3595     for (button = 0; button < natoms; button++)
3596         atoms[button] = atom;
3597
3598     for (button = BTN_MISC; button < BTN_JOYSTICK; button++)
3599     {
3600         if (TestBit(button, pEvdevMultitouch->key_bitmask))
3601         {
3602             int group = (button % 0x100)/16;
3603             int idx = button - ((button/16) * 16);
3604
3605             if (!btn_labels[group][idx])
3606                 continue;
3607
3608             atom = XIGetKnownProperty(btn_labels[group][idx]);
3609             if (!atom)
3610                 continue;
3611
3612             /* Props are 0-indexed, button numbers start with 1 */
3613             bmap = EvdevMultitouchUtilButtonEventToButtonNumber(pEvdevMultitouch, button) - 1;
3614              if( bmap >= 0 )
3615                 atoms[bmap] = atom;
3616         }
3617     }
3618
3619     /* wheel buttons, hardcoded anyway */
3620     if (natoms > 3)
3621         atoms[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
3622     if (natoms > 4)
3623         atoms[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
3624     if (natoms > 5)
3625         atoms[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
3626     if (natoms > 6)
3627         atoms[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
3628 #endif
3629 }
3630
3631 static void
3632 EvdevMultitouchInitProperty(DeviceIntPtr dev)
3633 {
3634     InputInfoPtr pInfo  = dev->public.devicePrivate;
3635     EvdevMultitouchPtr     pEvdevMultitouch = pInfo->private;
3636     int          rc;
3637     int          val;
3638     BOOL         invert[2];
3639     char         reopen;
3640
3641     prop_reopen = MakeAtom(EVDEVMULTITOUCH_PROP_REOPEN, strlen(EVDEVMULTITOUCH_PROP_REOPEN),
3642             TRUE);
3643
3644     reopen = pEvdevMultitouch->reopen_attempts;
3645     rc = XIChangeDeviceProperty(dev, prop_reopen, XA_INTEGER, 8,
3646                                 PropModeReplace, 1, &reopen, FALSE);
3647     if (rc != Success)
3648         return;
3649
3650     XISetDevicePropertyDeletable(dev, prop_reopen, FALSE);
3651
3652     if (pEvdevMultitouch->flags & (EVDEVMULTITOUCH_RELATIVE_EVENTS | EVDEVMULTITOUCH_ABSOLUTE_EVENTS))
3653     {
3654         invert[0] = pEvdevMultitouch->invert_x;
3655         invert[1] = pEvdevMultitouch->invert_y;
3656
3657         prop_invert = MakeAtom(EVDEVMULTITOUCH_PROP_INVERT_AXES, strlen(EVDEVMULTITOUCH_PROP_INVERT_AXES), TRUE);
3658
3659         rc = XIChangeDeviceProperty(dev, prop_invert, XA_INTEGER, 8,
3660                 PropModeReplace, 2,
3661                 invert, FALSE);
3662         if (rc != Success)
3663             return;
3664
3665         XISetDevicePropertyDeletable(dev, prop_invert, FALSE);
3666
3667         prop_calibration = MakeAtom(EVDEVMULTITOUCH_PROP_CALIBRATION,
3668                 strlen(EVDEVMULTITOUCH_PROP_CALIBRATION), TRUE);
3669         rc = XIChangeDeviceProperty(dev, prop_calibration, XA_INTEGER, 32,
3670                 PropModeReplace, 0, NULL, FALSE);
3671         if (rc != Success)
3672             return;
3673
3674         XISetDevicePropertyDeletable(dev, prop_calibration, FALSE);
3675
3676         prop_swap = MakeAtom(EVDEVMULTITOUCH_PROP_SWAP_AXES,
3677                 strlen(EVDEVMULTITOUCH_PROP_SWAP_AXES), TRUE);
3678
3679         rc = XIChangeDeviceProperty(dev, prop_swap, XA_INTEGER, 8,
3680                 PropModeReplace, 1, &pEvdevMultitouch->swap_axes, FALSE);
3681         if (rc != Success)
3682             return;
3683
3684         XISetDevicePropertyDeletable(dev, prop_swap, FALSE);
3685         
3686         if (pEvdevMultitouch->flags & EVDEVMULTITOUCH_MULTITOUCH)
3687         {
3688             /* tracking ids for mt */
3689             prop_tracking_id = MakeAtom(EVDEVMULTITOUCH_PROP_TRACKING_ID,
3690                     strlen(EVDEVMULTITOUCH_PROP_TRACKING_ID), TRUE);
3691             rc = XIChangeDeviceProperty(dev, prop_tracking_id, XA_INTEGER, 32,
3692                     PropModeReplace, 1, &pEvdevMultitouch->id, FALSE);
3693             if (rc != Success)
3694                 return;
3695
3696             XISetDevicePropertyDeletable(dev, prop_tracking_id, FALSE);
3697
3698             /* flag to emulate or not a touchscreen for mt */
3699             prop_multitouch = MakeAtom(EVDEVMULTITOUCH_PROP_MULTITOUCH_SUBDEVICES,
3700                     strlen(EVDEVMULTITOUCH_PROP_MULTITOUCH_SUBDEVICES), TRUE);
3701             rc = XIChangeDeviceProperty(dev, prop_multitouch, XA_INTEGER, 8,
3702                     PropModeReplace, 1, &pEvdevMultitouch->num_multitouch, FALSE);
3703             if (rc != Success)
3704                 return;
3705
3706             XISetDevicePropertyDeletable(dev, prop_multitouch, FALSE);
3707         }
3708
3709         //property for checking pointer grab status
3710         val = 0;
3711         prop_grabinfo = MakeAtom(EVDEVMULTITOUCH_PROP_GRABINFO, strlen(EVDEVMULTITOUCH_PROP_GRABINFO),  TRUE);
3712         rc = XIChangeDeviceProperty(dev, prop_grabinfo, XA_INTEGER, 8, PropModeReplace, 1, &val, FALSE);
3713
3714         if (rc != Success)
3715             return;
3716
3717         XISetDevicePropertyDeletable(dev, prop_grabinfo, FALSE);
3718
3719         if( EvdevMultitouchIsCoreDevice(pInfo) )//master only
3720         {
3721                 /* flag to use poll */
3722                 prop_use_poll = MakeAtom(EVDEVMULTITOUCH_PROP_USE_POLL, strlen(EVDEVMULTITOUCH_PROP_USE_POLL), TRUE);
3723                 rc = XIChangeDeviceProperty(dev, prop_use_poll, XA_INTEGER, 8, PropModeReplace, 1, &pEvdevMultitouch->use_poll, FALSE);
3724                 if (rc != Success)
3725                         return;
3726
3727                 XISetDevicePropertyDeletable(dev, prop_use_poll, FALSE);
3728
3729                 /* matrix to transform */
3730                 prop_transform = MakeAtom(EVDEVMULTITOUCH_PROP_TRANSFORM, strlen(EVDEVMULTITOUCH_PROP_TRANSFORM),  TRUE);
3731                 rc = XIChangeDeviceProperty(dev, prop_transform, XIGetKnownProperty(XATOM_FLOAT), 32, PropModeReplace, 9, transform, FALSE);
3732
3733                 if (rc != Success)
3734                     return;
3735
3736                 XISetDevicePropertyDeletable(dev, prop_transform, FALSE);
3737         }
3738
3739 #ifdef HAVE_LABELS
3740         /* Axis labelling */
3741         if ((pEvdevMultitouch->num_vals > 0) && (prop_axis_label = XIGetKnownProperty(AXIS_LABEL_PROP)))
3742         {
3743             Atom atoms[pEvdevMultitouch->num_vals];
3744             EvdevMultitouchInitAxesLabels(pEvdevMultitouch, pEvdevMultitouch->num_vals, atoms);
3745             XIChangeDeviceProperty(dev, prop_axis_label, XA_ATOM, 32,
3746                                    PropModeReplace, pEvdevMultitouch->num_vals, atoms, FALSE);
3747             XISetDevicePropertyDeletable(dev, prop_axis_label, FALSE);
3748         }
3749         /* Button labelling */
3750         if ((pEvdevMultitouch->num_buttons > 0) && (prop_btn_label = XIGetKnownProperty(BTN_LABEL_PROP)))
3751         {
3752             Atom atoms[EVDEVMULTITOUCH_MAXBUTTONS];
3753             EvdevMultitouchInitButtonLabels(pEvdevMultitouch, EVDEVMULTITOUCH_MAXBUTTONS, atoms);
3754             XIChangeDeviceProperty(dev, prop_btn_label, XA_ATOM, 32,
3755                                    PropModeReplace, pEvdevMultitouch->num_buttons, atoms, FALSE);
3756             XISetDevicePropertyDeletable(dev, prop_btn_label, FALSE);
3757         }
3758 #endif /* HAVE_LABELS */
3759     }
3760
3761 }
3762
3763 static void EvdevMultitouchSwapAxes(EvdevMultitouchPtr pEvdevMultitouch)
3764 {
3765     if(pEvdevMultitouch->swap_axes)
3766     {
3767         pEvdevMultitouch->absinfo[ABS_Y].maximum = pEvdevMultitouch->resolution.max_x;
3768         pEvdevMultitouch->absinfo[ABS_Y].minimum = pEvdevMultitouch->resolution.min_x;
3769         pEvdevMultitouch->absinfo[ABS_X].maximum = pEvdevMultitouch->resolution.max_y;
3770         pEvdevMultitouch->absinfo[ABS_X].minimum = pEvdevMultitouch->resolution.min_y;
3771     }
3772     else
3773     {
3774         pEvdevMultitouch->absinfo[ABS_X].maximum = pEvdevMultitouch->resolution.max_x;
3775         pEvdevMultitouch->absinfo[ABS_X].minimum = pEvdevMultitouch->resolution.min_x;
3776         pEvdevMultitouch->absinfo[ABS_Y].maximum = pEvdevMultitouch->resolution.max_y;
3777         pEvdevMultitouch->absinfo[ABS_Y].minimum = pEvdevMultitouch->resolution.min_y;
3778     }
3779 }
3780
3781 static int
3782 EvdevMultitouchSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
3783                  BOOL checkonly)
3784 {
3785     InputInfoPtr pInfo  = dev->public.devicePrivate;
3786     EvdevMultitouchPtr     pEvdevMultitouch = pInfo->private;
3787
3788     if (atom == prop_invert)
3789     {
3790         BOOL* data;
3791         if (val->format != 8 || val->size != 2 || val->type != XA_INTEGER)
3792             return BadMatch;
3793
3794         if (!checkonly)
3795         {
3796             data = (BOOL*)val->data;
3797             pEvdevMultitouch->invert_x = data[0];
3798             pEvdevMultitouch->invert_y = data[1];
3799         }
3800     } else if (atom == prop_reopen)
3801     {
3802         if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER)
3803             return BadMatch;
3804
3805         if (!checkonly)
3806             pEvdevMultitouch->reopen_attempts = *((CARD8*)val->data);
3807     } else if (atom == prop_calibration)
3808     {
3809         if (val->format != 32 || val->type != XA_INTEGER)
3810             return BadMatch;
3811         if (val->size != 4 && val->size != 0)
3812             return BadMatch;
3813
3814         if (!checkonly)
3815             EvdevMultitouchSetCalibration(pInfo, val->size, val->data);
3816     } else if (atom == prop_swap)
3817     {
3818         if (val->format != 8 || val->type != XA_INTEGER || val->size != 1)
3819             return BadMatch;
3820
3821         if (!checkonly)
3822             pEvdevMultitouch->swap_axes = *((BOOL*)val->data);
3823          EvdevMultitouchSwapAxes(pEvdevMultitouch);
3824     } else if (atom == prop_axis_label || atom == prop_btn_label)
3825         return BadAccess; /* Axis/Button labels can't be changed */
3826     else if (atom == prop_tracking_id)
3827     {
3828         if (val->format != 32 || val->type != XA_INTEGER || val->size != 1)
3829             return BadMatch;
3830
3831         if (!checkonly)
3832             pEvdevMultitouch->id = *((int*)val->data);
3833     } else if (atom == prop_multitouch)
3834     {
3835         BOOL data;
3836         if (val->format != 8 || val->type != XA_INTEGER || val->size != 1)
3837             return BadMatch;
3838         if (!checkonly) {
3839             data = *((BOOL*)val->data);
3840             if (pEvdevMultitouch->num_multitouch != data)
3841                 EvdevMultitouchSetMultitouch(pInfo,data);
3842         }
3843     } else if (atom == prop_use_poll)
3844     {
3845         BOOL data;
3846         if (val->format != 8 || val->type != XA_INTEGER || val->size != 1)
3847             return BadMatch;
3848         if (!checkonly) {
3849             data = *((BOOL*)val->data);
3850             if (pEvdevMultitouch->use_poll != data)
3851                   EvdevMultitouchSetUsePoll(pInfo,(BOOL)data);
3852         }
3853     }
3854     else if (atom == prop_transform)
3855     {
3856         float *f;
3857         if (val->format != 32 || val->type != XIGetKnownProperty(XATOM_FLOAT) || val->size != 9)
3858             return BadMatch;
3859         if (!checkonly) {
3860             f = (float*)val->data;
3861             EvdevMultitouchSetTransform(pInfo, val->size, f);
3862         }
3863     }
3864     else if (atom == prop_grabinfo)
3865     {
3866         BOOL data;
3867         if (val->format != 8 || val->type != XA_INTEGER || val->size != 1)
3868             return BadMatch;
3869         if (!checkonly) {
3870             data = *((BOOL*)val->data);
3871             EvdevMultitouchGetGrabInfo(pInfo, (BOOL)data);
3872         }
3873     }
3874
3875     return Success;
3876 }
3877 #endif
3878
3879 /* Duplicate xf86 options and convert them to InputOption */
3880 static InputOption *EvdevMultitouchOptionDupConvert(pointer original)
3881 {
3882     InputOption *iopts = NULL, *new;
3883     InputInfoRec dummy;
3884
3885
3886     memset(&dummy, 0, sizeof(dummy));
3887     xf86CollectInputOptions(&dummy, NULL, original);
3888
3889     while(dummy.options)
3890     {
3891         new = calloc(1, sizeof(InputOption));
3892
3893         new->key = xf86OptionName(dummy.options);
3894         new->value = xf86OptionValue(dummy.options);
3895
3896         new->next = iopts;
3897         iopts = new;
3898         dummy.options = xf86NextOption(dummy.options);
3899     }
3900     return iopts;
3901 }
3902 static void EvdevMultitouchFreeInputOpts(InputOption* opts)
3903 {
3904     InputOption *tmp = opts;
3905
3906     while(opts)
3907     {
3908         tmp = opts->next;
3909         free(opts->key);
3910         free(opts->value);
3911         free(opts);
3912         opts = tmp;
3913     }
3914 }
3915 static void EvdevMultitouchReplaceOption(InputOption *opts,const char* key, char * value)
3916 {
3917
3918     while(opts)
3919     {
3920         if (xf86NameCmp(opts->key, key) == 0)
3921         {
3922
3923             free(opts->value);
3924             opts->value = strdup(value);
3925         }
3926         opts = opts->next;
3927     }
3928 }
3929
3930 /**
3931  * New device creation through xorg/input
3932  *
3933  * @return 0 if successful, 1 if failure
3934  */
3935 static InputInfoPtr
3936 EvdevMultitouchCreateSubDevice(InputInfoPtr pInfo, int id) {
3937     InputInfoPtr pSubdev;
3938
3939     DeviceIntPtr dev; /* dummy */
3940     InputOption *input_options = NULL;
3941     char* name;
3942     
3943
3944     pInfo->options = xf86AddNewOption(pInfo->options, "Type", "core");
3945     pInfo->options = xf86AddNewOption(pInfo->options, "SendCoreEvents", "off");
3946
3947     /* Create new device */
3948
3949     input_options = EvdevMultitouchOptionDupConvert(pInfo->options);
3950
3951     EvdevMultitouchReplaceOption(input_options, "type","Object");
3952
3953     //EvdevMultitouchReplaceOption(input_options, "SendCoreEvents","off"); //FIXME: bug in xserver
3954     name = malloc( (strlen(pInfo->name) + strlen(" subdev ") + 20 )*sizeof(char)); // 20 for adding the id
3955
3956     if( !name )
3957     {
3958         ErrorF("[X11][%s] Failed to allocate memory !\n", __FUNCTION__);
3959          return NULL;
3960     }
3961
3962     sprintf(name, "%s subdev %i", pInfo->name, id);
3963     EvdevMultitouchReplaceOption(input_options, "name",name);
3964
3965     pCreatorInfo = pInfo;
3966     NewInputDeviceRequest(input_options, NULL, &dev);//for xserver 1.8.0
3967     //NewInputDeviceRequest(input_options, &dev);//for xserver 1.7.1
3968     pSubdev = dev->public.devicePrivate;
3969     pCreatorInfo = NULL;
3970
3971     EvdevMultitouchFreeInputOpts(input_options);
3972
3973     free(name);
3974     return pSubdev;
3975 }
3976 static void
3977 EvdevMultitouchDeleteSubDevice(InputInfoPtr pInfo, InputInfoPtr subdev) {
3978     /* We need to explicitely flush the events so as not deleting
3979      * a device that still has events in queue
3980      */
3981     xf86Msg(X_INFO, "%s: Removing subdevice %s\n", pInfo->name,subdev->name);
3982     DeleteInputDeviceRequest(subdev->dev);
3983 }