From 8dff8642c43a473713d48533974d9c7883bbc5c1 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Wed, 16 Jun 2010 02:30:41 +0200 Subject: refactor: Replace hwdata by mtdev This patch makes the switch, from using hwdata and the associated type A parser, to using mtdev and the associated type B parser. A command-line gesture test program is included. Signed-off-by: Henrik Rydberg --- src/gestures.c | 26 +++++++++- src/hwstate.c | 156 ++++++++++++++++++++++++++++++--------------------------- src/memory.c | 33 ++++++------ src/mtouch.c | 20 +++----- src/mtstate.c | 45 +++++++---------- src/test.c | 45 ++++++++++++----- 6 files changed, 182 insertions(+), 143 deletions(-) (limited to 'src') diff --git a/src/gestures.c b/src/gestures.c index 0cc2e0b..663f1a4 100644 --- a/src/gestures.c +++ b/src/gestures.c @@ -81,8 +81,8 @@ static void extract_movement(struct Gestures *gs, struct MTouch* mt) return; foreach_bit(i, mt->mem.moving) { - xp[i] = mt->state.finger[i].hw.position_x - xpos; - yp[i] = mt->state.finger[i].hw.position_y - ypos; + xp[i] = mt->state.finger[i].position_x - xpos; + yp[i] = mt->state.finger[i].position_y - ypos; xm[i] = mt->mem.dx[i]; ym[i] = mt->mem.dy[i]; mt->mem.dx[i] = 0; @@ -178,3 +178,25 @@ void extract_gestures(struct Gestures *gs, struct MTouch* mt) mt->prev_state = mt->state; } + +void output_gesture(const struct Gestures *gs) +{ + int i; + foreach_bit(i, gs->btmask) + xf86Msg(X_INFO, "button bit: %d %d\n", + i, GETBIT(gs->btdata, i)); + if (GETBIT(gs->type, GS_MOVE)) + xf86Msg(X_INFO, "motion: %d %d\n", gs->dx, gs->dy); + if (GETBIT(gs->type, GS_VSCROLL)) + xf86Msg(X_INFO, "vscroll: %d\n", gs->dy); + if (GETBIT(gs->type, GS_HSCROLL)) + xf86Msg(X_INFO, "hscroll: %d\n", gs->dx); + if (GETBIT(gs->type, GS_VSWIPE)) + xf86Msg(X_INFO, "vswipe: %d\n", gs->dy); + if (GETBIT(gs->type, GS_HSWIPE)) + xf86Msg(X_INFO, "hswipe: %d\n", gs->dx); + if (GETBIT(gs->type, GS_SCALE)) + xf86Msg(X_INFO, "scale: %d\n", gs->scale); + if (GETBIT(gs->type, GS_ROTATE)) + xf86Msg(X_INFO, "rotate: %d\n", gs->rot); +} diff --git a/src/hwstate.c b/src/hwstate.c index 032351c..f4f2972 100644 --- a/src/hwstate.c +++ b/src/hwstate.c @@ -21,91 +21,101 @@ #include "hwstate.h" -#define NOTOUCH(hw, c) ((hw)->touch_major == 0 && (c)->has_abs[BIT_TOUCH_MAJOR]) - -void init_hwstate(struct HWState *s) +void init_hwstate(struct HWState *s, const struct Capabilities *caps) { + int i; memset(s, 0, sizeof(struct HWState)); + for (i = 0; i < DIM_FINGER; i++) + s->data[i].tracking_id = caps->nullid; } -/* Dmitry Torokhov's code from kernel/driver/input/input.c */ -static int defuzz(int value, int old_val, int fuzz) +static void finish_packet(struct HWState *s, const struct Capabilities *caps, + const struct input_event *syn) { - if (fuzz) { - if (value > old_val - fuzz / 2 && value < old_val + fuzz / 2) - return old_val; - - if (value > old_val - fuzz && value < old_val + fuzz) - return (old_val * 3 + value) / 4; - - if (value > old_val - fuzz * 2 && value < old_val + fuzz * 2) - return (old_val + value) / 2; + static const mstime_t ms = 1000; + int i; + foreach_bit(i, s->used) { + if (!caps->has_abs[BIT_TOUCH_MINOR]) + s->data[i].touch_minor = s->data[i].touch_major; + if (!caps->has_abs[BIT_WIDTH_MINOR]) + s->data[i].width_minor = s->data[i].width_major; } - - return value; + s->evtime = syn->time.tv_usec / ms + syn->time.tv_sec * ms; } -static void set_finger(struct FingerState *fs, - const struct FingerData *hw, int id, - const struct Capabilities *caps) +static int read_event(struct HWState *s, const struct Capabilities *caps, + const struct input_event *ev) { - int x = defuzz(hw->position_x, fs->hw.position_x, caps->abs[BIT_POSITION_X].fuzz); - int y = defuzz(hw->position_y, fs->hw.position_y, caps->abs[BIT_POSITION_Y].fuzz); - int tj = defuzz(hw->touch_major, fs->hw.touch_major, caps->abs[BIT_TOUCH_MAJOR].fuzz); - int tn = defuzz(hw->touch_minor, fs->hw.touch_minor, caps->abs[BIT_TOUCH_MAJOR].fuzz); - int wj = defuzz(hw->width_major, fs->hw.width_major, caps->abs[BIT_TOUCH_MAJOR].fuzz); - int wn = defuzz(hw->width_minor, fs->hw.width_minor, caps->abs[BIT_TOUCH_MAJOR].fuzz); - fs->id = id; - fs->hw = *hw; - fs->hw.position_x = x; - fs->hw.position_y = y; - if (hw->touch_major) { - fs->hw.touch_major = tj; - fs->hw.touch_minor = tn; + switch (ev->type) { + case EV_SYN: + switch (ev->code) { + case SYN_REPORT: + finish_packet(s, caps, ev); + return 1; + } + break; + case EV_KEY: + switch (ev->code) { + case BTN_LEFT: + MODBIT(s->button, MT_BUTTON_LEFT, ev->value); + break; + case BTN_MIDDLE: + MODBIT(s->button, MT_BUTTON_MIDDLE, ev->value); + break; + case BTN_RIGHT: + MODBIT(s->button, MT_BUTTON_RIGHT, ev->value); + break; + } + break; + case EV_ABS: + switch (ev->code) { + case ABS_MT_SLOT: + if (ev->value >= 0 && ev->value < DIM_FINGER) + s->slot = ev->value; + break; + case ABS_MT_TOUCH_MAJOR: + s->data[s->slot].touch_major = ev->value; + break; + case ABS_MT_TOUCH_MINOR: + s->data[s->slot].touch_minor = ev->value; + break; + case ABS_MT_WIDTH_MAJOR: + s->data[s->slot].width_major = ev->value; + break; + case ABS_MT_WIDTH_MINOR: + s->data[s->slot].width_minor = ev->value; + break; + case ABS_MT_ORIENTATION: + s->data[s->slot].orientation = ev->value; + break; + case ABS_MT_PRESSURE: + s->data[s->slot].pressure = ev->value; + break; + case ABS_MT_POSITION_X: + s->data[s->slot].position_x = ev->value; + break; + case ABS_MT_POSITION_Y: + s->data[s->slot].position_y = ev->value; + break; + case ABS_MT_TRACKING_ID: + s->data[s->slot].tracking_id = ev->value; + MODBIT(s->used, s->slot, + ev->value != caps->nullid); + break; + } + break; } - fs->hw.width_major = wj; - fs->hw.width_minor = wn; - if (!caps->has_abs[BIT_TOUCH_MINOR]) - fs->hw.touch_minor = hw->touch_major; - if (!caps->has_abs[BIT_WIDTH_MINOR]) - fs->hw.width_minor = hw->width_major; + return 0; } -void modify_hwstate(struct HWState *s, - const struct HWData *hw, - const struct Capabilities *caps) +int modify_hwstate(struct HWState *s, struct MTDev *dev, + const struct Capabilities *caps) { - int A[DIM2_FINGER], *row; - int sid[DIM_FINGER], hw2s[DIM_FINGER]; - int id, i, j; - - /* setup distance matrix for finger id matching */ - for (j = 0; j < s->nfinger; j++) { - sid[j] = s->finger[j].id; - if (NOTOUCH(&s->finger[j].hw, caps)) - sid[j] = 0; - row = A + hw->nfinger * j; - for (i = 0; i < hw->nfinger; i++) - row[i] = finger_dist2(&hw->finger[i], &s->finger[j].hw); + struct input_event ev; + while (!mtdev_empty(dev)) { + mtdev_pop(dev, &ev); + if (read_event(s, caps, &ev)) + return 1; } - - match_fingers(hw2s, A, hw->nfinger, s->nfinger); - - /* update matched fingers and create new ones */ - for (i = 0; i < hw->nfinger; i++) { - j = hw2s[i]; - id = j >= 0 ? sid[j] : 0; - if (!NOTOUCH(&hw->finger[i], caps)) - while (!id) - id = ++s->lastid; - set_finger(&s->finger[i], &hw->finger[i], id, caps); - } - - /* clear remaining finger ids */ - for (i = hw->nfinger; i < s->nfinger; i++) - s->finger[i].id = 0; - - s->button = hw->button; - s->nfinger = hw->nfinger; - s->evtime = hw->evtime; + return 0; } diff --git a/src/memory.c b/src/memory.c index 4cfb7da..748aa07 100644 --- a/src/memory.c +++ b/src/memory.c @@ -32,13 +32,15 @@ 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) +static inline int dxval(const struct FingerState *a, + const struct FingerState *b) { - return a->hw.position_x - b->hw.position_x; + return a->position_x - b->position_x; } -static inline int dyval(const struct MTFinger *a, const struct MTFinger *b) +static inline int dyval(const struct FingerState *a, + const struct FingerState *b) { - return a->hw.position_y - b->hw.position_y; + return a->position_y - b->position_y; } void init_memory(struct Memory *mem) @@ -60,20 +62,18 @@ static void update_configuration(struct Memory *m, const struct MTState *prev_state, const struct MTState *state) { - const struct MTFinger *f = state->finger; + const struct FingerState *f = state->finger; bitmask_t fingers = BITONES(state->nfinger); int i; m->added = 0; foreach_bit(i, fingers) - if (!find_finger(prev_state, f[i].id)) + if (!find_finger(prev_state, f[i].tracking_id)) SETBIT(m->added, i); m->same = m->fingers == fingers && m->added == 0; m->fingers = fingers; if (!m->same) m->thumb = 0; - foreach_bit(i, fingers) - if (f[i].thumb) - SETBIT(m->thumb, i); + m->thumb |= state->thumb; } /** @@ -90,8 +90,9 @@ static void update_pointers(struct Memory *m, const struct MTState *state, const struct Capabilities *caps) { - const struct MTFinger *f = state->finger; + const struct FingerState *f = state->finger; int yclick = caps->abs[BIT_POSITION_Y].maximum - CLICK_AREA(caps); + int i; if (state->nfinger < 2) { @@ -102,7 +103,7 @@ static void update_pointers(struct Memory *m, if (m->same) { foreach_bit(i, m->fingers & ~m->pointing) { - if (f[i].hw.position_y <= m->ybar) { + if (f[i].position_y <= m->ybar) { m->pointing = m->fingers; return; } @@ -113,10 +114,10 @@ static void update_pointers(struct Memory *m, m->pointing = 0; m->ybar = yclick; foreach_bit(i, m->fingers) { - if (f[i].hw.position_y > yclick) + if (f[i].position_y > yclick) continue; - if (!m->pointing || f[i].hw.position_y > m->ybar) - m->ybar = f[i].hw.position_y; + if (!m->pointing || f[i].position_y > m->ybar) + m->ybar = f[i].position_y; SETBIT(m->pointing, i); } @@ -140,7 +141,7 @@ static void update_movement(struct Memory *m, const struct MTState *state, const struct Capabilities *caps) { - const struct MTFinger *prev, *f = state->finger; + const struct FingerState *prev, *f = state->finger; int i, xcut, ycut, xmax = 0, ymax = 0; m->moving = 0; @@ -167,7 +168,7 @@ static void update_movement(struct Memory *m, foreach_bit(i, m->pointing) { int dx, dy; - prev = find_finger(prev_state, f[i].id); + prev = find_finger(prev_state, f[i].tracking_id); dx = dxval(&f[i], prev); dy = dyval(&f[i], prev); m->dx[i] += dx; diff --git a/src/mtouch.c b/src/mtouch.c index ad077b7..959783a 100644 --- a/src/mtouch.c +++ b/src/mtouch.c @@ -33,9 +33,9 @@ int configure_mtouch(struct MTouch *mt, int fd) int open_mtouch(struct MTouch *mt, int fd) { int rc; + mtdev_init(&mt->dev, &mt->caps); init_iobuf(&mt->buf); - init_hwdata(&mt->hw); - init_hwstate(&mt->hs); + init_hwstate(&mt->hs, &mt->caps); init_mtstate(&mt->prev_state); init_mtstate(&mt->state); init_memory(&mt->mem); @@ -50,18 +50,11 @@ int close_mtouch(struct MTouch *mt, int fd) return rc; } -int read_synchronized_event(struct MTouch *mt, int fd) +int parse_event(struct MTouch *mt, const struct input_event *ev) { - const struct input_event *ev; - while (ev = get_iobuf_event(&mt->buf, fd)) - if (read_hwdata(&mt->hw, ev)) - return 1; - return 0; -} - -void parse_event(struct MTouch *mt) -{ - modify_hwstate(&mt->hs, &mt->hw, &mt->caps); + mtdev_push(&mt->dev, &mt->caps, ev); + if (!modify_hwstate(&mt->hs, &mt->dev, &mt->caps)) + return 0; extract_mtstate(&mt->state, &mt->hs, &mt->caps); #if 0 output_mtstate(&mt->state); @@ -70,4 +63,5 @@ void parse_event(struct MTouch *mt) #if 0 output_memory(&mt->mem); #endif + return 1; } diff --git a/src/mtstate.c b/src/mtstate.c index 2403765..7a8ef19 100644 --- a/src/mtstate.c +++ b/src/mtstate.c @@ -34,7 +34,7 @@ void init_mtstate(struct MTState *s) memset(s, 0, sizeof(struct MTState)); } -static int touching_finger(const struct FingerData *hw, +static int touching_finger(const struct FingerState *hw, const struct Capabilities *caps) { if (caps->has_abs[BIT_TOUCH_MAJOR] && caps->has_abs[BIT_WIDTH_MAJOR]) @@ -52,8 +52,8 @@ static int touching_finger(const struct FingerData *hw, * by all three values touch_major, width_minor, and trackpad size. * */ -static int thumb_finger(const struct FingerData *hw, - const struct Capabilities *caps) +static int is_thumb(const struct FingerState *hw, + const struct Capabilities *caps) { if (!caps->has_abs[BIT_TOUCH_MAJOR] || !caps->has_abs[BIT_TOUCH_MINOR] || @@ -66,26 +66,17 @@ static int thumb_finger(const struct FingerData *hw, hw->width_major > THUMB_WIDTH_SIZE(hw, caps); } -static int set_finger(struct MTFinger *f, - const struct FingerState *fs, - const struct Capabilities *caps) -{ - f->hw = fs->hw; - f->id = fs->id; - f->thumb = thumb_finger(&fs->hw, caps); -} - void extract_mtstate(struct MTState *s, const struct HWState *hs, const struct Capabilities *caps) { int i; - s->nfinger = 0; - for (i = 0; i < hs->nfinger; i++) { - if (!touching_finger(&hs->finger[i].hw, caps)) + foreach_bit(i, hs->used) { + if (!touching_finger(&hs->data[i], caps)) continue; - set_finger(&s->finger[s->nfinger], &hs->finger[i], caps); + s->finger[s->nfinger] = hs->data[i]; + MODBIT(s->thumb, s->nfinger, is_thumb(&hs->data[i], caps)); s->nfinger++; } @@ -93,12 +84,12 @@ void extract_mtstate(struct MTState *s, s->evtime = hs->evtime; } -const struct MTFinger *find_finger(const struct MTState *s, int id) +const struct FingerState *find_finger(const struct MTState *s, int id) { int i; for (i = 0; i < s->nfinger; i++) - if (s->finger[i].id == id) + if (s->finger[i].tracking_id == id) return s->finger + i; return NULL; @@ -119,14 +110,14 @@ void output_mtstate(const struct MTState *s) xf86Msg(X_INFO, " %+02d %+05d:%+05d +%05d:%+05d " "%+06d %+06d %+05d:%+05d\n", - s->finger[i].id, - s->finger[i].hw.touch_major, - s->finger[i].hw.touch_minor, - s->finger[i].hw.width_major, - s->finger[i].hw.width_minor, - s->finger[i].hw.orientation, - s->finger[i].hw.pressure, - s->finger[i].hw.position_x, - s->finger[i].hw.position_y); + s->finger[i].tracking_id, + s->finger[i].touch_major, + s->finger[i].touch_minor, + s->finger[i].width_major, + s->finger[i].width_minor, + s->finger[i].orientation, + s->finger[i].pressure, + s->finger[i].position_x, + s->finger[i].position_y); } } diff --git a/src/test.c b/src/test.c index 7d983a0..0088cdd 100644 --- a/src/test.c +++ b/src/test.c @@ -19,24 +19,45 @@ * **************************************************************************/ -#include +#include +#include #include -#include -#include -static void print_bitfield(unsigned m) +static void loop_device(int fd) { - int i; - - printf("%d\n", m); - foreach_bit(i, m) - printf("%d %d\n", i, 1 << i); + struct Gestures gs; + struct MTouch mt; + const struct input_event *ev; + struct input_event event; + if (configure_mtouch(&mt, fd)) { + fprintf(stderr, "error: could not configure device\n"); + return; + } + if (open_mtouch(&mt, fd)) { + fprintf(stderr, "error: could not open device\n"); + return; + } + while (ev = get_iobuf_event(&mt.buf, fd)) { + if (parse_event(&mt, ev)) { + extract_gestures(&gs, &mt); + output_gesture(&gs); + } + } + close_mtouch(&mt, fd); } int main(int argc, char *argv[]) { - print_bitfield(5); - print_bitfield(126); - print_bitfield(0); + if (argc < 2) { + fprintf(stderr, "Usage: test \n"); + return -1; + } + int fd = open(argv[1], O_RDONLY); + if (fd < 0) { + fprintf(stderr, "error: could not open file\n"); + return -1; + } + loop_device(fd); + close(fd); return 0; } -- cgit v1.2.3