summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;
}