From c8c74659d27b9eb0d45342db9a4969389e20f26a Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Fri, 14 May 2010 01:29:38 +0200 Subject: Refactor parsor memory usage Add the bitmasks "fingers" and "added" to parsor memory, and extend time handling to use a hold time and a forget time. Signed-off-by: Henrik Rydberg --- src/gestures.c | 52 +++++++++++++++++------------- src/memory.c | 99 ++++++++++++++++++++++++++++++---------------------------- src/memory.h | 20 ++++++++++-- src/mtouch.h | 11 +++++++ 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) int npoint = bitcount(mt->mem.pointing); int nmove = bitcount(mt->mem.moving); int i; - if (nmove && mt->state.evtime >= mt->mem.move_time) { - for (i = 0; i < mt->state.nfinger; i++) { - if (GETBIT(mt->mem.moving, i)) { - gs->dx += mt->mem.dx[i]; - gs->dy += mt->mem.dy[i]; - } - } - gs->dx /= nmove; - gs->dy /= nmove; - memset(mt->mem.dx, 0, sizeof(mt->mem.dx)); - memset(mt->mem.dy, 0, sizeof(mt->mem.dy)); + float xm[DIM_FINGER], ym[DIM_FINGER]; + float xmove = 0, ymove = 0; + + if (!nmove || nmove != npoint) + return; + + foreach_bit(i, mt->mem.moving) { + xm[i] = mt->mem.dx[i]; + ym[i] = mt->mem.dy[i]; + mt->mem.dx[i] = 0; + mt->mem.dy[i] = 0; + xmove += xm[i]; + ymove += ym[i]; } - if (gs->dx || gs->dy) { - if (npoint == 1) + xmove /= nmove; + ymove /= nmove; + + if (nmove == 1) { + gs->dx = xmove; + gs->dy = ymove; + if (gs->dx || gs->dy) SETBIT(gs->type, GS_MOVE); - if (npoint == 2) { - if (gs->dx) + } else { + gs->dx = xmove; + gs->dy = ymove; + if (abs(gs->dx) > abs(gs->dy)) { + if (nmove == 2) SETBIT(gs->type, GS_HSCROLL); - if (gs->dy) - SETBIT(gs->type, GS_VSCROLL); - } - if (npoint == 3) { - if (gs->dx) + if (nmove == 3) SETBIT(gs->type, GS_HSWIPE); - if (gs->dy) + } + if (abs(gs->dy) > abs(gs->dx)) { + if (nmove == 2) + SETBIT(gs->type, GS_VSCROLL); + if (nmove == 3) SETBIT(gs->type, GS_VSWIPE); } } 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 @@ #include "memory.h" /* fraction of max movement threshold */ -#define DELTA_CUT(x) (0.2 * (x)) +#define DELTA_CUT(x) (0.5 * (x)) /* timer for cursor stability on finger touch/release */ -static const int FINGER_ATTACK_MS = 70; +static const int FINGER_ATTACK_MS = 40; static const int FINGER_DECAY_MS = 120; +static const int FINGER_CORNER_MS = 150; static inline int dxval(const struct MTFinger *a, const struct MTFinger *b) { @@ -57,10 +58,14 @@ static void update_configuration(struct Memory *m, const struct MTState *state) { const struct MTFinger *f = state->finger; + unsigned fingers = BITONES(state->nfinger); int i; - m->same = state->nfinger == prev_state->nfinger; - for (i = 0; i < state->nfinger; i++) - m->same = m->same && find_finger(prev_state, f[i].id); + m->added = 0; + foreach_bit(i, fingers) + if (!find_finger(prev_state, f[i].id)) + SETBIT(m->added, i); + m->same = m->fingers == fingers && m->added == 0; + m->fingers = fingers; } /** @@ -81,17 +86,15 @@ static void update_pointers(struct Memory *m, int i; if (state->nfinger < 2) { - m->pointing = state->nfinger; + m->pointing = m->fingers; m->ybar = caps->abs_position_y.maximum; return; } if (m->same) { - for (i = 0; i < state->nfinger; i++) { - if (GETBIT(m->pointing, i)) - continue; + foreach_bit(i, m->fingers & ~m->pointing) { if (f[i].hw.position_y <= m->ybar) { - m->pointing = BITONES(state->nfinger); + m->pointing = m->fingers; return; } } @@ -100,7 +103,7 @@ static void update_pointers(struct Memory *m, m->pointing = 0; m->ybar = caps->yclick; - for (i = 0; i < state->nfinger; i++) { + foreach_bit(i, m->fingers) { if (f[i].hw.position_y > caps->yclick) continue; if (!m->pointing || f[i].hw.position_y > m->ybar) @@ -129,49 +132,50 @@ static void update_movement(struct Memory *m, const struct Capabilities *caps) { const struct MTFinger *prev, *f = state->finger; - int i, x = 0, y = 0; - int dx, dy, xcut, ycut, xmax = 0, ymax = 0; + int i, xcut, ycut, xmax = 0, ymax = 0; - m->pending = 0; m->moving = 0; - - if (state->nfinger == 0) - return; + m->pending = 0; if (!m->same) { - m->move_time = state->evtime; - if (state->nfinger > prev_state->nfinger) - m->move_time += FINGER_ATTACK_MS; - else - m->move_time += FINGER_DECAY_MS; + mstime_t d2, d2max = center_maxdist2(caps); + mem_hold_movement(m, state->evtime + FINGER_ATTACK_MS); + if (!m->added) + mem_hold_movement(m, state->evtime + FINGER_DECAY_MS); + foreach_bit(i, m->added) { + d2 = center_dist2(&f[i], caps); + d2 *= FINGER_CORNER_MS - FINGER_ATTACK_MS; + d2 /= d2max; + m->mvhold += d2; + } memset(m->dx, 0, sizeof(m->dx)); memset(m->dy, 0, sizeof(m->dy)); - } else { - for (i = 0; i < state->nfinger; i++) { - if (!GETBIT(m->pointing, i)) - continue; - prev = find_finger(prev_state, f[i].id); - dx = dxval(&f[i], prev); - dy = dyval(&f[i], prev); - m->dx[i] += dx; - m->dy[i] += dy; - xmax = maxval(xmax, abs(m->dx[i])); - ymax = maxval(ymax, abs(m->dy[i])); - } - xcut = DELTA_CUT(xmax); - ycut = DELTA_CUT(ymax); - for (i = 0; i < state->nfinger; i++) { - if (!GETBIT(m->pointing, i)) - continue; - if (abs(m->dx[i]) > xcut || - abs(m->dy[i]) > ycut) - SETBIT(m->pending, i); - } + return; + } + + if (state->evtime < m->mvforget) + return; - /* accumulate all movement during delay */ - if (m->pending && state->evtime >= m->move_time) - m->moving = m->pending; + foreach_bit(i, m->pointing) { + int dx, dy; + prev = find_finger(prev_state, f[i].id); + dx = dxval(&f[i], prev); + dy = dyval(&f[i], prev); + m->dx[i] += dx; + m->dy[i] += dy; + xmax = maxval(xmax, abs(m->dx[i])); + ymax = maxval(ymax, abs(m->dy[i])); } + xcut = DELTA_CUT(xmax); + ycut = DELTA_CUT(ymax); + foreach_bit(i, m->pointing) + if (abs(m->dx[i]) > xcut || abs(m->dy[i]) > ycut) + SETBIT(m->pending, i); + + if (state->evtime < m->mvhold) + return; + + m->moving = m->pending; } void refresh_memory(struct Memory *m, @@ -188,9 +192,10 @@ void output_memory(const struct Memory *m) { int i; xf86Msg(X_INFO, "btdata: %04x\n", m->btdata); + xf86Msg(X_INFO, "fingers: %04x\n", m->fingers); + xf86Msg(X_INFO, "added: %04x\n", m->added); xf86Msg(X_INFO, "pointing: %04x\n", m->pointing); xf86Msg(X_INFO, "pending: %04x\n", m->pending); xf86Msg(X_INFO, "moving: %04x\n", m->moving); xf86Msg(X_INFO, "ybar: %d\n", m->ybar); - xf86Msg(X_INFO, "move_time: %lld\n", m->move_time); } 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 @@ * * @btdata: logical finger state * @same: true if the finger configuration is unchanged + * @fingers: bitmask of fingers on the pad + * @added: bitmask of new fingers on the pad * @pointing: bitmask of pointing fingers * @pending: bitmask of tentatively moving fingers * @moving: bitmask of moving fingers * @ybar: vertical position on pad marking the clicking area - * @move_time: movement before this point in time is accumulated + * @mvhold: movement before this point in time is accumulated + * @mvforget: movement before this point in time is discarded * @dx: array of accumulated horiontal movement per finger * @dy: array of accumulated vertical movement per finger * */ struct Memory { unsigned btdata, same; + unsigned fingers, added; unsigned pointing, pending, moving; int ybar; - mstime_t move_time; + mstime_t mvhold, mvforget; int dx[DIM_FINGER], dy[DIM_FINGER]; }; @@ -53,4 +57,16 @@ void refresh_memory(struct Memory *m, const struct Capabilities *caps); void output_memory(const struct Memory *m); +static inline void mem_hold_movement(struct Memory *m, mstime_t t) +{ + if (t > m->mvhold) + m->mvhold = t; +} + +static inline void mem_forget_movement(struct Memory *m, mstime_t t) +{ + if (t > m->mvforget) + m->mvforget = t; +} + #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); int read_synchronized_event(struct MTouch *mt, int fd); void parse_event(struct MTouch *mt); + +static inline void mt_delay_movement(struct MTouch *mt, int t) +{ + mem_hold_movement(&mt->mem, mt->state.evtime + t); +} + +static inline void mt_skip_movement(struct MTouch *mt, int t) +{ + mem_forget_movement(&mt->mem, mt->state.evtime + t); +} + #endif -- cgit v1.2.3