diff options
| author | Henrik Rydberg <rydberg@euromail.se> | 2010-05-14 01:29:38 +0200 |
|---|---|---|
| committer | Henrik Rydberg <rydberg@euromail.se> | 2010-05-14 01:41:39 +0200 |
| commit | c8c74659d27b9eb0d45342db9a4969389e20f26a (patch) | |
| tree | cecd1876745b2288cb45007522a046f12d144f31 /src | |
| parent | bfd266660d69e13263e3895fb059040b65255a72 (diff) | |
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 <rydberg@euromail.se>
Diffstat (limited to 'src')
| -rw-r--r-- | src/gestures.c | 52 | ||||
| -rw-r--r-- | src/memory.c | 99 | ||||
| -rw-r--r-- | src/memory.h | 20 | ||||
| -rw-r--r-- | 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) | |||
| 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 */ |
| 28 | static const int FINGER_ATTACK_MS = 70; | 28 | static const int FINGER_ATTACK_MS = 40; |
| 29 | static const int FINGER_DECAY_MS = 120; | 29 | static const int FINGER_DECAY_MS = 120; |
| 30 | static const int FINGER_CORNER_MS = 150; | ||
| 30 | 31 | ||
| 31 | static inline int dxval(const struct MTFinger *a, const struct MTFinger *b) | 32 | static 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 | ||
| 177 | void refresh_memory(struct Memory *m, | 181 | void 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 | */ |
| 41 | struct Memory { | 44 | struct 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); |
| 54 | void output_memory(const struct Memory *m); | 58 | void output_memory(const struct Memory *m); |
| 55 | 59 | ||
| 60 | static inline void mem_hold_movement(struct Memory *m, mstime_t t) | ||
| 61 | { | ||
| 62 | if (t > m->mvhold) | ||
| 63 | m->mvhold = t; | ||
| 64 | } | ||
| 65 | |||
| 66 | static 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); | |||
| 45 | int read_synchronized_event(struct MTouch *mt, int fd); | 45 | int read_synchronized_event(struct MTouch *mt, int fd); |
| 46 | void parse_event(struct MTouch *mt); | 46 | void parse_event(struct MTouch *mt); |
| 47 | 47 | ||
| 48 | |||
| 49 | static inline void mt_delay_movement(struct MTouch *mt, int t) | ||
| 50 | { | ||
| 51 | mem_hold_movement(&mt->mem, mt->state.evtime + t); | ||
| 52 | } | ||
| 53 | |||
| 54 | static 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 |
