diff options
| author | Henrik Rydberg <rydberg@euromail.se> | 2010-06-16 02:30:41 +0200 |
|---|---|---|
| committer | Henrik Rydberg <rydberg@euromail.se> | 2010-06-16 02:30:41 +0200 |
| commit | 8dff8642c43a473713d48533974d9c7883bbc5c1 (patch) | |
| tree | ea8513c76d38f2612a1202d30abf0f2e768f204c /src/hwstate.c | |
| parent | 1c73d171b2814bf2809aa48c2d4b683a064a4f7e (diff) | |
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 <rydberg@euromail.se>
Diffstat (limited to 'src/hwstate.c')
| -rw-r--r-- | src/hwstate.c | 156 |
1 files changed, 83 insertions, 73 deletions
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 @@ | |||
| 21 | 21 | ||
| 22 | #include "hwstate.h" | 22 | #include "hwstate.h" |
| 23 | 23 | ||
| 24 | #define NOTOUCH(hw, c) ((hw)->touch_major == 0 && (c)->has_abs[BIT_TOUCH_MAJOR]) | 24 | void init_hwstate(struct HWState *s, const struct Capabilities *caps) |
| 25 | |||
| 26 | void init_hwstate(struct HWState *s) | ||
| 27 | { | 25 | { |
| 26 | int i; | ||
| 28 | memset(s, 0, sizeof(struct HWState)); | 27 | memset(s, 0, sizeof(struct HWState)); |
| 28 | for (i = 0; i < DIM_FINGER; i++) | ||
| 29 | s->data[i].tracking_id = caps->nullid; | ||
| 29 | } | 30 | } |
| 30 | 31 | ||
| 31 | /* Dmitry Torokhov's code from kernel/driver/input/input.c */ | 32 | static void finish_packet(struct HWState *s, const struct Capabilities *caps, |
| 32 | static int defuzz(int value, int old_val, int fuzz) | 33 | const struct input_event *syn) |
| 33 | { | 34 | { |
| 34 | if (fuzz) { | 35 | static const mstime_t ms = 1000; |
| 35 | if (value > old_val - fuzz / 2 && value < old_val + fuzz / 2) | 36 | int i; |
| 36 | return old_val; | 37 | foreach_bit(i, s->used) { |
| 37 | 38 | if (!caps->has_abs[BIT_TOUCH_MINOR]) | |
| 38 | if (value > old_val - fuzz && value < old_val + fuzz) | 39 | s->data[i].touch_minor = s->data[i].touch_major; |
| 39 | return (old_val * 3 + value) / 4; | 40 | if (!caps->has_abs[BIT_WIDTH_MINOR]) |
| 40 | 41 | s->data[i].width_minor = s->data[i].width_major; | |
| 41 | if (value > old_val - fuzz * 2 && value < old_val + fuzz * 2) | ||
| 42 | return (old_val + value) / 2; | ||
| 43 | } | 42 | } |
| 44 | 43 | s->evtime = syn->time.tv_usec / ms + syn->time.tv_sec * ms; | |
| 45 | return value; | ||
| 46 | } | 44 | } |
| 47 | 45 | ||
| 48 | static void set_finger(struct FingerState *fs, | 46 | static int read_event(struct HWState *s, const struct Capabilities *caps, |
| 49 | const struct FingerData *hw, int id, | 47 | const struct input_event *ev) |
| 50 | const struct Capabilities *caps) | ||
| 51 | { | 48 | { |
| 52 | int x = defuzz(hw->position_x, fs->hw.position_x, caps->abs[BIT_POSITION_X].fuzz); | 49 | switch (ev->type) { |
| 53 | int y = defuzz(hw->position_y, fs->hw.position_y, caps->abs[BIT_POSITION_Y].fuzz); | 50 | case EV_SYN: |
| 54 | int tj = defuzz(hw->touch_major, fs->hw.touch_major, caps->abs[BIT_TOUCH_MAJOR].fuzz); | 51 | switch (ev->code) { |
| 55 | int tn = defuzz(hw->touch_minor, fs->hw.touch_minor, caps->abs[BIT_TOUCH_MAJOR].fuzz); | 52 | case SYN_REPORT: |
| 56 | int wj = defuzz(hw->width_major, fs->hw.width_major, caps->abs[BIT_TOUCH_MAJOR].fuzz); | 53 | finish_packet(s, caps, ev); |
| 57 | int wn = defuzz(hw->width_minor, fs->hw.width_minor, caps->abs[BIT_TOUCH_MAJOR].fuzz); | 54 | return 1; |
| 58 | fs->id = id; | 55 | } |
| 59 | fs->hw = *hw; | 56 | break; |
| 60 | fs->hw.position_x = x; | 57 | case EV_KEY: |
| 61 | fs->hw.position_y = y; | 58 | switch (ev->code) { |
| 62 | if (hw->touch_major) { | 59 | case BTN_LEFT: |
| 63 | fs->hw.touch_major = tj; | 60 | MODBIT(s->button, MT_BUTTON_LEFT, ev->value); |
| 64 | fs->hw.touch_minor = tn; | 61 | break; |
| 62 | case BTN_MIDDLE: | ||
| 63 | MODBIT(s->button, MT_BUTTON_MIDDLE, ev->value); | ||
| 64 | break; | ||
| 65 | case BTN_RIGHT: | ||
| 66 | MODBIT(s->button, MT_BUTTON_RIGHT, ev->value); | ||
| 67 | break; | ||
| 68 | } | ||
| 69 | break; | ||
| 70 | case EV_ABS: | ||
| 71 | switch (ev->code) { | ||
| 72 | case ABS_MT_SLOT: | ||
| 73 | if (ev->value >= 0 && ev->value < DIM_FINGER) | ||
| 74 | s->slot = ev->value; | ||
| 75 | break; | ||
| 76 | case ABS_MT_TOUCH_MAJOR: | ||
| 77 | s->data[s->slot].touch_major = ev->value; | ||
| 78 | break; | ||
| 79 | case ABS_MT_TOUCH_MINOR: | ||
| 80 | s->data[s->slot].touch_minor = ev->value; | ||
| 81 | break; | ||
| 82 | case ABS_MT_WIDTH_MAJOR: | ||
| 83 | s->data[s->slot].width_major = ev->value; | ||
| 84 | break; | ||
| 85 | case ABS_MT_WIDTH_MINOR: | ||
| 86 | s->data[s->slot].width_minor = ev->value; | ||
| 87 | break; | ||
| 88 | case ABS_MT_ORIENTATION: | ||
| 89 | s->data[s->slot].orientation = ev->value; | ||
| 90 | break; | ||
| 91 | case ABS_MT_PRESSURE: | ||
| 92 | s->data[s->slot].pressure = ev->value; | ||
| 93 | break; | ||
| 94 | case ABS_MT_POSITION_X: | ||
| 95 | s->data[s->slot].position_x = ev->value; | ||
| 96 | break; | ||
| 97 | case ABS_MT_POSITION_Y: | ||
| 98 | s->data[s->slot].position_y = ev->value; | ||
| 99 | break; | ||
| 100 | case ABS_MT_TRACKING_ID: | ||
| 101 | s->data[s->slot].tracking_id = ev->value; | ||
| 102 | MODBIT(s->used, s->slot, | ||
| 103 | ev->value != caps->nullid); | ||
| 104 | break; | ||
| 105 | } | ||
| 106 | break; | ||
| 65 | } | 107 | } |
| 66 | fs->hw.width_major = wj; | 108 | return 0; |
| 67 | fs->hw.width_minor = wn; | ||
| 68 | if (!caps->has_abs[BIT_TOUCH_MINOR]) | ||
| 69 | fs->hw.touch_minor = hw->touch_major; | ||
| 70 | if (!caps->has_abs[BIT_WIDTH_MINOR]) | ||
| 71 | fs->hw.width_minor = hw->width_major; | ||
| 72 | } | 109 | } |
| 73 | 110 | ||
| 74 | void modify_hwstate(struct HWState *s, | 111 | int modify_hwstate(struct HWState *s, struct MTDev *dev, |
| 75 | const struct HWData *hw, | 112 | const struct Capabilities *caps) |
| 76 | const struct Capabilities *caps) | ||
| 77 | { | 113 | { |
| 78 | int A[DIM2_FINGER], *row; | 114 | struct input_event ev; |
| 79 | int sid[DIM_FINGER], hw2s[DIM_FINGER]; | 115 | while (!mtdev_empty(dev)) { |
| 80 | int id, i, j; | 116 | mtdev_pop(dev, &ev); |
| 81 | 117 | if (read_event(s, caps, &ev)) | |
| 82 | /* setup distance matrix for finger id matching */ | 118 | return 1; |
| 83 | for (j = 0; j < s->nfinger; j++) { | ||
| 84 | sid[j] = s->finger[j].id; | ||
| 85 | if (NOTOUCH(&s->finger[j].hw, caps)) | ||
| 86 | sid[j] = 0; | ||
| 87 | row = A + hw->nfinger * j; | ||
| 88 | for (i = 0; i < hw->nfinger; i++) | ||
| 89 | row[i] = finger_dist2(&hw->finger[i], &s->finger[j].hw); | ||
| 90 | } | 119 | } |
| 91 | 120 | return 0; | |
| 92 | match_fingers(hw2s, A, hw->nfinger, s->nfinger); | ||
| 93 | |||
| 94 | /* update matched fingers and create new ones */ | ||
| 95 | for (i = 0; i < hw->nfinger; i++) { | ||
| 96 | j = hw2s[i]; | ||
| 97 | id = j >= 0 ? sid[j] : 0; | ||
| 98 | if (!NOTOUCH(&hw->finger[i], caps)) | ||
| 99 | while (!id) | ||
| 100 | id = ++s->lastid; | ||
| 101 | set_finger(&s->finger[i], &hw->finger[i], id, caps); | ||
| 102 | } | ||
| 103 | |||
| 104 | /* clear remaining finger ids */ | ||
| 105 | for (i = hw->nfinger; i < s->nfinger; i++) | ||
| 106 | s->finger[i].id = 0; | ||
| 107 | |||
| 108 | s->button = hw->button; | ||
| 109 | s->nfinger = hw->nfinger; | ||
| 110 | s->evtime = hw->evtime; | ||
| 111 | } | 121 | } |
