summaryrefslogtreecommitdiff
path: root/src/memory.c
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2010-06-16 18:48:53 +0200
committerHenrik Rydberg <rydberg@euromail.se>2010-06-16 18:54:52 +0200
commit21a363a2486a713434e890fc1f6b86a180755230 (patch)
treeca788ccf7c8269c5cbd41350463fa478aa499903 /src/memory.c
parent523d193b089111849873d9de0ec1bf29f4176fbc (diff)
Add tapping logic
This patch adds tap-to-click, tap-and-hold for dragging, two-finger and three-finger taps. Turned on by default for touch screens only; switch on in gestures.c. Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'src/memory.c')
-rw-r--r--src/memory.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/memory.c b/src/memory.c
index cd88d7a..2bb4d95 100644
--- a/src/memory.c
+++ b/src/memory.c
@@ -27,11 +27,20 @@
27/* fraction of max movement threshold */ 27/* fraction of max movement threshold */
28#define DELTA_CUT(x) (0.5 * (x)) 28#define DELTA_CUT(x) (0.5 * (x))
29 29
30/* fraction of tap movement threshold */
31#define TAP_XMOVE(c) (0.05 * get_cap_xsize(c))
32#define TAP_YMOVE(c) (0.05 * get_cap_ysize(c))
33
30/* timer for cursor stability on finger touch/release */ 34/* timer for cursor stability on finger touch/release */
31static const int FINGER_ATTACK_MS = 40; 35static const int FINGER_ATTACK_MS = 40;
32static const int FINGER_DECAY_MS = 120; 36static const int FINGER_DECAY_MS = 120;
33static const int FINGER_CORNER_MS = 300; 37static const int FINGER_CORNER_MS = 300;
34 38
39/* tapping timings */
40static const int TAP_SETTLE_MS = 400;
41static const int TAP_TOUCH_MS = 120;
42static const int TAP_GAP_MS = 200;
43
35static inline int dxval(const struct FingerState *a, 44static inline int dxval(const struct FingerState *a,
36 const struct FingerState *b) 45 const struct FingerState *b)
37{ 46{
@@ -43,6 +52,23 @@ static inline int dyval(const struct FingerState *a,
43 return a->position_y - b->position_y; 52 return a->position_y - b->position_y;
44} 53}
45 54
55static inline void relax_tapping(struct Memory *m, const struct MTState *state)
56{
57 m->tprelax = state->evtime + TAP_SETTLE_MS;
58 m->wait = 0;
59 m->ntap = 0;
60}
61
62static inline int unrelated_taps(const struct Memory *m,
63 const struct Capabilities *caps)
64{
65 return abs(m->xdown - m->xup) > TAP_XMOVE(caps) ||
66 abs(m->ydown - m->yup) > TAP_YMOVE(caps);
67}
68
69/**
70 * init_memory
71 */
46void init_memory(struct Memory *mem) 72void init_memory(struct Memory *mem)
47{ 73{
48 memset(mem, 0, sizeof(struct Memory)); 74 memset(mem, 0, sizeof(struct Memory));
@@ -188,6 +214,63 @@ static void update_movement(struct Memory *m,
188 m->moving = m->pending; 214 m->moving = m->pending;
189} 215}
190 216
217/**
218 * update_tapping
219 *
220 * Update tpdown, tpup, tprelax, wait, maxtap, ntap.
221 *
222 * Precondition: pointing and thumb are set
223 *
224 * Postcondition: tpdown, tpup, tprelax, wait, maxtap, ntap set
225 *
226 */
227static void update_tapping(struct Memory *m,
228 const struct MTState *prev_state,
229 const struct MTState *state,
230 const struct Capabilities *caps)
231{
232 int x, y, i, npoint = bitcount(m->pointing);
233
234 /* use a position independent on the number of fingers */
235 if (state->nfinger) {
236 x = state->finger[0].position_x;
237 y = state->finger[0].position_y;
238 for (i = 1; i < state->nfinger; i++) {
239 x = minval(x, state->finger[i].position_x);
240 y = minval(y, state->finger[i].position_y);
241 }
242 }
243
244 if (m->thumb || state->evtime < m->mvforget) {
245 relax_tapping(m, state);
246 } else if (state->nfinger && !prev_state->nfinger) {
247 m->tpdown = state->evtime;
248 m->xdown = x;
249 m->ydown = y;
250 m->wait = 0;
251 m->maxtap = npoint;
252 if (m->tpdown > m->tpup + TAP_GAP_MS)
253 m->ntap = 0;
254 else if (unrelated_taps(m, caps))
255 relax_tapping(m, state);
256 m->xup = x;
257 m->yup = y;
258 } else if (!state->nfinger && prev_state->nfinger) {
259 m->tpup = state->evtime;
260 if (m->tpup > m->tprelax &&
261 m->tpup <= m->tpdown + TAP_TOUCH_MS) {
262 m->wait = TAP_GAP_MS;
263 m->ntap++;
264 if (unrelated_taps(m, caps))
265 relax_tapping(m, state);
266 }
267 } else if (state->nfinger) {
268 m->xup = minval(m->xup, x);
269 m->yup = minval(m->yup, y);
270 m->maxtap = maxval(m->maxtap, npoint);
271 }
272}
273
191void refresh_memory(struct Memory *m, 274void refresh_memory(struct Memory *m,
192 const struct MTState *prev_state, 275 const struct MTState *prev_state,
193 const struct MTState *state, 276 const struct MTState *state,
@@ -196,6 +279,7 @@ void refresh_memory(struct Memory *m,
196 update_configuration(m, prev_state, state); 279 update_configuration(m, prev_state, state);
197 update_pointers(m, state, caps); 280 update_pointers(m, state, caps);
198 update_movement(m, prev_state, state, caps); 281 update_movement(m, prev_state, state, caps);
282 update_tapping(m, prev_state, state, caps);
199} 283}
200 284
201void output_memory(const struct Memory *m) 285void output_memory(const struct Memory *m)