summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2010-12-22 18:29:00 +0100
committerHenrik Rydberg <rydberg@euromail.se>2010-12-22 18:29:00 +0100
commit56a77e68fb91eef928d8a95c50ae14508e37ae0f (patch)
tree51af9bb9dd508bca58e8b9416479e79f8bb7ee10
parent0e2ab3b5940e70493aaabdfe5e8da1c75db4db72 (diff)
downloadmtdev-git-56a77e68fb91eef928d8a95c50ae14508e37ae0f.tar.gz
Introduce a stable ABI
The current mtdev is not ABI stable, and the upcoming additions to the kernel api will break ABI. This patch starts the process of keeping binary compatibility with old programs, by moving the abi-specific parts under a special flag, MTDEV_NO_LEGACY_API, and makes sure the internal parts compiles with MTDEV_NO_LEGACY_API set. This way, older programs will still work, old programs will still compile, and new programs will be able to use the additions. Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
-rw-r--r--include/mtdev-mapping.h4
-rw-r--r--include/mtdev-plumbing.h37
-rw-r--r--include/mtdev.h117
-rw-r--r--src/Makefile.am2
-rw-r--r--src/caps.c163
-rw-r--r--src/common.h59
-rw-r--r--src/core.c126
-rw-r--r--src/state.h27
-rw-r--r--test/mtdev-mapgen.c32
9 files changed, 425 insertions, 142 deletions
diff --git a/include/mtdev-mapping.h b/include/mtdev-mapping.h
index 0e47970..0cdb39d 100644
--- a/include/mtdev-mapping.h
+++ b/include/mtdev-mapping.h
@@ -37,6 +37,8 @@ extern "C" {
#include <mtdev.h>
+#ifndef MTDEV_NO_LEGACY_API
+
#define MTDEV_TOUCH_MAJOR 0
#define MTDEV_TOUCH_MINOR 1
#define MTDEV_WIDTH_MAJOR 2
@@ -80,6 +82,8 @@ static inline unsigned int mtdev_mt2abs(unsigned int mtcode)
return mtdev_map_mt2abs[mtcode];
}
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/include/mtdev-plumbing.h b/include/mtdev-plumbing.h
index cadc1f7..21ca708 100644
--- a/include/mtdev-plumbing.h
+++ b/include/mtdev-plumbing.h
@@ -36,6 +36,15 @@ extern "C" {
#include <mtdev.h>
/**
+ * mtdev_new - allocate a new mtdev
+ *
+ * Allocate a new mtdev.
+ *
+ * Returns zero in case of memory allocation failure.
+ */
+struct mtdev *mtdev_new(void);
+
+/**
* mtdev_init - initialize mtdev converter
* @dev: the mtdev to initialize
*
@@ -46,6 +55,26 @@ extern "C" {
int mtdev_init(struct mtdev *dev);
/**
+ * mtdev_set_mt_event - set event type
+ * @dev: the mtdev in use
+ * @code: the ABS_MT code to set
+ * @value: boolean value
+ *
+ * Returns true if the given event code is present.
+ */
+void mtdev_set_mt_event(struct mtdev *dev, int code, int value);
+
+/**
+ * mtdev_set_abs_<property> - set abs event property
+ * @dev: the mtdev in use
+ * @code: the ABS_MT code to set
+ */
+void mtdev_set_abs_minimum(struct mtdev *dev, int code, int value);
+void mtdev_set_abs_maximum(struct mtdev *dev, int code, int value);
+void mtdev_set_abs_fuzz(struct mtdev *dev, int code, int value);
+void mtdev_set_abs_resolution(struct mtdev *dev, int code, int value);
+
+/**
* mtdev_configure - configure the mtdev converter
* @dev: the mtdev to configure
* @fd: file descriptor of the kernel device
@@ -106,6 +135,14 @@ int mtdev_empty(struct mtdev *dev);
*/
void mtdev_get_event(struct mtdev *dev, struct input_event* ev);
+/**
+ * mtdev_delete - free a previously allocated mtdev
+ *
+ * Frees the memory associated with the mtdev and invalidates the
+ * mtdev pointer.
+ */
+void mtdev_delete(struct mtdev *dev);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/mtdev.h b/include/mtdev.h
index 15bc53b..df74e95 100644
--- a/include/mtdev.h
+++ b/include/mtdev.h
@@ -62,59 +62,23 @@ extern "C" {
#ifndef ABS_MT_SLOT
#define ABS_MT_SLOT 0x2f /* MT slot being modified */
#endif
-#ifndef MT_SLOT_ABS_EVENTS
-#define MT_SLOT_ABS_EVENTS { \
- ABS_MT_TOUCH_MAJOR, \
- ABS_MT_TOUCH_MINOR, \
- ABS_MT_WIDTH_MAJOR, \
- ABS_MT_WIDTH_MINOR, \
- ABS_MT_ORIENTATION, \
- ABS_MT_POSITION_X, \
- ABS_MT_POSITION_Y, \
- ABS_MT_TOOL_TYPE, \
- ABS_MT_BLOB_ID, \
- ABS_MT_TRACKING_ID, \
- ABS_MT_PRESSURE, \
-}
-#endif
-
-#define MT_ABS_SIZE 11
#define MT_ID_NULL (-1)
#define MT_ID_MIN 0
#define MT_ID_MAX 65535
/**
- * struct mt_caps - protocol capabilities of kernel device
- * @has_mtdata: true if the device has MT capabilities
- * @has_slot: true if the device sends MT slots
- * @slot: slot event properties
- * @abs: ABS_MT event properties
- */
-struct mtdev_caps {
- int has_mtdata;
- int has_slot;
- int has_abs[MT_ABS_SIZE];
- struct input_absinfo slot;
- struct input_absinfo abs[MT_ABS_SIZE];
-};
-
-/**
- * struct mtdev - represents an input MT device
- * @caps: the kernel device protocol capabilities
- * @state: internal mtdev parsing state
+ * mtdev_new_open - create and open a new mtdev
+ * @fd: file descriptor of the kernel device
+ *
+ * Create a new mtdev and open the conversion.
*
- * The mtdev structure represents a kernel MT device type B, emitting
- * MT slot events. The events put into mtdev may be from any MT
- * device, specifically type A without contact tracking, type A with
- * contact tracking, or type B with contact tracking. See the kernel
- * documentation for further details.
+ * Returns zero in case of failure.
*
+ * This call combines the plumbing functions mtdev_new() and
+ * mtdev_open().
*/
-struct mtdev {
- struct mtdev_caps caps;
- struct mtdev_state *state;
-};
+struct mtdev *mtdev_new_open(int fd);
/**
* mtdev_open - open an mtdev converter
@@ -132,6 +96,27 @@ struct mtdev {
int mtdev_open(struct mtdev *dev, int fd);
/**
+ * mtdev_has_mt_event - check for event type
+ * @dev: the mtdev in use
+ * @code: the ABS_MT code to look for
+ *
+ * Returns true if the given event code is present.
+ */
+int mtdev_has_mt_event(const struct mtdev *dev, int code);
+
+/**
+ * mtdev_get_abs_<property> - get abs event property
+ * @dev: the mtdev in use
+ * @code: the ABS_MT code to look for
+ *
+ * Returns NULL if code is not a valid ABS_MT code.
+ */
+int mtdev_get_abs_minimum(const struct mtdev *dev, int code);
+int mtdev_get_abs_maximum(const struct mtdev *dev, int code);
+int mtdev_get_abs_fuzz(const struct mtdev *dev, int code);
+int mtdev_get_abs_resolution(const struct mtdev *dev, int code);
+
+/**
* mtdev_idle - check state of kernel device
* @dev: the mtdev in use
* @fd: file descriptor of the kernel device
@@ -173,6 +158,50 @@ int mtdev_get(struct mtdev *dev, int fd, struct input_event* ev, int ev_max);
*/
void mtdev_close(struct mtdev *dev);
+/**
+ * mtdev_close_delete - close conversion and delete mtdev
+ * @dev: the mtdev in use
+ *
+ * Flush pending buffers and deallocate all memory associated with
+ * mtdev. The device pointer is invalidated. This call combines the
+ * plumbing functions mtdev_close() and mtdev_delete().
+ */
+void mtdev_close_delete(struct mtdev *dev);
+
+#ifndef MTDEV_NO_LEGACY_API
+
+#define MT_ABS_SIZE 11
+#ifndef MT_SLOT_ABS_EVENTS
+#define MT_SLOT_ABS_EVENTS { \
+ ABS_MT_TOUCH_MAJOR, \
+ ABS_MT_TOUCH_MINOR, \
+ ABS_MT_WIDTH_MAJOR, \
+ ABS_MT_WIDTH_MINOR, \
+ ABS_MT_ORIENTATION, \
+ ABS_MT_POSITION_X, \
+ ABS_MT_POSITION_Y, \
+ ABS_MT_TOOL_TYPE, \
+ ABS_MT_BLOB_ID, \
+ ABS_MT_TRACKING_ID, \
+ ABS_MT_PRESSURE, \
+}
+#endif
+
+struct mtdev_caps {
+ int has_mtdata;
+ int has_slot;
+ int has_abs[MT_ABS_SIZE];
+ struct input_absinfo slot;
+ struct input_absinfo abs[MT_ABS_SIZE];
+};
+
+struct mtdev {
+ struct mtdev_caps caps;
+ struct mtdev_state *state;
+};
+
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/src/Makefile.am b/src/Makefile.am
index 1c22c33..16d388c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -16,7 +16,7 @@ libmtdev_la_SOURCES = \
match.c \
match_four.c
-AM_CFLAGS = $(CWARNFLAGS)
+AM_CFLAGS = $(CWARNFLAGS) #-DMTDEV_NO_LEGACY_ABI
INCLUDES = -I$(top_srcdir)/include/
diff --git a/src/caps.c b/src/caps.c
index bf578fa..23f16fc 100644
--- a/src/caps.c
+++ b/src/caps.c
@@ -26,10 +26,7 @@
*
****************************************************************************/
-#include "common.h"
-
-#define SETABS(c, x, map, key, fd) \
- (c->has_##x = getbit(map, key) && getabs(&c->x, key, fd))
+#include "state.h"
static const int SN_COORD = 250; /* coordinate signal-to-noise ratio */
static const int SN_WIDTH = 100; /* width signal-to-noise ratio */
@@ -54,59 +51,157 @@ static int getabs(struct input_absinfo *abs, int key, int fd)
return rc >= 0;
}
-static int has_mt_data(const struct mtdev_caps *cap)
+static struct input_absinfo *get_info(struct mtdev *dev, int code)
{
- return cap->has_abs[MTDEV_POSITION_X] && cap->has_abs[MTDEV_POSITION_Y];
+ int ix;
+
+ if (code == ABS_MT_SLOT)
+ return &dev->slot;
+ if (!mtdev_is_absmt(code))
+ return NULL;
+
+ ix = mtdev_abs2mt(code);
+ if (ix < 11)
+ return &dev->abs[ix];
+ else
+ return &dev->state->ext_abs[ix - 11];
}
-static void default_fuzz(struct mtdev_caps *cap, int bit, int sn)
+static void set_info(struct mtdev *dev, int code,
+ const unsigned long *bits, int fd)
{
- if (cap->has_abs[bit] && cap->abs[bit].fuzz == 0)
- cap->abs[bit].fuzz =
- (cap->abs[bit].maximum - cap->abs[bit].minimum) / sn;
+ int has = getbit(bits, code) && getabs(get_info(dev, code), code, fd);
+ mtdev_set_mt_event(dev, code, has);
}
-static int read_caps(struct mtdev_caps *cap, int fd)
+static void default_fuzz(struct mtdev *dev, int code, int sn)
+{
+ struct input_absinfo *abs = get_info(dev, code);
+ if (!mtdev_has_mt_event(dev, code) || abs->fuzz)
+ return;
+ abs->fuzz = (abs->maximum - abs->minimum) / sn;
+}
+
+int mtdev_configure(struct mtdev *dev, int fd)
{
unsigned long absbits[nlongs(ABS_MAX)];
int rc, i;
- memset(cap, 0, sizeof(struct mtdev_caps));
-
SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbits)), absbits));
if (rc < 0)
return rc;
- SETABS(cap, slot, absbits, ABS_MT_SLOT, fd);
+ set_info(dev, ABS_MT_SLOT, absbits, fd);
for (i = 0; i < MT_ABS_SIZE; i++)
- SETABS(cap, abs[i], absbits, mtdev_mt2abs(i), fd);
+ set_info(dev, mtdev_mt2abs(i), absbits, fd);
- cap->has_mtdata = has_mt_data(cap);
+ dev->has_mtdata = mtdev_has_mt_event(dev, ABS_MT_POSITION_X) &&
+ mtdev_has_mt_event(dev, ABS_MT_POSITION_Y);
- if (!cap->has_abs[MTDEV_POSITION_X])
- getabs(&cap->abs[MTDEV_POSITION_X], ABS_X, fd);
- if (!cap->has_abs[MTDEV_POSITION_Y])
- getabs(&cap->abs[MTDEV_POSITION_Y], ABS_Y, fd);
- if (!cap->has_abs[MTDEV_PRESSURE])
- getabs(&cap->abs[MTDEV_PRESSURE], ABS_PRESSURE, fd);
+ if (!mtdev_has_mt_event(dev, ABS_MT_POSITION_X))
+ getabs(get_info(dev, ABS_MT_POSITION_X), ABS_X, fd);
+ if (!mtdev_has_mt_event(dev, ABS_MT_POSITION_Y))
+ getabs(get_info(dev, ABS_MT_POSITION_Y), ABS_Y, fd);
+ if (!mtdev_has_mt_event(dev, ABS_MT_PRESSURE))
+ getabs(get_info(dev, ABS_MT_PRESSURE), ABS_PRESSURE, fd);
- if (!cap->has_abs[MTDEV_TRACKING_ID]) {
- cap->abs[MTDEV_TRACKING_ID].minimum = MT_ID_MIN;
- cap->abs[MTDEV_TRACKING_ID].maximum = MT_ID_MAX;
+ if (!mtdev_has_mt_event(dev, ABS_MT_TRACKING_ID)) {
+ mtdev_set_abs_minimum(dev, ABS_MT_TRACKING_ID, MT_ID_MIN);
+ mtdev_set_abs_maximum(dev, ABS_MT_TRACKING_ID, MT_ID_MAX);
}
- default_fuzz(cap, MTDEV_POSITION_X, SN_COORD);
- default_fuzz(cap, MTDEV_POSITION_Y, SN_COORD);
- default_fuzz(cap, MTDEV_TOUCH_MAJOR, SN_WIDTH);
- default_fuzz(cap, MTDEV_TOUCH_MINOR, SN_WIDTH);
- default_fuzz(cap, MTDEV_WIDTH_MAJOR, SN_WIDTH);
- default_fuzz(cap, MTDEV_WIDTH_MINOR, SN_WIDTH);
- default_fuzz(cap, MTDEV_ORIENTATION, SN_ORIENT);
+ default_fuzz(dev, ABS_MT_POSITION_X, SN_COORD);
+ default_fuzz(dev, ABS_MT_POSITION_Y, SN_COORD);
+ default_fuzz(dev, ABS_MT_TOUCH_MAJOR, SN_WIDTH);
+ default_fuzz(dev, ABS_MT_TOUCH_MINOR, SN_WIDTH);
+ default_fuzz(dev, ABS_MT_WIDTH_MAJOR, SN_WIDTH);
+ default_fuzz(dev, ABS_MT_WIDTH_MINOR, SN_WIDTH);
+ default_fuzz(dev, ABS_MT_ORIENTATION, SN_ORIENT);
return 0;
}
-int mtdev_configure(struct mtdev *dev, int fd)
+int mtdev_has_mt_event(const struct mtdev *dev, int code)
+{
+ int ix;
+
+ if (code == ABS_MT_SLOT)
+ return dev->has_slot;
+ if (!mtdev_is_absmt(code))
+ return 0;
+
+ ix = mtdev_abs2mt(code);
+ if (ix < 11)
+ return dev->has_abs[ix];
+ else
+ return dev->state->has_ext_abs[ix - 11];
+}
+
+int mtdev_get_abs_minimum(const struct mtdev *dev, int code)
{
- return read_caps(&dev->caps, fd);
+ const struct input_absinfo *abs = get_info((struct mtdev *)dev, code);
+ return abs ? abs->minimum : 0;
}
+
+int mtdev_get_abs_maximum(const struct mtdev *dev, int code)
+{
+ const struct input_absinfo *abs = get_info((struct mtdev *)dev, code);
+ return abs ? abs->maximum : 0;
+}
+
+int mtdev_get_abs_fuzz(const struct mtdev *dev, int code)
+{
+ const struct input_absinfo *abs = get_info((struct mtdev *)dev, code);
+ return abs ? abs->fuzz : 0;
+}
+
+int mtdev_get_abs_resolution(const struct mtdev *dev, int code)
+{
+ const struct input_absinfo *abs = get_info((struct mtdev *)dev, code);
+ return abs ? abs->resolution : 0;
+}
+
+void mtdev_set_abs_minimum(struct mtdev *dev, int code, int value)
+{
+ struct input_absinfo *abs = get_info(dev, code);
+ if (abs)
+ abs->minimum = value;
+}
+
+void mtdev_set_mt_event(struct mtdev *dev, int code, int value)
+{
+ int ix;
+
+ if (code == ABS_MT_SLOT)
+ dev->has_slot = value;
+ if (!mtdev_is_absmt(code))
+ return;
+
+ ix = mtdev_abs2mt(code);
+ if (ix < 11)
+ dev->has_abs[ix] = value;
+ else
+ dev->state->has_ext_abs[ix - 11] = value;
+}
+
+void mtdev_set_abs_maximum(struct mtdev *dev, int code, int value)
+{
+ struct input_absinfo *abs = get_info(dev, code);
+ if (abs)
+ abs->maximum = value;
+}
+
+void mtdev_set_abs_fuzz(struct mtdev *dev, int code, int value)
+{
+ struct input_absinfo *abs = get_info(dev, code);
+ if (abs)
+ abs->fuzz = value;
+}
+
+void mtdev_set_abs_resolution(struct mtdev *dev, int code, int value)
+{
+ struct input_absinfo *abs = get_info(dev, code);
+ if (abs)
+ abs->resolution = value;
+}
+
diff --git a/src/common.h b/src/common.h
index e06f7f7..43b5688 100644
--- a/src/common.h
+++ b/src/common.h
@@ -29,6 +29,8 @@
#ifndef COMMON_H
#define COMMON_H
+#define MTDEV_NO_LEGACY_API
+
#include <mtdev-mapping.h>
#include <mtdev-plumbing.h>
#include <malloc.h>
@@ -85,4 +87,61 @@ static inline int bitcount(unsigned v)
/* robust system ioctl calls */
#define SYSCALL(call) while (((call) == -1) && (errno == EINTR))
+/**
+ * struct mtdev - represents an input MT device
+ * @has_mtdata: true if the device has MT capabilities
+ * @has_slot: true if the device sends MT slots
+ * @slot: slot event properties
+ * @abs: ABS_MT event properties
+ * @state: internal mtdev parsing state
+ *
+ * The mtdev structure represents a kernel MT device type B, emitting
+ * MT slot events. The events put into mtdev may be from any MT
+ * device, specifically type A without contact tracking, type A with
+ * contact tracking, or type B with contact tracking. See the kernel
+ * documentation for further details.
+ *
+ */
+struct mtdev {
+ int has_mtdata;
+ int has_slot;
+ int has_abs[11];
+ struct input_absinfo slot;
+ struct input_absinfo abs[11];
+ struct mtdev_state *state;
+};
+
+#define MT_ABS_SIZE 11
+
+static const unsigned int mtdev_map_abs2mt[ABS_CNT] = {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static const unsigned int mtdev_map_mt2abs[MT_ABS_SIZE] = {
+ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+ 0x0038, 0x0039, 0x003a,
+};
+
+static inline int mtdev_is_absmt(unsigned int code)
+{
+ return mtdev_map_abs2mt[code];
+}
+
+static inline unsigned int mtdev_abs2mt(unsigned int code)
+{
+ return mtdev_map_abs2mt[code] - 1;
+}
+
+static inline unsigned int mtdev_mt2abs(unsigned int mtcode)
+{
+ return mtdev_map_mt2abs[mtcode];
+}
+
#endif
diff --git a/src/core.c b/src/core.c
index a6798b0..1f7c1fe 100644
--- a/src/core.c
+++ b/src/core.c
@@ -32,10 +32,16 @@
#include "match.h"
static inline int istouch(const struct mtdev_slot *data,
- const struct mtdev_caps *caps)
+ const struct mtdev *dev)
{
- return data->abs[MTDEV_TOUCH_MAJOR] ||
- !caps->has_abs[MTDEV_TOUCH_MAJOR];
+ return data->touch_major ||
+ !mtdev_has_mt_event(dev, ABS_MT_TOUCH_MAJOR);
+}
+
+static inline int isfilled(unsigned int mask)
+{
+ return GETBIT(mask, mtdev_abs2mt(ABS_MT_POSITION_X)) &&
+ GETBIT(mask, mtdev_abs2mt(ABS_MT_POSITION_Y));
}
/* Response-augmented EWMA filter, courtesy of Vojtech Pavlik */
@@ -58,7 +64,7 @@ static int defuzz(int value, int old_val, int fuzz)
/*
* solve - solve contact matching problem
* @state: mtdev state
- * @caps: device capabilities
+ * @dev: device capabilities
* @sid: array of current tracking ids
* @sx: array of current position x
* @sy: array of current position y
@@ -69,7 +75,7 @@ static int defuzz(int value, int old_val, int fuzz)
* @nn: number of new contacts
* @touch: which of the new contacts to fill
*/
-static void solve(struct mtdev_state *state, const struct mtdev_caps *caps,
+static void solve(struct mtdev_state *state, const struct mtdev *dev,
const int *sid, const int *sx, const int *sy, int sn,
int *nid, const int *nx, const int *ny, int nn,
bitmask_t touch)
@@ -100,34 +106,33 @@ static void solve(struct mtdev_state *state, const struct mtdev_caps *caps,
/*
* assign_tracking_id - assign tracking ids to all contacts
* @state: mtdev state
- * @caps: device capabilities
+ * @dev: device capabilities
* @data: array of all present contacts, to be filled
* @prop: array of all set contacts properties
* @size: number of contacts in array
* @touch: which of the contacts are actual touches
*/
static void assign_tracking_id(struct mtdev_state *state,
- const struct mtdev_caps *caps,
+ const struct mtdev *dev,
struct mtdev_slot *data, bitmask_t *prop,
int size, bitmask_t touch)
{
int sid[DIM_FINGER], sx[DIM_FINGER], sy[DIM_FINGER], sn = 0;
int nid[DIM_FINGER], nx[DIM_FINGER], ny[DIM_FINGER], i;
foreach_bit(i, state->used) {
- sid[sn] = state->data[i].abs[MTDEV_TRACKING_ID];
- sx[sn] = state->data[i].abs[MTDEV_POSITION_X];
- sy[sn] = state->data[i].abs[MTDEV_POSITION_Y];
+ sid[sn] = state->data[i].tracking_id;
+ sx[sn] = state->data[i].position_x;
+ sy[sn] = state->data[i].position_y;
sn++;
}
for (i = 0; i < size; i++) {
- nx[i] = data[i].abs[MTDEV_POSITION_X];
- ny[i] = data[i].abs[MTDEV_POSITION_Y];
+ nx[i] = data[i].position_x;
+ ny[i] = data[i].position_y;
}
- solve(state, caps, sid, sx, sy, sn, nid, nx, ny, size, touch);
+ solve(state, dev, sid, sx, sy, sn, nid, nx, ny, size, touch);
for (i = 0; i < size; i++) {
- data[i].abs[MTDEV_TRACKING_ID] =
- GETBIT(touch, i) ? nid[i] : MT_ID_NULL;
- prop[i] |= BITMASK(MTDEV_TRACKING_ID);
+ data[i].tracking_id = GETBIT(touch, i) ? nid[i] : MT_ID_NULL;
+ SETBIT(prop[i], mtdev_abs2mt(ABS_MT_TRACKING_ID));
}
}
@@ -157,9 +162,7 @@ static int process_typeA(struct mtdev_state *state,
case EV_SYN:
switch (ev.code) {
case SYN_MT_REPORT:
- if (size < DIM_FINGER &&
- GETBIT(prop[size], MTDEV_POSITION_X) &&
- GETBIT(prop[size], MTDEV_POSITION_Y))
+ if (size < DIM_FINGER && isfilled(prop[size]))
size++;
if (size < DIM_FINGER)
prop[size] = 0;
@@ -178,8 +181,8 @@ static int process_typeA(struct mtdev_state *state,
case EV_ABS:
if (size < DIM_FINGER && mtdev_is_absmt(ev.code)) {
mtcode = mtdev_abs2mt(ev.code);
- data[size].abs[mtcode] = ev.value;
- prop[size] |= BITMASK(mtcode);
+ set_sval(&data[size], mtcode, ev.value);
+ SETBIT(prop[size], mtcode);
mtcnt++;
consumed = 1;
}
@@ -210,21 +213,22 @@ static void process_typeB(struct mtdev_state *state)
/*
* filter_data - apply input filtering on new incoming data
* @state: mtdev state
- * @caps: device capabilities
+ * @dev: device capabilities
* @data: the incoming data to filter
* @prop: the properties to filter
* @slot: the slot the data refers to
*/
static void filter_data(const struct mtdev_state *state,
- const struct mtdev_caps *caps,
+ const struct mtdev *dev,
struct mtdev_slot *data, bitmask_t prop,
int slot)
{
int i;
foreach_bit(i, prop) {
- int fuzz = caps->abs[i].fuzz;
- int oldval = state->data[slot].abs[i];
- data->abs[i] = defuzz(data->abs[i], oldval, fuzz);
+ int fuzz = mtdev_get_abs_fuzz(dev, mtdev_mt2abs(i));
+ int oldval = get_sval(&state->data[slot], i);
+ int value = get_sval(data, i);
+ set_sval(data, i, defuzz(value, oldval, fuzz));
}
}
@@ -243,7 +247,7 @@ static void push_slot_changes(struct mtdev_state *state,
struct input_event ev;
int i, count = 0;
foreach_bit(i, prop)
- if (state->data[slot].abs[i] != data->abs[i])
+ if (get_sval(&state->data[slot], i) != get_sval(data, i))
count++;
if (!count)
return;
@@ -257,10 +261,10 @@ static void push_slot_changes(struct mtdev_state *state,
}
foreach_bit(i, prop) {
ev.code = mtdev_mt2abs(i);
- ev.value = data->abs[i];
- if (state->data[slot].abs[i] != ev.value) {
+ ev.value = get_sval(data, i);
+ if (get_sval(&state->data[slot], i) != ev.value) {
evbuf_put(&state->outbuf, &ev);
- state->data[slot].abs[i] = ev.value;
+ set_sval(&state->data[slot], i, ev.value);
}
}
}
@@ -268,14 +272,14 @@ static void push_slot_changes(struct mtdev_state *state,
/*
* apply_typeA_changes - parse and propagate state changes
* @state: mtdev state
- * @caps: device capabilities
+ * @dev: device capabilities
* @data: array of data to apply
* @prop: array of properties to apply
* @size: number of contacts in array
* @syn: reference to the SYN_REPORT event
*/
static void apply_typeA_changes(struct mtdev_state *state,
- const struct mtdev_caps *caps,
+ const struct mtdev *dev,
struct mtdev_slot *data, const bitmask_t *prop,
int size, const struct input_event *syn)
{
@@ -283,11 +287,11 @@ static void apply_typeA_changes(struct mtdev_state *state,
bitmask_t used = 0;
int i, slot, id;
for (i = 0; i < size; i++) {
- id = data[i].abs[MTDEV_TRACKING_ID];
+ id = data[i].tracking_id;
foreach_bit(slot, state->used) {
- if (state->data[slot].abs[MTDEV_TRACKING_ID] != id)
+ if (state->data[slot].tracking_id != id)
continue;
- filter_data(state, caps, &data[i], prop[i], slot);
+ filter_data(state, dev, &data[i], prop[i], slot);
push_slot_changes(state, &data[i], prop[i], slot, syn);
SETBIT(used, slot);
id = MT_ID_NULL;
@@ -304,8 +308,8 @@ static void apply_typeA_changes(struct mtdev_state *state,
/* clear unused slots and update slot usage */
foreach_bit(slot, state->used & ~used) {
struct mtdev_slot tdata = state->data[slot];
- bitmask_t tprop = BITMASK(MTDEV_TRACKING_ID);
- tdata.abs[MTDEV_TRACKING_ID] = MT_ID_NULL;
+ bitmask_t tprop = BITMASK(mtdev_abs2mt(ABS_MT_TRACKING_ID));
+ tdata.tracking_id = MT_ID_NULL;
push_slot_changes(state, &tdata, tprop, slot, syn);
}
state->used = used;
@@ -314,11 +318,11 @@ static void apply_typeA_changes(struct mtdev_state *state,
/*
* convert_A_to_B - propagate a type A packet as a type B packet
* @state: mtdev state
- * @caps: device capabilities
+ * @dev: device capabilities
* @syn: reference to the SYN_REPORT event
*/
static void convert_A_to_B(struct mtdev_state *state,
- const struct mtdev_caps *caps,
+ const struct mtdev *dev,
const struct input_event *syn)
{
struct mtdev_slot data[DIM_FINGER];
@@ -326,14 +330,19 @@ static void convert_A_to_B(struct mtdev_state *state,
int size = process_typeA(state, data, prop);
if (size < 0)
return;
- if (!caps->has_abs[MTDEV_TRACKING_ID]) {
+ if (!mtdev_has_mt_event(dev, ABS_MT_TRACKING_ID)) {
bitmask_t touch = 0;
int i;
for (i = 0; i < size; i++)
- MODBIT(touch, i, istouch(&data[i], caps));
- assign_tracking_id(state, caps, data, prop, size, touch);
+ MODBIT(touch, i, istouch(&data[i], dev));
+ assign_tracking_id(state, dev, data, prop, size, touch);
}
- apply_typeA_changes(state, caps, data, prop, size, syn);
+ apply_typeA_changes(state, dev, data, prop, size, syn);
+}
+
+struct mtdev *mtdev_new(void)
+{
+ return calloc(1, sizeof(struct mtdev));
}
int mtdev_init(struct mtdev *dev)
@@ -344,7 +353,7 @@ int mtdev_init(struct mtdev *dev)
if (!dev->state)
return -ENOMEM;
for (i = 0; i < DIM_FINGER; i++)
- dev->state->data[i].abs[MTDEV_TRACKING_ID] = MT_ID_NULL;
+ dev->state->data[i].tracking_id = MT_ID_NULL;
return 0;
}
@@ -364,15 +373,29 @@ int mtdev_open(struct mtdev *dev, int fd)
return ret;
}
+struct mtdev *mtdev_new_open(int fd)
+{
+ struct mtdev *dev;
+
+ dev = mtdev_new();
+ if (!dev)
+ return NULL;
+ if (!mtdev_open(dev, fd))
+ return dev;
+
+ mtdev_delete(dev);
+ return NULL;
+}
+
void mtdev_put_event(struct mtdev *dev, const struct input_event *ev)
{
struct mtdev_state *state = dev->state;
if (ev->type == EV_SYN && ev->code == SYN_REPORT) {
bitmask_t head = state->outbuf.head;
- if (dev->caps.has_slot)
+ if (mtdev_has_mt_event(dev, ABS_MT_SLOT))
process_typeB(state);
else
- convert_A_to_B(state, &dev->caps, ev);
+ convert_A_to_B(state, dev, ev);
if (state->outbuf.head != head)
evbuf_put(&state->outbuf, ev);
} else {
@@ -380,8 +403,19 @@ void mtdev_put_event(struct mtdev *dev, const struct input_event *ev)
}
}
+void mtdev_close_delete(struct mtdev *dev)
+{
+ mtdev_close(dev);
+ mtdev_delete(dev);
+}
+
void mtdev_close(struct mtdev *dev)
{
free(dev->state);
memset(dev, 0, sizeof(struct mtdev));
}
+
+void mtdev_delete(struct mtdev *dev)
+{
+ free(dev);
+}
diff --git a/src/state.h b/src/state.h
index df12139..4e98a08 100644
--- a/src/state.h
+++ b/src/state.h
@@ -37,9 +37,29 @@
* @abs: current values of ABS_MT axes for this slot
*/
struct mtdev_slot {
- int abs[MT_ABS_SIZE];
+ int touch_major;
+ int touch_minor;
+ int width_major;
+ int width_minor;
+ int orientation;
+ int position_x;
+ int position_y;
+ int tool_type;
+ int blob_id;
+ int tracking_id;
+ int pressure;
};
+static inline int get_sval(const struct mtdev_slot *slot, int ix)
+{
+ return (&slot->touch_major)[ix];
+}
+
+static inline void set_sval(struct mtdev_slot *slot, int ix, int value)
+{
+ (&slot->touch_major)[ix] = value;
+}
+
/*
* struct mtdev_state - MT slot parsing
* @inbuf: input event buffer
@@ -50,10 +70,15 @@ struct mtdev_slot {
* @lastid: last used tracking id
*/
struct mtdev_state {
+
+ int has_ext_abs[MT_ABS_SIZE - 11];
+ struct input_absinfo ext_abs[MT_ABS_SIZE - 11];
+
struct mtdev_iobuf iobuf;
struct mtdev_evbuf inbuf;
struct mtdev_evbuf outbuf;
struct mtdev_slot data[DIM_FINGER];
+
bitmask_t used;
bitmask_t slot;
bitmask_t lastid;
diff --git a/test/mtdev-mapgen.c b/test/mtdev-mapgen.c
index 8f70998..dc1ba91 100644
--- a/test/mtdev-mapgen.c
+++ b/test/mtdev-mapgen.c
@@ -26,12 +26,24 @@
*
****************************************************************************/
-#include <mtdev-mapping.h>
+#define MTDEV_NO_LEGACY_API
+#include <mtdev.h>
#include <stdio.h>
-#define BIT_DEF(name) \
- printf("#define MTDEV_"#name"\t%d\n", \
- cabs2mt[ABS_MT_##name] - 1)
+#define MT_ABS_SIZE 11
+#define MT_SLOT_ABS_EVENTS { \
+ ABS_MT_TOUCH_MAJOR, \
+ ABS_MT_TOUCH_MINOR, \
+ ABS_MT_WIDTH_MAJOR, \
+ ABS_MT_WIDTH_MINOR, \
+ ABS_MT_ORIENTATION, \
+ ABS_MT_POSITION_X, \
+ ABS_MT_POSITION_Y, \
+ ABS_MT_TOOL_TYPE, \
+ ABS_MT_BLOB_ID, \
+ ABS_MT_TRACKING_ID, \
+ ABS_MT_PRESSURE, \
+}
static unsigned int cabs2mt[ABS_CNT];
static unsigned int cmt2abs[MT_ABS_SIZE];
@@ -63,17 +75,5 @@ int main(int argc, char *argv[])
for (i = 0; i < MT_ABS_SIZE; i++)
printf(" 0x%04x,%s", cmt2abs[i], newln(i, MT_ABS_SIZE));
printf("};\n\n");
- BIT_DEF(TOUCH_MAJOR);
- BIT_DEF(TOUCH_MINOR);
- BIT_DEF(WIDTH_MAJOR);
- BIT_DEF(WIDTH_MINOR);
- BIT_DEF(ORIENTATION);
- BIT_DEF(POSITION_X);
- BIT_DEF(POSITION_Y);
- BIT_DEF(TOOL_TYPE);
- BIT_DEF(BLOB_ID);
- BIT_DEF(TRACKING_ID);
- BIT_DEF(PRESSURE);
- printf("\n");
return 0;
}