diff options
-rw-r--r-- | include/mtdev-mapping.h | 4 | ||||
-rw-r--r-- | include/mtdev-plumbing.h | 37 | ||||
-rw-r--r-- | include/mtdev.h | 117 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/caps.c | 163 | ||||
-rw-r--r-- | src/common.h | 59 | ||||
-rw-r--r-- | src/core.c | 126 | ||||
-rw-r--r-- | src/state.h | 27 | ||||
-rw-r--r-- | test/mtdev-mapgen.c | 32 |
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/ @@ -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 @@ -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; } |