summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--driver/multitouch.c10
-rw-r--r--include/gestures.h1
-rw-r--r--include/hwdata.h75
-rw-r--r--include/hwstate.h33
-rw-r--r--include/mtdev-caps.h1
-rw-r--r--include/mtouch.h11
-rw-r--r--include/mtstate.h16
-rw-r--r--mtdev/hwdata.c133
-rw-r--r--src/gestures.c26
-rw-r--r--src/hwstate.c156
-rw-r--r--src/memory.c33
-rw-r--r--src/mtouch.c20
-rw-r--r--src/mtstate.c45
-rw-r--r--src/test.c45
15 files changed, 221 insertions, 386 deletions
diff --git a/Makefile b/Makefile
index 546d1fb..9dccba5 100644
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,7 @@ XMODULES = driver
9 9
10o_match = match 10o_match = match
11 11
12o_mtdev = iobuf caps core hwdata 12o_mtdev = iobuf caps core
13 13
14o_src = hwstate mtstate memory mtouch gestures 14o_src = hwstate mtstate memory mtouch gestures
15 15
diff --git a/driver/multitouch.c b/driver/multitouch.c
index ee5242f..7233aa2 100644
--- a/driver/multitouch.c
+++ b/driver/multitouch.c
@@ -273,10 +273,12 @@ static void read_input(LocalDevicePtr local)
273{ 273{
274 struct Gestures gs; 274 struct Gestures gs;
275 struct MTouch *mt = local->private; 275 struct MTouch *mt = local->private;
276 while (read_synchronized_event(mt, local->fd)) { 276 const struct input_event *ev;
277 parse_event(mt); 277 while (ev = get_iobuf_event(&mt->buf, local->fd)) {
278 extract_gestures(&gs, mt); 278 if (parse_event(mt, ev)) {
279 handle_gestures(local, &gs, &mt->caps); 279 extract_gestures(&gs, mt);
280 handle_gestures(local, &gs, &mt->caps);
281 }
280 } 282 }
281} 283}
282 284
diff --git a/include/gestures.h b/include/gestures.h
index 2bd4a55..1d70a25 100644
--- a/include/gestures.h
+++ b/include/gestures.h
@@ -39,5 +39,6 @@ struct Gestures {
39}; 39};
40 40
41void extract_gestures(struct Gestures *gs, struct MTouch* mt); 41void extract_gestures(struct Gestures *gs, struct MTouch* mt);
42void output_gesture(const struct Gestures *gs);
42 43
43#endif 44#endif
diff --git a/include/hwdata.h b/include/hwdata.h
deleted file mode 100644
index 21864dc..0000000
--- a/include/hwdata.h
+++ /dev/null
@@ -1,75 +0,0 @@
1/***************************************************************************
2 *
3 * Multitouch X driver
4 * Copyright (C) 2008 Henrik Rydberg <rydberg@euromail.se>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 **************************************************************************/
21
22#ifndef HWDATA_H
23#define HWDATA_H
24
25#include "common.h"
26#include "button.h"
27
28#define BIT_MT_TOUCH_MAJOR 0
29#define BIT_MT_TOUCH_MINOR 1
30#define BIT_MT_WIDTH_MAJOR 2
31#define BIT_MT_WIDTH_MINOR 3
32#define BIT_MT_ORIENTATION 4
33#define BIT_MT_PRESSURE 5
34#define BIT_MT_POSITION_X 6
35#define BIT_MT_POSITION_Y 7
36#define BIT_MT_CNT 8
37
38struct FingerData {
39 int touch_major, touch_minor;
40 int width_major, width_minor;
41 int orientation, pressure;
42 int position_x, position_y;
43};
44
45/**
46 * struct HWData - hardware reads
47 *
48 * @finger: finger data
49 * @mask: bits corresponding to data actually read (readonly)
50 * @mread: bits corresponding to data in progress (writeonly)
51 * @button: bitmask of buttons
52 * @nfinger: number of fingers actually read (readonly)
53 * @nread: number of fingers in progress (writeonly)
54 *
55 */
56struct HWData {
57 struct FingerData finger[DIM_FINGER];
58 unsigned mask[DIM_FINGER], mread[DIM_FINGER];
59 unsigned button;
60 int nfinger, mtread, nread;
61 mstime_t evtime;
62};
63
64void init_hwdata(struct HWData *hw);
65int read_hwdata(struct HWData *hw, const struct input_event* ev);
66void output_hwdata(const struct HWData *hw);
67
68static inline int finger_dist2(const struct FingerData *a,
69 const struct FingerData *b)
70{
71 return dist2(a->position_x - b->position_x,
72 a->position_y - b->position_y);
73}
74
75#endif
diff --git a/include/hwstate.h b/include/hwstate.h
index 07d4ed6..4243292 100644
--- a/include/hwstate.h
+++ b/include/hwstate.h
@@ -22,26 +22,35 @@
22#ifndef HWSTATE_H 22#ifndef HWSTATE_H
23#define HWSTATE_H 23#define HWSTATE_H
24 24
25#include "mtdev-caps.h" 25#include "mtdev.h"
26#include "hwdata.h"
27 26
28/* zero id means not mapped (not touching) */
29struct FingerState { 27struct FingerState {
30 struct FingerData hw; 28 int touch_major, touch_minor;
31 int id; 29 int width_major, width_minor;
30 int orientation, pressure;
31 int position_x, position_y;
32 int tracking_id;
32}; 33};
33 34
34struct HWState { 35struct HWState {
35 struct FingerState finger[DIM_FINGER]; 36 struct FingerState data[DIM_FINGER];
37 bitmask_t used;
38 bitmask_t slot;
36 bitmask_t button; 39 bitmask_t button;
37 int nfinger;
38 mstime_t evtime; 40 mstime_t evtime;
39 int lastid;
40}; 41};
41 42
42void init_hwstate(struct HWState *s); 43void init_hwstate(struct HWState *s,
43void modify_hwstate(struct HWState *s, 44 const struct Capabilities *caps);
44 const struct HWData *hw, 45int modify_hwstate(struct HWState *s, struct MTDev *dev,
45 const struct Capabilities *caps); 46 const struct Capabilities *caps);
47void output_hwstate(const struct HWState *s);
48
49static inline int finger_dist2(const struct FingerState *a,
50 const struct FingerState *b)
51{
52 return dist2(a->position_x - b->position_x,
53 a->position_y - b->position_y);
54}
46 55
47#endif 56#endif
diff --git a/include/mtdev-caps.h b/include/mtdev-caps.h
index 4460eca..727cd11 100644
--- a/include/mtdev-caps.h
+++ b/include/mtdev-caps.h
@@ -23,6 +23,7 @@
23#define MTDEV_CAPS_H 23#define MTDEV_CAPS_H
24 24
25#include "common.h" 25#include "common.h"
26#include "button.h"
26#include "abs2mt.h" 27#include "abs2mt.h"
27#include "mtbit.h" 28#include "mtbit.h"
28 29
diff --git a/include/mtouch.h b/include/mtouch.h
index a495960..2b76652 100644
--- a/include/mtouch.h
+++ b/include/mtouch.h
@@ -22,16 +22,13 @@
22#ifndef MTOUCH_H 22#ifndef MTOUCH_H
23#define MTOUCH_H 23#define MTOUCH_H
24 24
25#include "mtdev-iobuf.h"
26#include "hwdata.h"
27#include "hwstate.h"
28#include "mtstate.h"
29#include "memory.h" 25#include "memory.h"
26#include "mtdev-iobuf.h"
30 27
31struct MTouch { 28struct MTouch {
32 struct Capabilities caps; 29 struct Capabilities caps;
30 struct MTDev dev;
33 struct IOBuffer buf; 31 struct IOBuffer buf;
34 struct HWData hw;
35 struct HWState hs; 32 struct HWState hs;
36 struct MTState prev_state, state; 33 struct MTState prev_state, state;
37 struct Memory mem; 34 struct Memory mem;
@@ -41,9 +38,7 @@ int configure_mtouch(struct MTouch *mt, int fd);
41int open_mtouch(struct MTouch *mt, int fd); 38int open_mtouch(struct MTouch *mt, int fd);
42int close_mtouch(struct MTouch *mt, int fd); 39int close_mtouch(struct MTouch *mt, int fd);
43 40
44int read_synchronized_event(struct MTouch *mt, int fd); 41int parse_event(struct MTouch *mt, const struct input_event *ev);
45void parse_event(struct MTouch *mt);
46
47 42
48static inline void mt_delay_movement(struct MTouch *mt, int t) 43static inline void mt_delay_movement(struct MTouch *mt, int t)
49{ 44{
diff --git a/include/mtstate.h b/include/mtstate.h
index b6b8e8d..a474114 100644
--- a/include/mtstate.h
+++ b/include/mtstate.h
@@ -24,14 +24,10 @@
24 24
25#include "hwstate.h" 25#include "hwstate.h"
26 26
27struct MTFinger {
28 struct FingerData hw;
29 int id, thumb;
30};
31
32struct MTState { 27struct MTState {
33 struct MTFinger finger[DIM_FINGER]; 28 struct FingerState finger[DIM_FINGER];
34 int nfinger; 29 int nfinger;
30 bitmask_t thumb;
35 bitmask_t button; 31 bitmask_t button;
36 mstime_t evtime; 32 mstime_t evtime;
37}; 33};
@@ -42,14 +38,14 @@ void extract_mtstate(struct MTState *s,
42 const struct Capabilities *caps); 38 const struct Capabilities *caps);
43void output_mtstate(const struct MTState *s); 39void output_mtstate(const struct MTState *s);
44 40
45const struct MTFinger *find_finger(const struct MTState *s, int id); 41const struct FingerState *find_finger(const struct MTState *s, int id);
46 42
47 43
48static inline int center_dist2(const struct MTFinger *a, 44static inline int center_dist2(const struct FingerState *a,
49 const struct Capabilities *caps) 45 const struct Capabilities *caps)
50{ 46{
51 return dist2(a->hw.position_x - get_cap_xmid(caps), 47 return dist2(a->position_x - get_cap_xmid(caps),
52 a->hw.position_y - get_cap_ymid(caps)); 48 a->position_y - get_cap_ymid(caps));
53} 49}
54 50
55static inline int center_maxdist2(const struct Capabilities *caps) 51static inline int center_maxdist2(const struct Capabilities *caps)
diff --git a/mtdev/hwdata.c b/mtdev/hwdata.c
deleted file mode 100644
index 689418e..0000000
--- a/mtdev/hwdata.c
+++ /dev/null
@@ -1,133 +0,0 @@
1/***************************************************************************
2 *
3 * Multitouch X driver
4 * Copyright (C) 2008 Henrik Rydberg <rydberg@euromail.se>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 **************************************************************************/
21
22#include "hwdata.h"
23
24void init_hwdata(struct HWData *hw)
25{
26 memset(hw, 0, sizeof(struct HWData));
27}
28
29static void set_value(struct HWData *hw, int code, int value)
30{
31 if (hw->nread < DIM_FINGER) {
32 (&hw->finger[hw->nread].touch_major)[code] = value;
33 SETBIT(hw->mread[hw->nread], code);
34 }
35 hw->mtread++;
36}
37
38static void accept_finger(struct HWData *hw)
39{
40 if (hw->nread < DIM_FINGER &&
41 GETBIT(hw->mread[hw->nread], BIT_MT_POSITION_X) &&
42 GETBIT(hw->mread[hw->nread], BIT_MT_POSITION_Y)) {
43 hw->mask[hw->nread] = hw->mread[hw->nread];
44 hw->nread++;
45 }
46 if (hw->nread < DIM_FINGER)
47 hw->mread[hw->nread] = 0;
48}
49
50static void accept_packet(struct HWData *hw, const struct timeval* tv)
51{
52 static const mstime_t ms = 1000;
53 if (hw->mtread)
54 hw->nfinger = hw->nread;
55 hw->mtread = 0;
56 hw->nread = 0;
57 hw->mread[hw->nread] = 0;
58 hw->evtime = tv->tv_usec / ms + tv->tv_sec * ms;
59}
60
61int read_hwdata(struct HWData *hw, const struct input_event* ev)
62{
63 switch (ev->type) {
64 case EV_SYN:
65 switch (ev->code) {
66 case SYN_REPORT:
67 accept_packet(hw, &ev->time);
68 return 1;
69 case SYN_MT_REPORT:
70 accept_finger(hw);
71 break;
72 }
73 break;
74 case EV_KEY:
75 switch (ev->code) {
76 case BTN_TOUCH:
77 hw->mtread++;
78 break;
79 case BTN_LEFT:
80 if (ev->value)
81 SETBIT(hw->button, MT_BUTTON_LEFT);
82 else
83 CLEARBIT(hw->button, MT_BUTTON_LEFT);
84 break;
85 case BTN_MIDDLE:
86 if (ev->value)
87 SETBIT(hw->button, MT_BUTTON_MIDDLE);
88 else
89 CLEARBIT(hw->button, MT_BUTTON_MIDDLE);
90 break;
91 case BTN_RIGHT:
92 if (ev->value)
93 SETBIT(hw->button, MT_BUTTON_RIGHT);
94 else
95 CLEARBIT(hw->button, MT_BUTTON_RIGHT);
96 break;
97 }
98 break;
99 case EV_ABS:
100 switch (ev->code) {
101 case ABS_MT_TOUCH_MAJOR:
102 set_value(hw, BIT_MT_TOUCH_MAJOR, ev->value);
103 break;
104 case ABS_MT_TOUCH_MINOR:
105 set_value(hw, BIT_MT_TOUCH_MINOR, ev->value);
106 break;
107 case ABS_MT_WIDTH_MAJOR:
108 set_value(hw, BIT_MT_WIDTH_MAJOR, ev->value);
109 break;
110 case ABS_MT_WIDTH_MINOR:
111 set_value(hw, BIT_MT_WIDTH_MINOR, ev->value);
112 break;
113 case ABS_MT_ORIENTATION:
114 set_value(hw, BIT_MT_ORIENTATION, ev->value);
115 break;
116 case ABS_MT_PRESSURE:
117 set_value(hw, BIT_MT_PRESSURE, ev->value);
118 break;
119 case ABS_MT_POSITION_X:
120 set_value(hw, BIT_MT_POSITION_X, ev->value);
121 break;
122 case ABS_MT_POSITION_Y:
123 set_value(hw, BIT_MT_POSITION_Y, ev->value);
124 break;
125 }
126 break;
127 }
128 return 0;
129}
130
131void output_hwdata(const struct HWData *hw)
132{
133}
diff --git a/src/gestures.c b/src/gestures.c
index 0cc2e0b..663f1a4 100644
--- a/src/gestures.c
+++ b/src/gestures.c
@@ -81,8 +81,8 @@ static void extract_movement(struct Gestures *gs, struct MTouch* mt)
81 return; 81 return;
82 82
83 foreach_bit(i, mt->mem.moving) { 83 foreach_bit(i, mt->mem.moving) {
84 xp[i] = mt->state.finger[i].hw.position_x - xpos; 84 xp[i] = mt->state.finger[i].position_x - xpos;
85 yp[i] = mt->state.finger[i].hw.position_y - ypos; 85 yp[i] = mt->state.finger[i].position_y - ypos;
86 xm[i] = mt->mem.dx[i]; 86 xm[i] = mt->mem.dx[i];
87 ym[i] = mt->mem.dy[i]; 87 ym[i] = mt->mem.dy[i];
88 mt->mem.dx[i] = 0; 88 mt->mem.dx[i] = 0;
@@ -178,3 +178,25 @@ void extract_gestures(struct Gestures *gs, struct MTouch* mt)
178 mt->prev_state = mt->state; 178 mt->prev_state = mt->state;
179} 179}
180 180
181
182void output_gesture(const struct Gestures *gs)
183{
184 int i;
185 foreach_bit(i, gs->btmask)
186 xf86Msg(X_INFO, "button bit: %d %d\n",
187 i, GETBIT(gs->btdata, i));
188 if (GETBIT(gs->type, GS_MOVE))
189 xf86Msg(X_INFO, "motion: %d %d\n", gs->dx, gs->dy);
190 if (GETBIT(gs->type, GS_VSCROLL))
191 xf86Msg(X_INFO, "vscroll: %d\n", gs->dy);
192 if (GETBIT(gs->type, GS_HSCROLL))
193 xf86Msg(X_INFO, "hscroll: %d\n", gs->dx);
194 if (GETBIT(gs->type, GS_VSWIPE))
195 xf86Msg(X_INFO, "vswipe: %d\n", gs->dy);
196 if (GETBIT(gs->type, GS_HSWIPE))
197 xf86Msg(X_INFO, "hswipe: %d\n", gs->dx);
198 if (GETBIT(gs->type, GS_SCALE))
199 xf86Msg(X_INFO, "scale: %d\n", gs->scale);
200 if (GETBIT(gs->type, GS_ROTATE))
201 xf86Msg(X_INFO, "rotate: %d\n", gs->rot);
202}
diff --git a/src/hwstate.c b/src/hwstate.c
index 032351c..f4f2972 100644
--- a/src/hwstate.c
+++ b/src/hwstate.c
@@ -21,91 +21,101 @@
21 21
22#include "hwstate.h" 22#include "hwstate.h"
23 23
24#define NOTOUCH(hw, c) ((hw)->touch_major == 0 && (c)->has_abs[BIT_TOUCH_MAJOR]) 24void init_hwstate(struct HWState *s, const struct Capabilities *caps)
25
26void init_hwstate(struct HWState *s)
27{ 25{
26 int i;
28 memset(s, 0, sizeof(struct HWState)); 27 memset(s, 0, sizeof(struct HWState));
28 for (i = 0; i < DIM_FINGER; i++)
29 s->data[i].tracking_id = caps->nullid;
29} 30}
30 31
31/* Dmitry Torokhov's code from kernel/driver/input/input.c */ 32static void finish_packet(struct HWState *s, const struct Capabilities *caps,
32static int defuzz(int value, int old_val, int fuzz) 33 const struct input_event *syn)
33{ 34{
34 if (fuzz) { 35 static const mstime_t ms = 1000;
35 if (value > old_val - fuzz / 2 && value < old_val + fuzz / 2) 36 int i;
36 return old_val; 37 foreach_bit(i, s->used) {
37 38 if (!caps->has_abs[BIT_TOUCH_MINOR])
38 if (value > old_val - fuzz && value < old_val + fuzz) 39 s->data[i].touch_minor = s->data[i].touch_major;
39 return (old_val * 3 + value) / 4; 40 if (!caps->has_abs[BIT_WIDTH_MINOR])
40 41 s->data[i].width_minor = s->data[i].width_major;
41 if (value > old_val - fuzz * 2 && value < old_val + fuzz * 2)
42 return (old_val + value) / 2;
43 } 42 }
44 43 s->evtime = syn->time.tv_usec / ms + syn->time.tv_sec * ms;
45 return value;
46} 44}
47 45
48static void set_finger(struct FingerState *fs, 46static int read_event(struct HWState *s, const struct Capabilities *caps,
49 const struct FingerData *hw, int id, 47 const struct input_event *ev)
50 const struct Capabilities *caps)
51{ 48{
52 int x = defuzz(hw->position_x, fs->hw.position_x, caps->abs[BIT_POSITION_X].fuzz); 49 switch (ev->type) {
53 int y = defuzz(hw->position_y, fs->hw.position_y, caps->abs[BIT_POSITION_Y].fuzz); 50 case EV_SYN:
54 int tj = defuzz(hw->touch_major, fs->hw.touch_major, caps->abs[BIT_TOUCH_MAJOR].fuzz); 51 switch (ev->code) {
55 int tn = defuzz(hw->touch_minor, fs->hw.touch_minor, caps->abs[BIT_TOUCH_MAJOR].fuzz); 52 case SYN_REPORT:
56 int wj = defuzz(hw->width_major, fs->hw.width_major, caps->abs[BIT_TOUCH_MAJOR].fuzz); 53 finish_packet(s, caps, ev);
57 int wn = defuzz(hw->width_minor, fs->hw.width_minor, caps->abs[BIT_TOUCH_MAJOR].fuzz); 54 return 1;
58 fs->id = id; 55 }
59 fs->hw = *hw; 56 break;
60 fs->hw.position_x = x; 57 case EV_KEY:
61 fs->hw.position_y = y; 58 switch (ev->code) {
62 if (hw->touch_major) { 59 case BTN_LEFT:
63 fs->hw.touch_major = tj; 60 MODBIT(s->button, MT_BUTTON_LEFT, ev->value);
64 fs->hw.touch_minor = tn; 61 break;
62 case BTN_MIDDLE:
63 MODBIT(s->button, MT_BUTTON_MIDDLE, ev->value);
64 break;
65 case BTN_RIGHT:
66 MODBIT(s->button, MT_BUTTON_RIGHT, ev->value);
67 break;
68 }
69 break;
70 case EV_ABS:
71 switch (ev->code) {
72 case ABS_MT_SLOT:
73 if (ev->value >= 0 && ev->value < DIM_FINGER)
74 s->slot = ev->value;
75 break;
76 case ABS_MT_TOUCH_MAJOR:
77 s->data[s->slot].touch_major = ev->value;
78 break;
79 case ABS_MT_TOUCH_MINOR:
80 s->data[s->slot].touch_minor = ev->value;
81 break;
82 case ABS_MT_WIDTH_MAJOR:
83 s->data[s->slot].width_major = ev->value;
84 break;
85 case ABS_MT_WIDTH_MINOR:
86 s->data[s->slot].width_minor = ev->value;
87 break;
88 case ABS_MT_ORIENTATION:
89 s->data[s->slot].orientation = ev->value;
90 break;
91 case ABS_MT_PRESSURE:
92 s->data[s->slot].pressure = ev->value;
93 break;
94 case ABS_MT_POSITION_X:
95 s->data[s->slot].position_x = ev->value;
96 break;
97 case ABS_MT_POSITION_Y:
98 s->data[s->slot].position_y = ev->value;
99 break;
100 case ABS_MT_TRACKING_ID:
101 s->data[s->slot].tracking_id = ev->value;
102 MODBIT(s->used, s->slot,
103 ev->value != caps->nullid);
104 break;
105 }
106 break;
65 } 107 }
66 fs->hw.width_major = wj; 108 return 0;
67 fs->hw.width_minor = wn;
68 if (!caps->has_abs[BIT_TOUCH_MINOR])
69 fs->hw.touch_minor = hw->touch_major;
70 if (!caps->has_abs[BIT_WIDTH_MINOR])
71 fs->hw.width_minor = hw->width_major;
72} 109}
73 110
74void modify_hwstate(struct HWState *s, 111int modify_hwstate(struct HWState *s, struct MTDev *dev,
75 const struct HWData *hw, 112 const struct Capabilities *caps)
76 const struct Capabilities *caps)
77{ 113{
78 int A[DIM2_FINGER], *row; 114 struct input_event ev;
79 int sid[DIM_FINGER], hw2s[DIM_FINGER]; 115 while (!mtdev_empty(dev)) {
80 int id, i, j; 116 mtdev_pop(dev, &ev);
81 117 if (read_event(s, caps, &ev))
82 /* setup distance matrix for finger id matching */ 118 return 1;
83 for (j = 0; j < s->nfinger; j++) {
84 sid[j] = s->finger[j].id;
85 if (NOTOUCH(&s->finger[j].hw, caps))
86 sid[j] = 0;
87 row = A + hw->nfinger * j;
88 for (i = 0; i < hw->nfinger; i++)
89 row[i] = finger_dist2(&hw->finger[i], &s->finger[j].hw);
90 } 119 }
91 120 return 0;
92 match_fingers(hw2s, A, hw->nfinger, s->nfinger);
93
94 /* update matched fingers and create new ones */
95 for (i = 0; i < hw->nfinger; i++) {
96 j = hw2s[i];
97 id = j >= 0 ? sid[j] : 0;
98 if (!NOTOUCH(&hw->finger[i], caps))
99 while (!id)
100 id = ++s->lastid;
101 set_finger(&s->finger[i], &hw->finger[i], id, caps);
102 }
103
104 /* clear remaining finger ids */
105 for (i = hw->nfinger; i < s->nfinger; i++)
106 s->finger[i].id = 0;
107
108 s->button = hw->button;
109 s->nfinger = hw->nfinger;
110 s->evtime = hw->evtime;
111} 121}
diff --git a/src/memory.c b/src/memory.c
index 4cfb7da..748aa07 100644
--- a/src/memory.c
+++ b/src/memory.c
@@ -32,13 +32,15 @@ static const int FINGER_ATTACK_MS = 40;
32static const int FINGER_DECAY_MS = 120; 32static const int FINGER_DECAY_MS = 120;
33static const int FINGER_CORNER_MS = 150; 33static const int FINGER_CORNER_MS = 150;
34 34
35static inline int dxval(const struct MTFinger *a, const struct MTFinger *b) 35static inline int dxval(const struct FingerState *a,
36 const struct FingerState *b)
36{ 37{
37 return a->hw.position_x - b->hw.position_x; 38 return a->position_x - b->position_x;
38} 39}
39static inline int dyval(const struct MTFinger *a, const struct MTFinger *b) 40static inline int dyval(const struct FingerState *a,
41 const struct FingerState *b)
40{ 42{
41 return a->hw.position_y - b->hw.position_y; 43 return a->position_y - b->position_y;
42} 44}
43 45
44void init_memory(struct Memory *mem) 46void init_memory(struct Memory *mem)
@@ -60,20 +62,18 @@ static void update_configuration(struct Memory *m,
60 const struct MTState *prev_state, 62 const struct MTState *prev_state,
61 const struct MTState *state) 63 const struct MTState *state)
62{ 64{
63 const struct MTFinger *f = state->finger; 65 const struct FingerState *f = state->finger;
64 bitmask_t fingers = BITONES(state->nfinger); 66 bitmask_t fingers = BITONES(state->nfinger);
65 int i; 67 int i;
66 m->added = 0; 68 m->added = 0;
67 foreach_bit(i, fingers) 69 foreach_bit(i, fingers)
68 if (!find_finger(prev_state, f[i].id)) 70 if (!find_finger(prev_state, f[i].tracking_id))
69 SETBIT(m->added, i); 71 SETBIT(m->added, i);
70 m->same = m->fingers == fingers && m->added == 0; 72 m->same = m->fingers == fingers && m->added == 0;
71 m->fingers = fingers; 73 m->fingers = fingers;
72 if (!m->same) 74 if (!m->same)
73 m->thumb = 0; 75 m->thumb = 0;
74 foreach_bit(i, fingers) 76 m->thumb |= state->thumb;
75 if (f[i].thumb)
76 SETBIT(m->thumb, i);
77} 77}
78 78
79/** 79/**
@@ -90,8 +90,9 @@ static void update_pointers(struct Memory *m,
90 const struct MTState *state, 90 const struct MTState *state,
91 const struct Capabilities *caps) 91 const struct Capabilities *caps)
92{ 92{
93 const struct MTFinger *f = state->finger; 93 const struct FingerState *f = state->finger;
94 int yclick = caps->abs[BIT_POSITION_Y].maximum - CLICK_AREA(caps); 94 int yclick = caps->abs[BIT_POSITION_Y].maximum - CLICK_AREA(caps);
95
95 int i; 96 int i;
96 97
97 if (state->nfinger < 2) { 98 if (state->nfinger < 2) {
@@ -102,7 +103,7 @@ static void update_pointers(struct Memory *m,
102 103
103 if (m->same) { 104 if (m->same) {
104 foreach_bit(i, m->fingers & ~m->pointing) { 105 foreach_bit(i, m->fingers & ~m->pointing) {
105 if (f[i].hw.position_y <= m->ybar) { 106 if (f[i].position_y <= m->ybar) {
106 m->pointing = m->fingers; 107 m->pointing = m->fingers;
107 return; 108 return;
108 } 109 }
@@ -113,10 +114,10 @@ static void update_pointers(struct Memory *m,
113 m->pointing = 0; 114 m->pointing = 0;
114 m->ybar = yclick; 115 m->ybar = yclick;
115 foreach_bit(i, m->fingers) { 116 foreach_bit(i, m->fingers) {
116 if (f[i].hw.position_y > yclick) 117 if (f[i].position_y > yclick)
117 continue; 118 continue;
118 if (!m->pointing || f[i].hw.position_y > m->ybar) 119 if (!m->pointing || f[i].position_y > m->ybar)
119 m->ybar = f[i].hw.position_y; 120 m->ybar = f[i].position_y;
120 SETBIT(m->pointing, i); 121 SETBIT(m->pointing, i);
121 } 122 }
122 123
@@ -140,7 +141,7 @@ static void update_movement(struct Memory *m,
140 const struct MTState *state, 141 const struct MTState *state,
141 const struct Capabilities *caps) 142 const struct Capabilities *caps)
142{ 143{
143 const struct MTFinger *prev, *f = state->finger; 144 const struct FingerState *prev, *f = state->finger;
144 int i, xcut, ycut, xmax = 0, ymax = 0; 145 int i, xcut, ycut, xmax = 0, ymax = 0;
145 146
146 m->moving = 0; 147 m->moving = 0;
@@ -167,7 +168,7 @@ static void update_movement(struct Memory *m,
167 168
168 foreach_bit(i, m->pointing) { 169 foreach_bit(i, m->pointing) {
169 int dx, dy; 170 int dx, dy;
170 prev = find_finger(prev_state, f[i].id); 171 prev = find_finger(prev_state, f[i].tracking_id);
171 dx = dxval(&f[i], prev); 172 dx = dxval(&f[i], prev);
172 dy = dyval(&f[i], prev); 173 dy = dyval(&f[i], prev);
173 m->dx[i] += dx; 174 m->dx[i] += dx;
diff --git a/src/mtouch.c b/src/mtouch.c
index ad077b7..959783a 100644
--- a/src/mtouch.c
+++ b/src/mtouch.c
@@ -33,9 +33,9 @@ int configure_mtouch(struct MTouch *mt, int fd)
33int open_mtouch(struct MTouch *mt, int fd) 33int open_mtouch(struct MTouch *mt, int fd)
34{ 34{
35 int rc; 35 int rc;
36 mtdev_init(&mt->dev, &mt->caps);
36 init_iobuf(&mt->buf); 37 init_iobuf(&mt->buf);
37 init_hwdata(&mt->hw); 38 init_hwstate(&mt->hs, &mt->caps);
38 init_hwstate(&mt->hs);
39 init_mtstate(&mt->prev_state); 39 init_mtstate(&mt->prev_state);
40 init_mtstate(&mt->state); 40 init_mtstate(&mt->state);
41 init_memory(&mt->mem); 41 init_memory(&mt->mem);
@@ -50,18 +50,11 @@ int close_mtouch(struct MTouch *mt, int fd)
50 return rc; 50 return rc;
51} 51}
52 52
53int read_synchronized_event(struct MTouch *mt, int fd) 53int parse_event(struct MTouch *mt, const struct input_event *ev)
54{ 54{
55 const struct input_event *ev; 55 mtdev_push(&mt->dev, &mt->caps, ev);
56 while (ev = get_iobuf_event(&mt->buf, fd)) 56 if (!modify_hwstate(&mt->hs, &mt->dev, &mt->caps))
57 if (read_hwdata(&mt->hw, ev)) 57 return 0;
58 return 1;
59 return 0;
60}
61
62void parse_event(struct MTouch *mt)
63{
64 modify_hwstate(&mt->hs, &mt->hw, &mt->caps);
65 extract_mtstate(&mt->state, &mt->hs, &mt->caps); 58 extract_mtstate(&mt->state, &mt->hs, &mt->caps);
66#if 0 59#if 0
67 output_mtstate(&mt->state); 60 output_mtstate(&mt->state);
@@ -70,4 +63,5 @@ void parse_event(struct MTouch *mt)
70#if 0 63#if 0
71 output_memory(&mt->mem); 64 output_memory(&mt->mem);
72#endif 65#endif
66 return 1;
73} 67}
diff --git a/src/mtstate.c b/src/mtstate.c
index 2403765..7a8ef19 100644
--- a/src/mtstate.c
+++ b/src/mtstate.c
@@ -34,7 +34,7 @@ void init_mtstate(struct MTState *s)
34 memset(s, 0, sizeof(struct MTState)); 34 memset(s, 0, sizeof(struct MTState));
35} 35}
36 36
37static int touching_finger(const struct FingerData *hw, 37static int touching_finger(const struct FingerState *hw,
38 const struct Capabilities *caps) 38 const struct Capabilities *caps)
39{ 39{
40 if (caps->has_abs[BIT_TOUCH_MAJOR] && caps->has_abs[BIT_WIDTH_MAJOR]) 40 if (caps->has_abs[BIT_TOUCH_MAJOR] && caps->has_abs[BIT_WIDTH_MAJOR])
@@ -52,8 +52,8 @@ static int touching_finger(const struct FingerData *hw,
52 * by all three values touch_major, width_minor, and trackpad size. 52 * by all three values touch_major, width_minor, and trackpad size.
53 * 53 *
54 */ 54 */
55static int thumb_finger(const struct FingerData *hw, 55static int is_thumb(const struct FingerState *hw,
56 const struct Capabilities *caps) 56 const struct Capabilities *caps)
57{ 57{
58 if (!caps->has_abs[BIT_TOUCH_MAJOR] || 58 if (!caps->has_abs[BIT_TOUCH_MAJOR] ||
59 !caps->has_abs[BIT_TOUCH_MINOR] || 59 !caps->has_abs[BIT_TOUCH_MINOR] ||
@@ -66,26 +66,17 @@ static int thumb_finger(const struct FingerData *hw,
66 hw->width_major > THUMB_WIDTH_SIZE(hw, caps); 66 hw->width_major > THUMB_WIDTH_SIZE(hw, caps);
67} 67}
68 68
69static int set_finger(struct MTFinger *f,
70 const struct FingerState *fs,
71 const struct Capabilities *caps)
72{
73 f->hw = fs->hw;
74 f->id = fs->id;
75 f->thumb = thumb_finger(&fs->hw, caps);
76}
77
78void extract_mtstate(struct MTState *s, 69void extract_mtstate(struct MTState *s,
79 const struct HWState *hs, 70 const struct HWState *hs,
80 const struct Capabilities *caps) 71 const struct Capabilities *caps)
81{ 72{
82 int i; 73 int i;
83
84 s->nfinger = 0; 74 s->nfinger = 0;
85 for (i = 0; i < hs->nfinger; i++) { 75 foreach_bit(i, hs->used) {
86 if (!touching_finger(&hs->finger[i].hw, caps)) 76 if (!touching_finger(&hs->data[i], caps))
87 continue; 77 continue;
88 set_finger(&s->finger[s->nfinger], &hs->finger[i], caps); 78 s->finger[s->nfinger] = hs->data[i];
79 MODBIT(s->thumb, s->nfinger, is_thumb(&hs->data[i], caps));
89 s->nfinger++; 80 s->nfinger++;
90 } 81 }
91 82
@@ -93,12 +84,12 @@ void extract_mtstate(struct MTState *s,
93 s->evtime = hs->evtime; 84 s->evtime = hs->evtime;
94} 85}
95 86
96const struct MTFinger *find_finger(const struct MTState *s, int id) 87const struct FingerState *find_finger(const struct MTState *s, int id)
97{ 88{
98 int i; 89 int i;
99 90
100 for (i = 0; i < s->nfinger; i++) 91 for (i = 0; i < s->nfinger; i++)
101 if (s->finger[i].id == id) 92 if (s->finger[i].tracking_id == id)
102 return s->finger + i; 93 return s->finger + i;
103 94
104 return NULL; 95 return NULL;
@@ -119,14 +110,14 @@ void output_mtstate(const struct MTState *s)
119 xf86Msg(X_INFO, 110 xf86Msg(X_INFO,
120 " %+02d %+05d:%+05d +%05d:%+05d " 111 " %+02d %+05d:%+05d +%05d:%+05d "
121 "%+06d %+06d %+05d:%+05d\n", 112 "%+06d %+06d %+05d:%+05d\n",
122 s->finger[i].id, 113 s->finger[i].tracking_id,
123 s->finger[i].hw.touch_major, 114 s->finger[i].touch_major,
124 s->finger[i].hw.touch_minor, 115 s->finger[i].touch_minor,
125 s->finger[i].hw.width_major, 116 s->finger[i].width_major,
126 s->finger[i].hw.width_minor, 117 s->finger[i].width_minor,
127 s->finger[i].hw.orientation, 118 s->finger[i].orientation,
128 s->finger[i].hw.pressure, 119 s->finger[i].pressure,
129 s->finger[i].hw.position_x, 120 s->finger[i].position_x,
130 s->finger[i].hw.position_y); 121 s->finger[i].position_y);
131 } 122 }
132} 123}
diff --git a/src/test.c b/src/test.c
index 7d983a0..0088cdd 100644
--- a/src/test.c
+++ b/src/test.c
@@ -19,24 +19,45 @@
19 * 19 *
20 **************************************************************************/ 20 **************************************************************************/
21 21
22#include <common.h> 22#include <gestures.h>
23#include <fcntl.h>
23#include <xbypass.h> 24#include <xbypass.h>
24#include <stdio.h>
25#include <time.h>
26 25
27static void print_bitfield(unsigned m) 26static void loop_device(int fd)
28{ 27{
29 int i; 28 struct Gestures gs;
30 29 struct MTouch mt;
31 printf("%d\n", m); 30 const struct input_event *ev;
32 foreach_bit(i, m) 31 struct input_event event;
33 printf("%d %d\n", i, 1 << i); 32 if (configure_mtouch(&mt, fd)) {
33 fprintf(stderr, "error: could not configure device\n");
34 return;
35 }
36 if (open_mtouch(&mt, fd)) {
37 fprintf(stderr, "error: could not open device\n");
38 return;
39 }
40 while (ev = get_iobuf_event(&mt.buf, fd)) {
41 if (parse_event(&mt, ev)) {
42 extract_gestures(&gs, &mt);
43 output_gesture(&gs);
44 }
45 }
46 close_mtouch(&mt, fd);
34} 47}
35 48
36int main(int argc, char *argv[]) 49int main(int argc, char *argv[])
37{ 50{
38 print_bitfield(5); 51 if (argc < 2) {
39 print_bitfield(126); 52 fprintf(stderr, "Usage: test <mtdev>\n");
40 print_bitfield(0); 53 return -1;
54 }
55 int fd = open(argv[1], O_RDONLY);
56 if (fd < 0) {
57 fprintf(stderr, "error: could not open file\n");
58 return -1;
59 }
60 loop_device(fd);
61 close(fd);
41 return 0; 62 return 0;
42} 63}