From f02210172efc6bfc05c4598c14e1268d2828097e Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Fri, 14 May 2010 01:09:42 +0200 Subject: Simplify bit bookkeeping In preparation of adding several additional finger bit registers, remove the redundant bit-counting variables and introduce fast bit-traversal functions instead. Signed-off-by: Henrik Rydberg --- src/common.h | 15 +++++++++++++++ src/gestures.c | 30 +++++++++++++----------------- src/memory.c | 2 -- src/memory.h | 4 ++-- src/test.c | 13 +++++++++++++ 5 files changed, 43 insertions(+), 21 deletions(-) diff --git a/src/common.h b/src/common.h index 27082b7..1b4d007 100644 --- a/src/common.h +++ b/src/common.h @@ -61,4 +61,19 @@ #define SETBIT(m, x) (m |= BITMASK(x)) #define CLEARBIT(m, x) (m &= ~BITMASK(x)) +/* Count number of bits (Sean Eron Andersson's Bit Hacks) */ +static inline int bitcount(unsigned v) +{ + v -= ((v>>1) & 0x55555555); + v = (v&0x33333333) + ((v>>2) & 0x33333333); + return (((v + (v>>4)) & 0xF0F0F0F) * 0x1010101) >> 24; +} + +/* Return index of first bit [0-31], -1 on zero */ +#define firstbit(v) (__builtin_ffs(v) - 1) + +/* boost-style foreach bit */ +#define foreach_bit(i, m) \ + for (i = firstbit(m); i >= 0; i = firstbit((m) & (~0U << i + 1))) + #endif diff --git a/src/gestures.c b/src/gestures.c index 7346043..f44e6ab 100644 --- a/src/gestures.c +++ b/src/gestures.c @@ -58,7 +58,6 @@ static void extract_pointers(struct Gestures *gs, struct MTouch* mt) if (mt->state.nfinger < 2) { mt->mem.pointing = mt->state.nfinger; - mt->mem.npoint = mt->state.nfinger; mt->mem.ybar = mt->caps.abs_position_y.maximum; return; } @@ -69,7 +68,6 @@ static void extract_pointers(struct Gestures *gs, struct MTouch* mt) continue; if (f[i].hw.position_y <= mt->mem.ybar) { mt->mem.pointing = BITONES(mt->state.nfinger); - mt->mem.npoint = mt->state.nfinger; return; } } @@ -77,15 +75,13 @@ static void extract_pointers(struct Gestures *gs, struct MTouch* mt) } mt->mem.pointing = 0; - mt->mem.npoint = 0; mt->mem.ybar = mt->caps.yclick; for (i = 0; i < mt->state.nfinger; i++) { if (f[i].hw.position_y > mt->caps.yclick) continue; - if (!mt->mem.npoint || f[i].hw.position_y > mt->mem.ybar) + if (!mt->mem.pointing || f[i].hw.position_y > mt->mem.ybar) mt->mem.ybar = f[i].hw.position_y; SETBIT(mt->mem.pointing, i); - mt->mem.npoint++; } } @@ -97,7 +93,6 @@ static void extract_movement(struct Gestures *gs, struct MTouch* mt) int dx, dy, xcut, ycut, xmax = 0, ymax = 0; mt->mem.moving = 0; - mt->mem.nmove = 0; if (mt->state.nfinger == 0) return; @@ -128,22 +123,21 @@ static void extract_movement(struct Gestures *gs, struct MTouch* mt) if (!GETBIT(mt->mem.pointing, i)) continue; if (abs(mt->mem.dx[i]) > xcut || - abs(mt->mem.dy[i]) > ycut) { + abs(mt->mem.dy[i]) > ycut) SETBIT(mt->mem.moving, i); - mt->mem.nmove++; - } } /* accumulate all movement during delay */ - if (mt->mem.nmove && mt->state.evtime >= mt->mem.move_time) { + if (mt->mem.moving && mt->state.evtime >= mt->mem.move_time) { + int nmove = bitcount(mt->mem.moving); 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 /= mt->mem.nmove; - gs->dy /= mt->mem.nmove; + gs->dx /= nmove; + gs->dy /= nmove; memset(mt->mem.dx, 0, sizeof(mt->mem.dx)); memset(mt->mem.dy, 0, sizeof(mt->mem.dy)); } @@ -153,10 +147,11 @@ static void extract_movement(struct Gestures *gs, struct MTouch* mt) static void extract_buttons(struct Gestures *gs, struct MTouch* mt) { unsigned btdata = mt->state.button & BITONES(DIM_BUTTON); + int npoint = bitcount(mt->mem.pointing); if (mt->state.button == BITMASK(MT_BUTTON_LEFT)) { - if (mt->mem.npoint == 2) + if (npoint == 2) btdata = BITMASK(MT_BUTTON_RIGHT); - if (mt->mem.npoint == 3) + if (npoint == 3) btdata = BITMASK(MT_BUTTON_MIDDLE); } if (mt->state.button != mt->prev_state.button) { @@ -170,18 +165,19 @@ static void extract_buttons(struct Gestures *gs, struct MTouch* mt) static void extract_type(struct Gestures *gs, struct MTouch* mt) { + int npoint = bitcount(mt->mem.pointing); if (gs->btmask) SETBIT(gs->type, GS_BUTTON); if (gs->dx || gs->dy) { - if (mt->mem.npoint == 1) + if (npoint == 1) SETBIT(gs->type, GS_MOVE); - if (mt->mem.npoint == 2) { + if (npoint == 2) { if (gs->dx) SETBIT(gs->type, GS_HSCROLL); if (gs->dy) SETBIT(gs->type, GS_VSCROLL); } - if (mt->mem.npoint == 3) { + if (npoint == 3) { if (gs->dx) SETBIT(gs->type, GS_HSWIPE); if (gs->dy) diff --git a/src/memory.c b/src/memory.c index 15b483c..0e2edba 100644 --- a/src/memory.c +++ b/src/memory.c @@ -32,8 +32,6 @@ void output_memory(const struct Memory *m) xf86Msg(X_INFO, "btdata: %04x\n", m->btdata); xf86Msg(X_INFO, "pointing: %04x\n", m->pointing); xf86Msg(X_INFO, "moving: %04x\n", m->moving); - xf86Msg(X_INFO, "npoint: %d\n", m->npoint); xf86Msg(X_INFO, "ybar: %d\n", m->ybar); xf86Msg(X_INFO, "move_time: %lld\n", m->move_time); - xf86Msg(X_INFO, "nmove: %d\n", m->nmove); } diff --git a/src/memory.h b/src/memory.h index 81cdae0..23d2ce6 100644 --- a/src/memory.h +++ b/src/memory.h @@ -26,9 +26,9 @@ struct Memory { unsigned btdata, pointing, moving; - int npoint, ybar; + int ybar; mstime_t move_time; - int dx[DIM_FINGER], dy[DIM_FINGER], nmove; + int dx[DIM_FINGER], dy[DIM_FINGER]; diff --git a/src/test.c b/src/test.c index e9b8ce3..fc16201 100644 --- a/src/test.c +++ b/src/test.c @@ -19,10 +19,23 @@ * **************************************************************************/ +#include "common.h" #include #include +static void print_bitfield(unsigned m) +{ + int i; + + printf("%d\n", m); + foreach_bit(i, m) + printf("%d %d\n", i, 1 << i); +} + int main(int argc, char *argv[]) { + print_bitfield(5); + print_bitfield(126); + print_bitfield(0); return 0; } -- cgit v1.2.3