chiark / gitweb /
xf86-input-mtrack (0.3.1-1) unstable; urgency=medium
[xf86-input-mtrack.git] / src / hwstate.c
1 /***************************************************************************
2  *
3  * Multitouch X driver
4  * Copyright (C) 2008 Henrik Rydberg <rydberg@euromail.se>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  **************************************************************************/
21
22 #include "hwstate.h"
23
24 void hwstate_init(struct HWState *s, const struct Capabilities *caps)
25 {
26         int i;
27         memset(s, 0, sizeof(struct HWState));
28         for (i = 0; i < DIM_FINGER; i++)
29                 s->data[i].tracking_id = MT_ID_NULL;
30         s->max_x = get_cap_xsize(caps);
31         s->max_y = get_cap_ysize(caps);
32 }
33
34 static void finish_packet(struct HWState *s, const struct Capabilities *caps,
35                           const struct input_event *syn)
36 {
37         static const mstime_t ms = 1000;
38         int i;
39         foreach_bit(i, s->used) {
40                 if (!caps->has_abs[MTDEV_TOUCH_MINOR])
41                         s->data[i].touch_minor = s->data[i].touch_major;
42                 if (!caps->has_abs[MTDEV_WIDTH_MINOR])
43                         s->data[i].width_minor = s->data[i].width_major;
44         }
45         timercp(&s->evtime, &syn->time);
46 }
47
48 static int read_event(struct HWState *s, const struct Capabilities *caps,
49                       const struct input_event *ev)
50 {
51         switch (ev->type) {
52         case EV_SYN:
53                 switch (ev->code) {
54                 case SYN_REPORT:
55                         finish_packet(s, caps, ev);
56                         return 1;
57                 }
58                 break;
59         case EV_KEY:
60                 switch (ev->code) {
61                 case BTN_LEFT:
62                         MODBIT(s->button, MT_BUTTON_LEFT, ev->value);
63                         break;
64                 case BTN_MIDDLE:
65                         MODBIT(s->button, MT_BUTTON_MIDDLE, ev->value);
66                         break;
67                 case BTN_RIGHT:
68                         MODBIT(s->button, MT_BUTTON_RIGHT, ev->value);
69                         break;
70                 }
71                 break;
72         case EV_ABS:
73                 switch (ev->code) {
74                 case ABS_MT_SLOT:
75                         if (ev->value >= 0 && ev->value < DIM_FINGER)
76                                 s->slot = ev->value;
77                         break;
78                 case ABS_MT_TOUCH_MAJOR:
79                         s->data[s->slot].touch_major = ev->value;
80                         break;
81                 case ABS_MT_TOUCH_MINOR:
82                         s->data[s->slot].touch_minor = ev->value;
83                         break;
84                 case ABS_MT_WIDTH_MAJOR:
85                         s->data[s->slot].width_major = ev->value;
86                         break;
87                 case ABS_MT_WIDTH_MINOR:
88                         s->data[s->slot].width_minor = ev->value;
89                         break;
90                 case ABS_MT_ORIENTATION:
91                         s->data[s->slot].orientation = ev->value;
92                         break;
93                 case ABS_MT_PRESSURE:
94                         s->data[s->slot].pressure = ev->value;
95                         break;
96                 case ABS_MT_POSITION_X:
97                         s->data[s->slot].position_x = ev->value;
98                         break;
99                 case ABS_MT_POSITION_Y:
100                         s->data[s->slot].position_y = ev->value;
101                         break;
102                 case ABS_MT_TRACKING_ID:
103                         s->data[s->slot].tracking_id = ev->value;
104                         MODBIT(s->used, s->slot, ev->value != MT_ID_NULL);
105                         break;
106                 }
107                 break;
108         }
109         return 0;
110 }
111
112 int hwstate_modify(struct HWState *s, struct mtdev *dev, int fd,
113                    const struct Capabilities *caps)
114 {
115         struct input_event ev;
116         int ret;
117         while ((ret = mtdev_get(dev, fd, &ev, 1)) > 0) {
118                 if (read_event(s, caps, &ev))
119                         return 1;
120         }
121         return ret;
122 }
123
124 int find_finger(const struct HWState *s, int tracking_id) {
125         int i;
126         foreach_bit(i, s->used) {
127                 if (s->data[i].tracking_id == tracking_id)
128                         return i;
129         }
130         return -1;
131 }