aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2010-06-16 02:30:41 +0200
committerHenrik Rydberg <rydberg@euromail.se>2010-06-16 02:30:41 +0200
commit8dff8642c43a473713d48533974d9c7883bbc5c1 (patch)
treeea8513c76d38f2612a1202d30abf0f2e768f204c /src
parent1c73d171b2814bf2809aa48c2d4b683a064a4f7e (diff)
downloadxorg-input-kobomultitouch-8dff8642c43a473713d48533974d9c7883bbc5c1.tar.gz
xorg-input-kobomultitouch-8dff8642c43a473713d48533974d9c7883bbc5c1.tar.bz2
xorg-input-kobomultitouch-8dff8642c43a473713d48533974d9c7883bbc5c1.zip
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')
-rw-r--r--src/gestures.c26
-rw-r--r--src/hwstate.c156
-rw-r--r--src/memory.c33
-rw-r--r--src/mtouch.c20
-rw-r--r--src/mtstate.c45
-rw-r--r--src/test.c45
6 files changed, 182 insertions, 143 deletions
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 <common.h>
+#include <gestures.h>
+#include <fcntl.h>
#include <xbypass.h>
-#include <stdio.h>
-#include <time.h>
-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 <mtdev>\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;
}