summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gestures.c52
-rw-r--r--src/memory.c99
-rw-r--r--src/memory.h20
-rw-r--r--src/mtouch.h11
4 files changed, 112 insertions, 70 deletions
diff --git a/src/gestures.c b/src/gestures.c
index f5244aa..b6c3bf4 100644
--- a/src/gestures.c
+++ b/src/gestures.c
@@ -65,31 +65,41 @@ static void extract_movement(struct Gestures *gs, struct MTouch* mt)
65 int npoint = bitcount(mt->mem.pointing); 65 int npoint = bitcount(mt->mem.pointing);
66 int nmove = bitcount(mt->mem.moving); 66 int nmove = bitcount(mt->mem.moving);
67 int i; 67 int i;
68 if (nmove && mt->state.evtime >= mt->mem.move_time) { 68 float xm[DIM_FINGER], ym[DIM_FINGER];
69 for (i = 0; i < mt->state.nfinger; i++) { 69 float xmove = 0, ymove = 0;
70 if (GETBIT(mt->mem.moving, i)) { 70
71 gs->dx += mt->mem.dx[i]; 71 if (!nmove || nmove != npoint)
72 gs->dy += mt->mem.dy[i]; 72 return;
73 } 73
74 } 74 foreach_bit(i, mt->mem.moving) {
75 gs->dx /= nmove; 75 xm[i] = mt->mem.dx[i];
76 gs->dy /= nmove; 76 ym[i] = mt->mem.dy[i];
77 memset(mt->mem.dx, 0, sizeof(mt->mem.dx)); 77 mt->mem.dx[i] = 0;
78 memset(mt->mem.dy, 0, sizeof(mt->mem.dy)); 78 mt->mem.dy[i] = 0;
79 xmove += xm[i];
80 ymove += ym[i];
79 } 81 }
80 if (gs->dx || gs->dy) { 82 xmove /= nmove;
81 if (npoint == 1) 83 ymove /= nmove;
84
85 if (nmove == 1) {
86 gs->dx = xmove;
87 gs->dy = ymove;
88 if (gs->dx || gs->dy)
82 SETBIT(gs->type, GS_MOVE); 89 SETBIT(gs->type, GS_MOVE);
83 if (npoint == 2) { 90 } else {
84 if (gs->dx) 91 gs->dx = xmove;
92 gs->dy = ymove;
93 if (abs(gs->dx) > abs(gs->dy)) {
94 if (nmove == 2)
85 SETBIT(gs->type, GS_HSCROLL); 95 SETBIT(gs->type, GS_HSCROLL);
86 if (gs->dy) 96 if (nmove == 3)
87 SETBIT(gs->type, GS_VSCROLL);
88 }
89 if (npoint == 3) {
90 if (gs->dx)
91 SETBIT(gs->type, GS_HSWIPE); 97 SETBIT(gs->type, GS_HSWIPE);
92 if (gs->dy) 98 }
99 if (abs(gs->dy) > abs(gs->dx)) {
100 if (nmove == 2)
101 SETBIT(gs->type, GS_VSCROLL);
102 if (nmove == 3)
93 SETBIT(gs->type, GS_VSWIPE); 103 SETBIT(gs->type, GS_VSWIPE);
94 } 104 }
95 } 105 }
diff --git a/src/memory.c b/src/memory.c
index a09eadb..7d8cda8 100644
--- a/src/memory.c
+++ b/src/memory.c
@@ -22,11 +22,12 @@
22#include "memory.h" 22#include "memory.h"
23 23
24/* fraction of max movement threshold */ 24/* fraction of max movement threshold */
25#define DELTA_CUT(x) (0.2 * (x)) 25#define DELTA_CUT(x) (0.5 * (x))
26 26
27/* timer for cursor stability on finger touch/release */ 27/* timer for cursor stability on finger touch/release */
28static const int FINGER_ATTACK_MS = 70; 28static const int FINGER_ATTACK_MS = 40;
29static const int FINGER_DECAY_MS = 120; 29static const int FINGER_DECAY_MS = 120;
30static const int FINGER_CORNER_MS = 150;
30 31
31static inline int dxval(const struct MTFinger *a, const struct MTFinger *b) 32static inline int dxval(const struct MTFinger *a, const struct MTFinger *b)
32{ 33{
@@ -57,10 +58,14 @@ static void update_configuration(struct Memory *m,
57 const struct MTState *state) 58 const struct MTState *state)
58{ 59{
59 const struct MTFinger *f = state->finger; 60 const struct MTFinger *f = state->finger;
61 unsigned fingers = BITONES(state->nfinger);
60 int i; 62 int i;
61 m->same = state->nfinger == prev_state->nfinger; 63 m->added = 0;
62 for (i = 0; i < state->nfinger; i++) 64 foreach_bit(i, fingers)
63 m->same = m->same && find_finger(prev_state, f[i].id); 65 if (!find_finger(prev_state, f[i].id))
66 SETBIT(m->added, i);
67 m->same = m->fingers == fingers && m->added == 0;
68 m->fingers = fingers;
64} 69}
65 70
66/** 71/**
@@ -81,17 +86,15 @@ static void update_pointers(struct Memory *m,
81 int i; 86 int i;
82 87
83 if (state->nfinger < 2) { 88 if (state->nfinger < 2) {
84 m->pointing = state->nfinger; 89 m->pointing = m->fingers;
85 m->ybar = caps->abs_position_y.maximum; 90 m->ybar = caps->abs_position_y.maximum;
86 return; 91 return;
87 } 92 }
88 93
89 if (m->same) { 94 if (m->same) {
90 for (i = 0; i < state->nfinger; i++) { 95 foreach_bit(i, m->fingers & ~m->pointing) {
91 if (GETBIT(m->pointing, i))
92 continue;
93 if (f[i].hw.position_y <= m->ybar) { 96 if (f[i].hw.position_y <= m->ybar) {
94 m->pointing = BITONES(state->nfinger); 97 m->pointing = m->fingers;
95 return; 98 return;
96 } 99 }
97 } 100 }
@@ -100,7 +103,7 @@ static void update_pointers(struct Memory *m,
100 103
101 m->pointing = 0; 104 m->pointing = 0;
102 m->ybar = caps->yclick; 105 m->ybar = caps->yclick;
103 for (i = 0; i < state->nfinger; i++) { 106 foreach_bit(i, m->fingers) {
104 if (f[i].hw.position_y > caps->yclick) 107 if (f[i].hw.position_y > caps->yclick)
105 continue; 108 continue;
106 if (!m->pointing || f[i].hw.position_y > m->ybar) 109 if (!m->pointing || f[i].hw.position_y > m->ybar)
@@ -129,49 +132,50 @@ static void update_movement(struct Memory *m,
129 const struct Capabilities *caps) 132 const struct Capabilities *caps)
130{ 133{
131 const struct MTFinger *prev, *f = state->finger; 134 const struct MTFinger *prev, *f = state->finger;
132 int i, x = 0, y = 0; 135 int i, xcut, ycut, xmax = 0, ymax = 0;
133 int dx, dy, xcut, ycut, xmax = 0, ymax = 0;
134 136
135 m->pending = 0;
136 m->moving = 0; 137 m->moving = 0;
137 138 m->pending = 0;
138 if (state->nfinger == 0)
139 return;
140 139
141 if (!m->same) { 140 if (!m->same) {
142 m->move_time = state->evtime; 141 mstime_t d2, d2max = center_maxdist2(caps);
143 if (state->nfinger > prev_state->nfinger) 142 mem_hold_movement(m, state->evtime + FINGER_ATTACK_MS);
144 m->move_time += FINGER_ATTACK_MS; 143 if (!m->added)
145 else 144 mem_hold_movement(m, state->evtime + FINGER_DECAY_MS);
146 m->move_time += FINGER_DECAY_MS; 145 foreach_bit(i, m->added) {
146 d2 = center_dist2(&f[i], caps);
147 d2 *= FINGER_CORNER_MS - FINGER_ATTACK_MS;
148 d2 /= d2max;
149 m->mvhold += d2;
150 }
147 memset(m->dx, 0, sizeof(m->dx)); 151 memset(m->dx, 0, sizeof(m->dx));
148 memset(m->dy, 0, sizeof(m->dy)); 152 memset(m->dy, 0, sizeof(m->dy));
149 } else { 153 return;
150 for (i = 0; i < state->nfinger; i++) { 154 }
151 if (!GETBIT(m->pointing, i)) 155
152 continue; 156 if (state->evtime < m->mvforget)
153 prev = find_finger(prev_state, f[i].id); 157 return;
154 dx = dxval(&f[i], prev);
155 dy = dyval(&f[i], prev);
156 m->dx[i] += dx;
157 m->dy[i] += dy;
158 xmax = maxval(xmax, abs(m->dx[i]));
159 ymax = maxval(ymax, abs(m->dy[i]));
160 }
161 xcut = DELTA_CUT(xmax);
162 ycut = DELTA_CUT(ymax);
163 for (i = 0; i < state->nfinger; i++) {
164 if (!GETBIT(m->pointing, i))
165 continue;
166 if (abs(m->dx[i]) > xcut ||
167 abs(m->dy[i]) > ycut)
168 SETBIT(m->pending, i);
169 }
170 158
171 /* accumulate all movement during delay */ 159 foreach_bit(i, m->pointing) {
172 if (m->pending && state->evtime >= m->move_time) 160 int dx, dy;
173 m->moving = m->pending; 161 prev = find_finger(prev_state, f[i].id);
162 dx = dxval(&f[i], prev);
163 dy = dyval(&f[i], prev);
164 m->dx[i] += dx;
165 m->dy[i] += dy;
166 xmax = maxval(xmax, abs(m->dx[i]));
167 ymax = maxval(ymax, abs(m->dy[i]));
174 } 168 }
169 xcut = DELTA_CUT(xmax);
170 ycut = DELTA_CUT(ymax);
171 foreach_bit(i, m->pointing)
172 if (abs(m->dx[i]) > xcut || abs(m->dy[i]) > ycut)
173 SETBIT(m->pending, i);
174
175 if (state->evtime < m->mvhold)
176 return;
177
178 m->moving = m->pending;
175} 179}
176 180
177void refresh_memory(struct Memory *m, 181void refresh_memory(struct Memory *m,
@@ -188,9 +192,10 @@ void output_memory(const struct Memory *m)
188{ 192{
189 int i; 193 int i;
190 xf86Msg(X_INFO, "btdata: %04x\n", m->btdata); 194 xf86Msg(X_INFO, "btdata: %04x\n", m->btdata);
195 xf86Msg(X_INFO, "fingers: %04x\n", m->fingers);
196 xf86Msg(X_INFO, "added: %04x\n", m->added);
191 xf86Msg(X_INFO, "pointing: %04x\n", m->pointing); 197 xf86Msg(X_INFO, "pointing: %04x\n", m->pointing);
192 xf86Msg(X_INFO, "pending: %04x\n", m->pending); 198 xf86Msg(X_INFO, "pending: %04x\n", m->pending);
193 xf86Msg(X_INFO, "moving: %04x\n", m->moving); 199 xf86Msg(X_INFO, "moving: %04x\n", m->moving);
194 xf86Msg(X_INFO, "ybar: %d\n", m->ybar); 200 xf86Msg(X_INFO, "ybar: %d\n", m->ybar);
195 xf86Msg(X_INFO, "move_time: %lld\n", m->move_time);
196} 201}
diff --git a/src/memory.h b/src/memory.h
index 9810b81..cc7bf55 100644
--- a/src/memory.h
+++ b/src/memory.h
@@ -29,20 +29,24 @@
29 * 29 *
30 * @btdata: logical finger state 30 * @btdata: logical finger state
31 * @same: true if the finger configuration is unchanged 31 * @same: true if the finger configuration is unchanged
32 * @fingers: bitmask of fingers on the pad
33 * @added: bitmask of new fingers on the pad
32 * @pointing: bitmask of pointing fingers 34 * @pointing: bitmask of pointing fingers
33 * @pending: bitmask of tentatively moving fingers 35 * @pending: bitmask of tentatively moving fingers
34 * @moving: bitmask of moving fingers 36 * @moving: bitmask of moving fingers
35 * @ybar: vertical position on pad marking the clicking area 37 * @ybar: vertical position on pad marking the clicking area
36 * @move_time: movement before this point in time is accumulated 38 * @mvhold: movement before this point in time is accumulated
39 * @mvforget: movement before this point in time is discarded
37 * @dx: array of accumulated horiontal movement per finger 40 * @dx: array of accumulated horiontal movement per finger
38 * @dy: array of accumulated vertical movement per finger 41 * @dy: array of accumulated vertical movement per finger
39 * 42 *
40 */ 43 */
41struct Memory { 44struct Memory {
42 unsigned btdata, same; 45 unsigned btdata, same;
46 unsigned fingers, added;
43 unsigned pointing, pending, moving; 47 unsigned pointing, pending, moving;
44 int ybar; 48 int ybar;
45 mstime_t move_time; 49 mstime_t mvhold, mvforget;
46 int dx[DIM_FINGER], dy[DIM_FINGER]; 50 int dx[DIM_FINGER], dy[DIM_FINGER];
47}; 51};
48 52
@@ -53,4 +57,16 @@ void refresh_memory(struct Memory *m,
53 const struct Capabilities *caps); 57 const struct Capabilities *caps);
54void output_memory(const struct Memory *m); 58void output_memory(const struct Memory *m);
55 59
60static inline void mem_hold_movement(struct Memory *m, mstime_t t)
61{
62 if (t > m->mvhold)
63 m->mvhold = t;
64}
65
66static inline void mem_forget_movement(struct Memory *m, mstime_t t)
67{
68 if (t > m->mvforget)
69 m->mvforget = t;
70}
71
56#endif 72#endif
diff --git a/src/mtouch.h b/src/mtouch.h
index 4004b4d..aab35bd 100644
--- a/src/mtouch.h
+++ b/src/mtouch.h
@@ -45,4 +45,15 @@ int close_mtouch(struct MTouch *mt, int fd);
45int read_synchronized_event(struct MTouch *mt, int fd); 45int read_synchronized_event(struct MTouch *mt, int fd);
46void parse_event(struct MTouch *mt); 46void parse_event(struct MTouch *mt);
47 47
48
49static inline void mt_delay_movement(struct MTouch *mt, int t)
50{
51 mem_hold_movement(&mt->mem, mt->state.evtime + t);
52}
53
54static inline void mt_skip_movement(struct MTouch *mt, int t)
55{
56 mem_forget_movement(&mt->mem, mt->state.evtime + t);
57}
58
48#endif 59#endif