summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2010-10-12 15:38:43 +0200
committerHenrik Rydberg <rydberg@euromail.se>2010-10-12 15:38:43 +0200
commitacea9df3381825a634c000a574f58b4ca5293ee8 (patch)
tree3698bd55f137bc377f1b840e4fb5bf9e446e7250 /src
parent7380af2c93dc83f4f09e293717d46eadf7799e89 (diff)
Same version, but using the mtdev library.
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'src')
-rw-r--r--src/capabilities.c171
-rw-r--r--src/hwstate.c24
-rw-r--r--src/memory.c4
-rw-r--r--src/mtouch.c32
-rw-r--r--src/mtstate.c14
-rw-r--r--src/test.c4
6 files changed, 203 insertions, 46 deletions
diff --git a/src/capabilities.c b/src/capabilities.c
new file mode 100644
index 0000000..0d11669
--- /dev/null
+++ b/src/capabilities.c
@@ -0,0 +1,171 @@
+/***************************************************************************
+ *
+ * Multitouch X driver
+ * Copyright (C) 2008 Henrik Rydberg <rydberg@euromail.se>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#include "capabilities.h"
+
+#define SETABS(c, x, map, key, fd) \
+ (c->has_##x = getbit(map, key) && getabs(&c->x, key, fd))
+
+#define ADDCAP(s, c, x) strcat(s, c->has_##x ? " " #x : "")
+
+static const int SN_COORD = 250; /* coordinate signal-to-noise ratio */
+static const int SN_WIDTH = 100; /* width signal-to-noise ratio */
+static const int SN_ORIENT = 10; /* orientation signal-to-noise ratio */
+
+static const int bits_per_long = 8 * sizeof(long);
+
+static inline int nlongs(int nbit)
+{
+ return (nbit + bits_per_long - 1) / bits_per_long;
+}
+
+static inline int getbit(const unsigned long *map, int key)
+{
+ return (map[key / bits_per_long] >> (key % bits_per_long)) & 0x01;
+}
+
+static int getabs(struct input_absinfo *abs, int key, int fd)
+{
+ int rc;
+ SYSCALL(rc = ioctl(fd, EVIOCGABS(key), abs));
+ return rc >= 0;
+}
+
+static int has_mt_data(const struct Capabilities *cap)
+{
+ return cap->has_abs[MTDEV_POSITION_X] && cap->has_abs[MTDEV_POSITION_Y];
+}
+
+static int has_integrated_button(const struct Capabilities *cap)
+{
+ static const int bcm5974_vmask_ibt = 1;
+ if (strcmp(cap->devname, "bcm5974"))
+ return 0;
+ return cap->devid.version & bcm5974_vmask_ibt;
+}
+
+static void default_fuzz(struct Capabilities *cap, unsigned int code, int sn)
+{
+ int bit = mtdev_abs2mt(code);
+ if (cap->has_abs[bit] && cap->abs[bit].fuzz == 0)
+ cap->abs[bit].fuzz =
+ (cap->abs[bit].maximum - cap->abs[bit].minimum) / sn;
+}
+
+int read_capabilities(struct Capabilities *cap, int fd)
+{
+ unsigned long evbits[nlongs(EV_MAX)];
+ unsigned long absbits[nlongs(ABS_MAX)];
+ unsigned long keybits[nlongs(KEY_MAX)];
+ int rc, i;
+
+ memset(cap, 0, sizeof(struct Capabilities));
+
+ SYSCALL(rc = ioctl(fd, EVIOCGID, &cap->devid));
+ if (rc < 0)
+ return rc;
+ SYSCALL(rc = ioctl(fd, EVIOCGNAME(sizeof(cap->devname)), cap->devname));
+ if (rc < 0)
+ return rc;
+ SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_SYN, sizeof(evbits)), evbits));
+ if (rc < 0)
+ return rc;
+ SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits));
+ if (rc < 0)
+ return rc;
+ SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbits)), absbits));
+ if (rc < 0)
+ return rc;
+
+ cap->has_left = getbit(keybits, BTN_LEFT);
+ cap->has_middle = getbit(keybits, BTN_MIDDLE);
+ cap->has_right = getbit(keybits, BTN_RIGHT);
+
+ SETABS(cap, slot, absbits, ABS_MT_SLOT, fd);
+ for (i = 0; i < MT_ABS_SIZE; i++)
+ SETABS(cap, abs[i], absbits, mtdev_mt2abs(i), fd);
+
+ cap->has_mtdata = has_mt_data(cap);
+ cap->has_ibt = has_integrated_button(cap);
+
+ default_fuzz(cap, ABS_MT_POSITION_X, SN_COORD);
+ default_fuzz(cap, ABS_MT_POSITION_Y, SN_COORD);
+ default_fuzz(cap, ABS_MT_TOUCH_MAJOR, SN_WIDTH);
+ default_fuzz(cap, ABS_MT_TOUCH_MINOR, SN_WIDTH);
+ default_fuzz(cap, ABS_MT_WIDTH_MAJOR, SN_WIDTH);
+ default_fuzz(cap, ABS_MT_WIDTH_MINOR, SN_WIDTH);
+ default_fuzz(cap, ABS_MT_ORIENTATION, SN_ORIENT);
+
+ return 0;
+}
+
+int get_cap_xsize(const struct Capabilities *cap)
+{
+ const struct input_absinfo *x = &cap->abs[MTDEV_POSITION_X];
+ return x->maximum - x->minimum;
+}
+
+int get_cap_ysize(const struct Capabilities *cap)
+{
+ const struct input_absinfo *y = &cap->abs[MTDEV_POSITION_Y];
+ return y->maximum - y->minimum;
+}
+
+int get_cap_wsize(const struct Capabilities *cap)
+{
+ const struct input_absinfo *w = &cap->abs[MTDEV_TOUCH_MAJOR];
+ return w->maximum - w->minimum;
+}
+
+int get_cap_xmid(const struct Capabilities *cap)
+{
+ const struct input_absinfo *x = &cap->abs[MTDEV_POSITION_X];
+ return (x->maximum + x->minimum) >> 1;
+}
+
+int get_cap_ymid(const struct Capabilities *cap)
+{
+ const struct input_absinfo *y = &cap->abs[MTDEV_POSITION_Y];
+ return (y->maximum + y->minimum) >> 1;
+}
+
+void output_capabilities(const struct Capabilities *cap)
+{
+ char line[1024];
+ int i;
+ memset(line, 0, sizeof(line));
+ ADDCAP(line, cap, left);
+ ADDCAP(line, cap, middle);
+ ADDCAP(line, cap, right);
+ ADDCAP(line, cap, mtdata);
+ ADDCAP(line, cap, ibt);
+ xf86Msg(X_INFO, "multitouch: devname: %s\n", cap->devname);
+ xf86Msg(X_INFO, "multitouch: devid: %x %x %x\n",
+ cap->devid.vendor, cap->devid.product, cap->devid.version);
+ xf86Msg(X_INFO, "multitouch: caps:%s\n", line);
+ for (i = 0; i < MT_ABS_SIZE; i++) {
+ if (cap->has_abs[i])
+ xf86Msg(X_INFO, "multitouch: %d: min: %d max: %d\n",
+ i,
+ cap->abs[i].minimum,
+ cap->abs[i].maximum);
+ }
+}
diff --git a/src/hwstate.c b/src/hwstate.c
index 82a3a10..076efa1 100644
--- a/src/hwstate.c
+++ b/src/hwstate.c
@@ -26,7 +26,7 @@ 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;
+ s->data[i].tracking_id = MT_ID_NULL;
}
static void finish_packet(struct HWState *s, const struct Capabilities *caps,
@@ -35,16 +35,16 @@ static void finish_packet(struct HWState *s, const struct Capabilities *caps,
static const mstime_t ms = 1000;
int i;
foreach_bit(i, s->used) {
- if (!caps->has_abs[BIT_TOUCH_MINOR])
+ if (!caps->has_abs[MTDEV_TOUCH_MINOR])
s->data[i].touch_minor = s->data[i].touch_major;
- if (!caps->has_abs[BIT_WIDTH_MINOR])
+ if (!caps->has_abs[MTDEV_WIDTH_MINOR])
s->data[i].width_minor = s->data[i].width_major;
}
s->evtime = syn->time.tv_usec / ms + syn->time.tv_sec * ms;
}
-int hwstate_read(struct HWState *s, const struct Capabilities *caps,
- const struct input_event *ev)
+static int read_event(struct HWState *s, const struct Capabilities *caps,
+ const struct input_event *ev)
{
switch (ev->type) {
case EV_SYN:
@@ -99,11 +99,21 @@ int hwstate_read(struct HWState *s, const struct Capabilities *caps,
break;
case ABS_MT_TRACKING_ID:
s->data[s->slot].tracking_id = ev->value;
- MODBIT(s->used, s->slot,
- ev->value != caps->nullid);
+ MODBIT(s->used, s->slot, ev->value != MT_ID_NULL);
break;
}
break;
}
return 0;
}
+
+int modify_hwstate(struct HWState *s, struct mtdev *dev, int fd,
+ const struct Capabilities *caps)
+{
+ struct input_event ev;
+ int ret;
+ while ((ret = mtdev_get(dev, fd, &ev, 1)) > 0)
+ if (read_event(s, caps, &ev))
+ return 1;
+ return ret;
+}
diff --git a/src/memory.c b/src/memory.c
index 974a531..63134ca 100644
--- a/src/memory.c
+++ b/src/memory.c
@@ -119,13 +119,13 @@ static void update_pointers(struct Memory *m,
const struct Capabilities *caps)
{
const struct FingerState *f = state->finger;
- int yclick = caps->abs[BIT_POSITION_Y].maximum - CLICK_AREA(caps);
+ int yclick = caps->abs[MTDEV_POSITION_Y].maximum - CLICK_AREA(caps);
int i;
if (state->nfinger < 2) {
m->pointing = m->fingers;
- m->ybar = caps->abs[BIT_POSITION_Y].maximum;
+ m->ybar = caps->abs[MTDEV_POSITION_Y].maximum;
return;
}
diff --git a/src/mtouch.c b/src/mtouch.c
index f7a2710..e2d9572 100644
--- a/src/mtouch.c
+++ b/src/mtouch.c
@@ -34,8 +34,7 @@ int configure_mtouch(struct MTouch *mt, int fd)
int open_mtouch(struct MTouch *mt, int fd)
{
- mtdev_init(&mt->dev, &mt->caps);
- init_iobuf(&mt->buf);
+ mtdev_open(&mt->dev, fd);
init_hwstate(&mt->hs, &mt->caps);
init_mtstate(&mt->prev_state);
init_mtstate(&mt->state);
@@ -48,40 +47,19 @@ int open_mtouch(struct MTouch *mt, int fd)
return 0;
}
-
-int get_mtouch(struct MTouch *mt, int fd, struct input_event* ev, int ev_max)
-{
- const struct input_event *kev;
- int count = 0;
- while (count < ev_max) {
- while (mtdev_empty(&mt->dev)) {
- kev = get_iobuf_event(&mt->buf, fd);
- if (!kev)
- return count;
- mtdev_put(&mt->dev, &mt->caps, kev);
- }
- mtdev_get(&mt->dev, &ev[count++]);
- }
- return count;
-}
-
int close_mtouch(struct MTouch *mt, int fd)
{
if (use_grab) {
int rc;
SYSCALL(rc = ioctl(fd, EVIOCGRAB, (pointer)0));
}
- mtdev_destroy(&mt->dev);
+ mtdev_close(&mt->dev);
return 0;
}
int read_packet(struct MTouch *mt, int fd)
{
- struct input_event ev;
- int ret;
- while ((ret = get_mtouch(mt, fd, &ev, 1)) > 0)
- if (hwstate_read(&mt->hs, &mt->caps, &ev))
- break;
+ int ret = modify_hwstate(&mt->hs, &mt->dev, fd, &mt->caps);
if (ret <= 0)
return ret;
extract_mtstate(&mt->state, &mt->hs, &mt->caps);
@@ -97,7 +75,5 @@ int read_packet(struct MTouch *mt, int fd)
int has_delayed_gestures(struct MTouch *mt, int fd)
{
- return mt->mem.wait &&
- mtdev_empty(&mt->dev) &&
- poll_iobuf(&mt->buf, fd, mt->mem.wait) == 0;
+ return mt->mem.wait && mtdev_idle(&mt->dev, fd, mt->mem.wait);
}
diff --git a/src/mtstate.c b/src/mtstate.c
index 7a8ef19..4c893a2 100644
--- a/src/mtstate.c
+++ b/src/mtstate.c
@@ -22,7 +22,7 @@
#include "mtstate.h"
#define TOUCH_WIDTH(hw) (0.05 * hw->width_major)
-#define TOUCH_SCALE(caps) (0.05 * caps->abs[BIT_TOUCH_MAJOR].maximum)
+#define TOUCH_SCALE(caps) (0.05 * caps->abs[MTDEV_TOUCH_MAJOR].maximum)
#define THUMB_TOUCH(hw) (1.2 * hw->touch_minor)
#define THUMB_WIDTH_TOUCH(hw) (3 * hw->touch_major)
@@ -37,9 +37,9 @@ void init_mtstate(struct MTState *s)
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])
+ if (caps->has_abs[MTDEV_TOUCH_MAJOR] && caps->has_abs[MTDEV_WIDTH_MAJOR])
return hw->touch_major > TOUCH_WIDTH(hw);
- if (caps->has_abs[BIT_TOUCH_MAJOR])
+ if (caps->has_abs[MTDEV_TOUCH_MAJOR])
return hw->touch_major > TOUCH_SCALE(caps);
return 1;
}
@@ -55,10 +55,10 @@ static int touching_finger(const struct FingerState *hw,
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] ||
- !caps->has_abs[BIT_WIDTH_MAJOR] ||
- !caps->has_abs[BIT_WIDTH_MINOR])
+ if (!caps->has_abs[MTDEV_TOUCH_MAJOR] ||
+ !caps->has_abs[MTDEV_TOUCH_MINOR] ||
+ !caps->has_abs[MTDEV_WIDTH_MAJOR] ||
+ !caps->has_abs[MTDEV_WIDTH_MINOR])
return 0;
return hw->touch_major > THUMB_TOUCH(hw) &&
hw->width_major > THUMB_WIDTH_TOUCH(hw) &&
diff --git a/src/test.c b/src/test.c
index e4247d2..3a23db3 100644
--- a/src/test.c
+++ b/src/test.c
@@ -35,8 +35,8 @@ static void loop_device(int fd)
fprintf(stderr, "error: could not open device\n");
return;
}
- while (poll_iobuf(&mt.buf, fd, 5000)) {
- while (read_packet(&mt, fd) > 0) {
+ while (mtdev_pull(&mt.dev, fd, 1) > 0) {
+ if (parse_event(&mt)) {
extract_gestures(&gs, &mt);
output_gesture(&gs);
}