diff options
| author | Henrik Rydberg <rydberg@euromail.se> | 2010-10-12 15:38:43 +0200 |
|---|---|---|
| committer | Henrik Rydberg <rydberg@euromail.se> | 2010-10-12 15:38:43 +0200 |
| commit | acea9df3381825a634c000a574f58b4ca5293ee8 (patch) | |
| tree | 3698bd55f137bc377f1b840e4fb5bf9e446e7250 | |
| parent | 7380af2c93dc83f4f09e293717d46eadf7799e89 (diff) | |
Same version, but using the mtdev library.
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
| -rw-r--r-- | Makefile | 15 | ||||
| -rw-r--r-- | driver/multitouch.c | 8 | ||||
| -rw-r--r-- | include/abs2mt.h | 39 | ||||
| -rw-r--r-- | include/capabilities.h (renamed from include/mtdev-caps.h) | 8 | ||||
| -rw-r--r-- | include/common.h | 49 | ||||
| -rw-r--r-- | include/hwstate.h | 6 | ||||
| -rw-r--r-- | include/match.h | 36 | ||||
| -rw-r--r-- | include/mtbit.h | 14 | ||||
| -rw-r--r-- | include/mtdev-evbuf.h | 57 | ||||
| -rw-r--r-- | include/mtdev-iobuf.h | 38 | ||||
| -rw-r--r-- | include/mtdev.h | 57 | ||||
| -rw-r--r-- | include/mtouch.h | 7 | ||||
| -rw-r--r-- | match/match.c | 385 | ||||
| -rw-r--r-- | match/test.c | 135 | ||||
| -rw-r--r-- | mtdev/core.c | 402 | ||||
| -rw-r--r-- | mtdev/iobuf.c | 63 | ||||
| -rw-r--r-- | mtdev/mapgen.c | 69 | ||||
| -rw-r--r-- | mtdev/test.c | 79 | ||||
| -rw-r--r-- | src/capabilities.c (renamed from mtdev/caps.c) | 22 | ||||
| -rw-r--r-- | src/hwstate.c | 24 | ||||
| -rw-r--r-- | src/memory.c | 4 | ||||
| -rw-r--r-- | src/mtouch.c | 32 | ||||
| -rw-r--r-- | src/mtstate.c | 14 | ||||
| -rw-r--r-- | src/test.c | 4 |
24 files changed, 58 insertions, 1509 deletions
| @@ -4,20 +4,13 @@ EXTRAVERSION = beta1 | |||
| 4 | 4 | ||
| 5 | LIBRARY = multitouch.so | 5 | LIBRARY = multitouch.so |
| 6 | FDIS = 11-multitouch.fdi | 6 | FDIS = 11-multitouch.fdi |
| 7 | MODULES = match mtdev src | 7 | MODULES = src |
| 8 | XMODULES = driver | 8 | XMODULES = driver |
| 9 | 9 | ||
| 10 | o_match = match | 10 | o_src = capabilities hwstate mtstate memory mtouch gestures |
| 11 | |||
| 12 | o_mtdev = iobuf caps core | ||
| 13 | |||
| 14 | o_src = hwstate mtstate memory mtouch gestures | ||
| 15 | 11 | ||
| 16 | o_driver= multitouch | 12 | o_driver= multitouch |
| 17 | 13 | ||
| 18 | TARGETS += match/test | ||
| 19 | TARGETS += mtdev/mapgen | ||
| 20 | TARGETS += mtdev/test | ||
| 21 | TARGETS += src/test | 14 | TARGETS += src/test |
| 22 | 15 | ||
| 23 | OBJECTS = $(addsuffix .o,\ | 16 | OBJECTS = $(addsuffix .o,\ |
| @@ -33,7 +26,7 @@ TOBJ = $(addprefix obj/,$(addsuffix .o,$(TARGETS))) | |||
| 33 | TFDI = $(addprefix fdi/,$(FDIS)) | 26 | TFDI = $(addprefix fdi/,$(FDIS)) |
| 34 | OBJS = $(addprefix obj/,$(OBJECTS)) | 27 | OBJS = $(addprefix obj/,$(OBJECTS)) |
| 35 | XOBJS = $(addprefix obj/,$(XOBJECTS)) | 28 | XOBJS = $(addprefix obj/,$(XOBJECTS)) |
| 36 | LIBS = -lm | 29 | LIBS = -lmtdev -lm |
| 37 | 30 | ||
| 38 | DLIB = usr/lib/xorg/modules/input | 31 | DLIB = usr/lib/xorg/modules/input |
| 39 | DFDI = usr/share/hal/fdi/policy/20thirdparty | 32 | DFDI = usr/share/hal/fdi/policy/20thirdparty |
| @@ -52,7 +45,7 @@ bin/%: obj/%.o $(OBJS) | |||
| 52 | 45 | ||
| 53 | $(TLIB): $(OBJS) $(XOBJS) | 46 | $(TLIB): $(OBJS) $(XOBJS) |
| 54 | @rm -f $(TLIB) | 47 | @rm -f $(TLIB) |
| 55 | gcc -shared $(OBJS) $(XOBJS) -Wl,-soname -Wl,$(LIBRARY) -o $@ | 48 | gcc -shared $(OBJS) $(XOBJS) $(LIBS) -Wl,-soname -Wl,$(LIBRARY) -o $@ |
| 56 | 49 | ||
| 57 | obj/%.o: %.c | 50 | obj/%.o: %.c |
| 58 | @mkdir -p $(@D) | 51 | @mkdir -p $(@D) |
diff --git a/driver/multitouch.c b/driver/multitouch.c index eef86c5..3ccc1c6 100644 --- a/driver/multitouch.c +++ b/driver/multitouch.c | |||
| @@ -132,16 +132,16 @@ static int device_init(DeviceIntPtr dev, LocalDevicePtr local) | |||
| 132 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 | 132 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 |
| 133 | axes_labels[0], | 133 | axes_labels[0], |
| 134 | #endif | 134 | #endif |
| 135 | mt->caps.abs[BIT_POSITION_X].minimum, | 135 | mt->caps.abs[MTDEV_POSITION_X].minimum, |
| 136 | mt->caps.abs[BIT_POSITION_X].maximum, | 136 | mt->caps.abs[MTDEV_POSITION_X].maximum, |
| 137 | 1, 0, 1); | 137 | 1, 0, 1); |
| 138 | xf86InitValuatorDefaults(dev, 0); | 138 | xf86InitValuatorDefaults(dev, 0); |
| 139 | xf86InitValuatorAxisStruct(dev, 1, | 139 | xf86InitValuatorAxisStruct(dev, 1, |
| 140 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 | 140 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 |
| 141 | axes_labels[1], | 141 | axes_labels[1], |
| 142 | #endif | 142 | #endif |
| 143 | mt->caps.abs[BIT_POSITION_Y].minimum, | 143 | mt->caps.abs[MTDEV_POSITION_Y].minimum, |
| 144 | mt->caps.abs[BIT_POSITION_Y].maximum, | 144 | mt->caps.abs[MTDEV_POSITION_Y].maximum, |
| 145 | 1, 0, 1); | 145 | 1, 0, 1); |
| 146 | xf86InitValuatorDefaults(dev, 1); | 146 | xf86InitValuatorDefaults(dev, 1); |
| 147 | 147 | ||
diff --git a/include/abs2mt.h b/include/abs2mt.h deleted file mode 100644 index 6021d8d..0000000 --- a/include/abs2mt.h +++ /dev/null | |||
| @@ -1,39 +0,0 @@ | |||
| 1 | /* generated by mapgen - do not edit */ | ||
| 2 | |||
| 3 | #ifndef ABS2MT_H | ||
| 4 | #define ABS2MT_H | ||
| 5 | |||
| 6 | #include "common.h" | ||
| 7 | |||
| 8 | static const unsigned int map_abs2mt[ABS_CNT] = { | ||
| 9 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, | ||
| 10 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, | ||
| 11 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, | ||
| 12 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, | ||
| 13 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, | ||
| 14 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, | ||
| 15 | 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, | ||
| 16 | 0x0009, 0x000a, 0x000b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, | ||
| 17 | }; | ||
| 18 | |||
| 19 | static const unsigned int map_mt2abs[MT_ABS_SIZE] = { | ||
| 20 | 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, | ||
| 21 | 0x0038, 0x0039, 0x003a, | ||
| 22 | }; | ||
| 23 | |||
| 24 | static inline int has_abs2mt(unsigned int code) | ||
| 25 | { | ||
| 26 | return map_abs2mt[code]; | ||
| 27 | } | ||
| 28 | |||
| 29 | static inline unsigned int abs2mt(unsigned int code) | ||
| 30 | { | ||
| 31 | return map_abs2mt[code] - 1; | ||
| 32 | } | ||
| 33 | |||
| 34 | static inline unsigned int mt2abs(unsigned int mtcode) | ||
| 35 | { | ||
| 36 | return map_mt2abs[mtcode]; | ||
| 37 | } | ||
| 38 | |||
| 39 | #endif | ||
diff --git a/include/mtdev-caps.h b/include/capabilities.h index 727cd11..0dfc73b 100644 --- a/include/mtdev-caps.h +++ b/include/capabilities.h | |||
| @@ -19,20 +19,18 @@ | |||
| 19 | * | 19 | * |
| 20 | **************************************************************************/ | 20 | **************************************************************************/ |
| 21 | 21 | ||
| 22 | #ifndef MTDEV_CAPS_H | 22 | #ifndef CAPABILITIES_H |
| 23 | #define MTDEV_CAPS_H | 23 | #define CAPABILITIES_H |
| 24 | 24 | ||
| 25 | #include "common.h" | 25 | #include "common.h" |
| 26 | #include "button.h" | 26 | #include "button.h" |
| 27 | #include "abs2mt.h" | ||
| 28 | #include "mtbit.h" | ||
| 29 | 27 | ||
| 30 | struct Capabilities { | 28 | struct Capabilities { |
| 31 | struct input_id devid; | 29 | struct input_id devid; |
| 32 | char devname[32]; | 30 | char devname[32]; |
| 33 | int has_left, has_middle, has_right; | 31 | int has_left, has_middle, has_right; |
| 34 | int has_mtdata, has_ibt; | 32 | int has_mtdata, has_ibt; |
| 35 | int has_slot, nullid; | 33 | int has_slot; |
| 36 | int has_abs[MT_ABS_SIZE]; | 34 | int has_abs[MT_ABS_SIZE]; |
| 37 | struct input_absinfo slot; | 35 | struct input_absinfo slot; |
| 38 | struct input_absinfo abs[MT_ABS_SIZE]; | 36 | struct input_absinfo abs[MT_ABS_SIZE]; |
diff --git a/include/common.h b/include/common.h index e13088f..6d00d6e 100644 --- a/include/common.h +++ b/include/common.h | |||
| @@ -26,59 +26,12 @@ | |||
| 26 | #include <xf86.h> | 26 | #include <xf86.h> |
| 27 | #include <xf86_OSproc.h> | 27 | #include <xf86_OSproc.h> |
| 28 | #include <xf86Xinput.h> | 28 | #include <xf86Xinput.h> |
| 29 | #include <linux/input.h> | ||
| 30 | #include <errno.h> | 29 | #include <errno.h> |
| 31 | 30 | #include <mtdev-mapping.h> | |
| 32 | /* includes available in 2.6.30-rc5 */ | ||
| 33 | |||
| 34 | #ifndef BTN_TOOL_QUADTAP | ||
| 35 | #define BTN_TOOL_QUADTAP 0x14f /* Four fingers on trackpad */ | ||
| 36 | #define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */ | ||
| 37 | #define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */ | ||
| 38 | #define ABS_MT_WIDTH_MAJOR 0x32 /* Major axis of approaching ellipse */ | ||
| 39 | #define ABS_MT_WIDTH_MINOR 0x33 /* Minor axis (omit if circular) */ | ||
| 40 | #define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */ | ||
| 41 | #define ABS_MT_POSITION_X 0x35 /* Center X ellipse position */ | ||
| 42 | #define ABS_MT_POSITION_Y 0x36 /* Center Y ellipse position */ | ||
| 43 | #define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */ | ||
| 44 | #define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */ | ||
| 45 | #define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */ | ||
| 46 | #define SYN_MT_REPORT 2 | ||
| 47 | #define MT_TOOL_FINGER 0 | ||
| 48 | #define MT_TOOL_PEN 1 | ||
| 49 | #endif | ||
| 50 | |||
| 51 | /* includes available in 2.6.33 */ | ||
| 52 | #ifndef ABS_MT_PRESSURE | ||
| 53 | #define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */ | ||
| 54 | #endif | ||
| 55 | |||
| 56 | /* includes available in 2.6.36 */ | ||
| 57 | #ifndef ABS_MT_SLOT | ||
| 58 | #define ABS_MT_SLOT 0x2f /* MT slot being modified */ | ||
| 59 | #define MT_SLOT_ABS_EVENTS { \ | ||
| 60 | ABS_MT_TOUCH_MAJOR, \ | ||
| 61 | ABS_MT_TOUCH_MINOR, \ | ||
| 62 | ABS_MT_WIDTH_MAJOR, \ | ||
| 63 | ABS_MT_WIDTH_MINOR, \ | ||
| 64 | ABS_MT_ORIENTATION, \ | ||
| 65 | ABS_MT_POSITION_X, \ | ||
| 66 | ABS_MT_POSITION_Y, \ | ||
| 67 | ABS_MT_TOOL_TYPE, \ | ||
| 68 | ABS_MT_BLOB_ID, \ | ||
| 69 | ABS_MT_TRACKING_ID, \ | ||
| 70 | ABS_MT_PRESSURE, \ | ||
| 71 | } | ||
| 72 | #endif | ||
| 73 | |||
| 74 | #define MT_ABS_SIZE 11 /* Size of MT_SLOT_ABS_EVENTS */ | ||
| 75 | 31 | ||
| 76 | #define DIM_FINGER 32 | 32 | #define DIM_FINGER 32 |
| 77 | #define DIM2_FINGER (DIM_FINGER * DIM_FINGER) | 33 | #define DIM2_FINGER (DIM_FINGER * DIM_FINGER) |
| 78 | 34 | ||
| 79 | /* event buffer size (must be a power of two) */ | ||
| 80 | #define DIM_EVENTS 512 | ||
| 81 | |||
| 82 | /* year-proof millisecond event time */ | 35 | /* year-proof millisecond event time */ |
| 83 | typedef __u64 mstime_t; | 36 | typedef __u64 mstime_t; |
| 84 | 37 | ||
diff --git a/include/hwstate.h b/include/hwstate.h index efd291f..4c59a1e 100644 --- a/include/hwstate.h +++ b/include/hwstate.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | #ifndef HWSTATE_H | 22 | #ifndef HWSTATE_H |
| 23 | #define HWSTATE_H | 23 | #define HWSTATE_H |
| 24 | 24 | ||
| 25 | #include "mtdev.h" | 25 | #include "capabilities.h" |
| 26 | 26 | ||
| 27 | struct FingerState { | 27 | struct FingerState { |
| 28 | int touch_major, touch_minor; | 28 | int touch_major, touch_minor; |
| @@ -42,8 +42,8 @@ struct HWState { | |||
| 42 | 42 | ||
| 43 | void init_hwstate(struct HWState *s, | 43 | void init_hwstate(struct HWState *s, |
| 44 | const struct Capabilities *caps); | 44 | const struct Capabilities *caps); |
| 45 | int hwstate_read(struct HWState *s, const struct Capabilities *caps, | 45 | int modify_hwstate(struct HWState *s, struct mtdev *dev, int fd, |
| 46 | const struct input_event *ev); | 46 | const struct Capabilities *caps); |
| 47 | void output_hwstate(const struct HWState *s); | 47 | void output_hwstate(const struct HWState *s); |
| 48 | 48 | ||
| 49 | static inline int finger_dist2(const struct FingerState *a, | 49 | static inline int finger_dist2(const struct FingerState *a, |
diff --git a/include/match.h b/include/match.h deleted file mode 100644 index 25842fc..0000000 --- a/include/match.h +++ /dev/null | |||
| @@ -1,36 +0,0 @@ | |||
| 1 | /*************************************************************************** | ||
| 2 | * | ||
| 3 | * Multitouch X driver | ||
| 4 | * Copyright (C) 2008 Henrik Rydberg <rydberg@euromail.se> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 19 | * | ||
| 20 | **************************************************************************/ | ||
| 21 | |||
| 22 | #ifndef MATCHER_H | ||
| 23 | #define MATCHER_H | ||
| 24 | |||
| 25 | /** | ||
| 26 | * Special implementation of the hungarian algorithm. | ||
| 27 | * The maximum number of fingers matches a uint32. | ||
| 28 | * Bitmasks are used extensively. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #include "common.h" | ||
| 32 | |||
| 33 | void match_fingers(int index[DIM_FINGER], int A[DIM2_FINGER], | ||
| 34 | int nrow, int ncol); | ||
| 35 | |||
| 36 | #endif | ||
diff --git a/include/mtbit.h b/include/mtbit.h deleted file mode 100644 index 2c4dacb..0000000 --- a/include/mtbit.h +++ /dev/null | |||
| @@ -1,14 +0,0 @@ | |||
| 1 | /* generated by mapgen - do not edit */ | ||
| 2 | |||
| 3 | #ifndef MTBIT_H | ||
| 4 | #define MTBIT_H | ||
| 5 | |||
| 6 | #define BIT_TRACKING_ID 9 | ||
| 7 | #define BIT_POSITION_X 5 | ||
| 8 | #define BIT_POSITION_Y 6 | ||
| 9 | #define BIT_TOUCH_MAJOR 0 | ||
| 10 | #define BIT_TOUCH_MINOR 1 | ||
| 11 | #define BIT_WIDTH_MAJOR 2 | ||
| 12 | #define BIT_WIDTH_MINOR 3 | ||
| 13 | |||
| 14 | #endif | ||
diff --git a/include/mtdev-evbuf.h b/include/mtdev-evbuf.h deleted file mode 100644 index 77fec41..0000000 --- a/include/mtdev-evbuf.h +++ /dev/null | |||
| @@ -1,57 +0,0 @@ | |||
| 1 | /*************************************************************************** | ||
| 2 | * | ||
| 3 | * Multitouch X driver | ||
| 4 | * Copyright (C) 2008 Henrik Rydberg <rydberg@euromail.se> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 19 | * | ||
| 20 | **************************************************************************/ | ||
| 21 | |||
| 22 | #ifndef MTDEV_EVBUF_H | ||
| 23 | #define MTDEV_EVBUF_H | ||
| 24 | |||
| 25 | #include "common.h" | ||
| 26 | |||
| 27 | struct EventBuffer { | ||
| 28 | int head; | ||
| 29 | int tail; | ||
| 30 | struct input_event buffer[DIM_EVENTS]; | ||
| 31 | }; | ||
| 32 | |||
| 33 | static inline void evbuf_init(struct EventBuffer *evbuf) | ||
| 34 | { | ||
| 35 | memset(evbuf, 0, sizeof(*evbuf)); | ||
| 36 | } | ||
| 37 | |||
| 38 | static inline int evbuf_empty(const struct EventBuffer *evbuf) | ||
| 39 | { | ||
| 40 | return evbuf->head == evbuf->tail; | ||
| 41 | } | ||
| 42 | |||
| 43 | static inline void evbuf_put(struct EventBuffer *evbuf, | ||
| 44 | const struct input_event *ev) | ||
| 45 | { | ||
| 46 | evbuf->buffer[evbuf->head++] = *ev; | ||
| 47 | evbuf->head &= DIM_EVENTS - 1; | ||
| 48 | } | ||
| 49 | |||
| 50 | static inline void evbuf_get(struct EventBuffer *evbuf, | ||
| 51 | struct input_event *ev) | ||
| 52 | { | ||
| 53 | *ev = evbuf->buffer[evbuf->tail++]; | ||
| 54 | evbuf->tail &= DIM_EVENTS - 1; | ||
| 55 | } | ||
| 56 | |||
| 57 | #endif | ||
diff --git a/include/mtdev-iobuf.h b/include/mtdev-iobuf.h deleted file mode 100644 index 7d4265c..0000000 --- a/include/mtdev-iobuf.h +++ /dev/null | |||
| @@ -1,38 +0,0 @@ | |||
| 1 | /*************************************************************************** | ||
| 2 | * | ||
| 3 | * Multitouch X driver | ||
| 4 | * Copyright (C) 2008 Henrik Rydberg <rydberg@euromail.se> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 19 | * | ||
| 20 | **************************************************************************/ | ||
| 21 | |||
| 22 | #ifndef MTDEV_IOBUF_H | ||
| 23 | #define MTDEV_IOBUF_H | ||
| 24 | |||
| 25 | #include "common.h" | ||
| 26 | |||
| 27 | #define EVENT_SIZE sizeof(struct input_event) | ||
| 28 | #define DIM_BUFFER (DIM_EVENTS * EVENT_SIZE) | ||
| 29 | |||
| 30 | struct IOBuffer { | ||
| 31 | char begin[DIM_BUFFER], *at, *top, *end; | ||
| 32 | }; | ||
| 33 | |||
| 34 | void init_iobuf(struct IOBuffer *buf); | ||
| 35 | const struct input_event *get_iobuf_event(struct IOBuffer *buf, int fd); | ||
| 36 | int poll_iobuf(struct IOBuffer *buf, int fd, int ms); | ||
| 37 | |||
| 38 | #endif | ||
diff --git a/include/mtdev.h b/include/mtdev.h deleted file mode 100644 index 936d597..0000000 --- a/include/mtdev.h +++ /dev/null | |||
| @@ -1,57 +0,0 @@ | |||
| 1 | /*************************************************************************** | ||
| 2 | * | ||
| 3 | * Multitouch X driver | ||
| 4 | * Copyright (C) 2008 Henrik Rydberg <rydberg@euromail.se> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 19 | * | ||
| 20 | **************************************************************************/ | ||
| 21 | |||
| 22 | #ifndef MTDEV_H | ||
| 23 | #define MTDEV_H | ||
| 24 | |||
| 25 | #include "mtdev-caps.h" | ||
| 26 | #include "mtdev-evbuf.h" | ||
| 27 | |||
| 28 | /** | ||
| 29 | * struct MTDev - represents an input MT device | ||
| 30 | * @inbuf: input event buffer | ||
| 31 | * @outbuf: output event buffer | ||
| 32 | * @priv: structure of private data | ||
| 33 | */ | ||
| 34 | struct MTDev { | ||
| 35 | struct EventBuffer inbuf; | ||
| 36 | struct EventBuffer outbuf; | ||
| 37 | struct MTDevState *priv; | ||
| 38 | }; | ||
| 39 | |||
| 40 | int mtdev_init(struct MTDev *mtdev, const struct Capabilities *caps); | ||
| 41 | |||
| 42 | static inline int mtdev_empty(struct MTDev *mtdev) | ||
| 43 | { | ||
| 44 | return evbuf_empty(&mtdev->outbuf); | ||
| 45 | } | ||
| 46 | |||
| 47 | void mtdev_put(struct MTDev *dev, const struct Capabilities *caps, | ||
| 48 | const struct input_event *ev); | ||
| 49 | |||
| 50 | static inline void mtdev_get(struct MTDev *mtdev, struct input_event* ev) | ||
| 51 | { | ||
| 52 | evbuf_get(&mtdev->outbuf, ev); | ||
| 53 | } | ||
| 54 | |||
| 55 | void mtdev_destroy(struct MTDev *mtdev); | ||
| 56 | |||
| 57 | #endif | ||
diff --git a/include/mtouch.h b/include/mtouch.h index 482d010..aedb02c 100644 --- a/include/mtouch.h +++ b/include/mtouch.h | |||
| @@ -23,12 +23,10 @@ | |||
| 23 | #define MTOUCH_H | 23 | #define MTOUCH_H |
| 24 | 24 | ||
| 25 | #include "memory.h" | 25 | #include "memory.h" |
| 26 | #include "mtdev-iobuf.h" | ||
| 27 | 26 | ||
| 28 | struct MTouch { | 27 | struct MTouch { |
| 29 | struct Capabilities caps; | 28 | struct Capabilities caps; |
| 30 | struct MTDev dev; | 29 | struct mtdev dev; |
| 31 | struct IOBuffer buf; | ||
| 32 | struct HWState hs; | 30 | struct HWState hs; |
| 33 | struct MTState prev_state, state; | 31 | struct MTState prev_state, state; |
| 34 | struct Memory mem; | 32 | struct Memory mem; |
| @@ -36,10 +34,9 @@ struct MTouch { | |||
| 36 | 34 | ||
| 37 | int configure_mtouch(struct MTouch *mt, int fd); | 35 | int configure_mtouch(struct MTouch *mt, int fd); |
| 38 | int open_mtouch(struct MTouch *mt, int fd); | 36 | int open_mtouch(struct MTouch *mt, int fd); |
| 39 | int get_mtouch(struct MTouch *mt, int fd, struct input_event* ev, int ev_max); | ||
| 40 | int close_mtouch(struct MTouch *mt, int fd); | 37 | int close_mtouch(struct MTouch *mt, int fd); |
| 41 | 38 | ||
| 42 | int parse_event(struct MTouch *mt, const struct input_event *ev); | 39 | int read_packet(struct MTouch *mt, int fd); |
| 43 | 40 | ||
| 44 | int has_delayed_gestures(struct MTouch *mt, int fd); | 41 | int has_delayed_gestures(struct MTouch *mt, int fd); |
| 45 | 42 | ||
diff --git a/match/match.c b/match/match.c deleted file mode 100644 index 4cb4495..0000000 --- a/match/match.c +++ /dev/null | |||
| @@ -1,385 +0,0 @@ | |||
| 1 | /*************************************************************************** | ||
| 2 | * | ||
| 3 | * Multitouch X driver | ||
| 4 | * Copyright (C) 2008 Henrik Rydberg <rydberg@euromail.se> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 19 | * | ||
| 20 | **************************************************************************/ | ||
| 21 | |||
| 22 | #include "match.h" | ||
| 23 | #include <string.h> | ||
| 24 | #include <stdio.h> | ||
| 25 | |||
| 26 | /** | ||
| 27 | * Bitmap implementation of the hungarian algorithm (GPL license) | ||
| 28 | * | ||
| 29 | * Copyright (C) 2008 Henrik Rydberg <rydberg@euromail.se> | ||
| 30 | * | ||
| 31 | * Based on code released by Markus Buehren (2004) (BSD license) | ||
| 32 | * | ||
| 33 | * Copyright (C) 2004, Markus Buehren. All rights reserved. | ||
| 34 | * See CREDITS file for full license terms. | ||
| 35 | * | ||
| 36 | */ | ||
| 37 | |||
| 38 | typedef unsigned col_t[1]; | ||
| 39 | typedef unsigned mat_t[DIM_FINGER]; | ||
| 40 | |||
| 41 | #define GET1(m, x) ((m[0] >> (x)) & 1U) | ||
| 42 | #define SET1(m, x) (m[0] |= (1U << (x))) | ||
| 43 | #define CLEAR1(m, x) (m[0] &= ~(1U << (x))) | ||
| 44 | |||
| 45 | #define GET2(m, row, col) ((m[col] >> (row)) & 1U) | ||
| 46 | #define SET2(m, row, col) (m[col] |= (1U << (row))) | ||
| 47 | #define CLEAR2(m, row, col) (m[col] &= ~(1U << (row))) | ||
| 48 | |||
| 49 | /********************************************************/ | ||
| 50 | |||
| 51 | static void buildixvector(int *ix, mat_t mstar, int nrows, int ncols) | ||
| 52 | { | ||
| 53 | int row, col; | ||
| 54 | for (row = 0; row < nrows; row++) { | ||
| 55 | for (col = 0; col < ncols; col++) { | ||
| 56 | if (GET2(mstar, row, col)) { | ||
| 57 | ix[row] = col; | ||
| 58 | break; | ||
| 59 | } | ||
| 60 | } | ||
| 61 | } | ||
| 62 | } | ||
| 63 | |||
| 64 | |||
| 65 | /********************************************************/ | ||
| 66 | |||
| 67 | static void step2a(int *ix, int *mdist, mat_t mstar, mat_t nmstar, | ||
| 68 | mat_t mprime, col_t ccol, col_t crow, int nrows, int ncols, | ||
| 69 | int dmin); | ||
| 70 | static void step2b(int *ix, int *mdist, mat_t mstar, mat_t nmstar, | ||
| 71 | mat_t mprime, col_t ccol, col_t crow, int nrows, int ncols, | ||
| 72 | int dmin); | ||
| 73 | static void step3(int *ix, int *mdist, mat_t mstar, mat_t nmstar, | ||
| 74 | mat_t mprime, col_t ccol, col_t crow, int nrows, int ncols, | ||
| 75 | int dmin); | ||
| 76 | static void step4(int *ix, int *mdist, mat_t mstar, mat_t nmstar, | ||
| 77 | mat_t mprime, col_t ccol, col_t crow, int nrows, int ncols, | ||
| 78 | int dmin, int row, int col); | ||
| 79 | static void step5(int *ix, int *mdist, mat_t mstar, mat_t nmstar, | ||
| 80 | mat_t mprime, col_t ccol, col_t crow, int nrows, int ncols, | ||
| 81 | int dmin); | ||
| 82 | |||
| 83 | static void ixoptimal(int *ix, int *mdist, int nrows, int ncols) | ||
| 84 | { | ||
| 85 | int *mdistTemp, *mdistEnd, *columnEnd, value, minValue; | ||
| 86 | int dmin, row, col; | ||
| 87 | col_t ccol, crow; | ||
| 88 | mat_t mstar, mprime, nmstar; | ||
| 89 | |||
| 90 | memset(ccol, 0, sizeof(col_t)); | ||
| 91 | memset(crow, 0, sizeof(col_t)); | ||
| 92 | memset(mstar, 0, sizeof(mat_t)); | ||
| 93 | memset(mprime, 0, sizeof(mat_t)); | ||
| 94 | memset(nmstar, 0, sizeof(mat_t)); | ||
| 95 | |||
| 96 | /* initialization */ | ||
| 97 | for (row = 0; row < nrows; row++) | ||
| 98 | ix[row] = -1; | ||
| 99 | |||
| 100 | mdistEnd = mdist + nrows * ncols; | ||
| 101 | |||
| 102 | /* preliminary steps */ | ||
| 103 | if (nrows <= ncols) { | ||
| 104 | dmin = nrows; | ||
| 105 | |||
| 106 | for (row = 0; row < nrows; row++) { | ||
| 107 | /* find the smallest element in the row */ | ||
| 108 | mdistTemp = mdist + row; | ||
| 109 | minValue = *mdistTemp; | ||
| 110 | mdistTemp += nrows; | ||
| 111 | while (mdistTemp < mdistEnd) { | ||
| 112 | value = *mdistTemp; | ||
| 113 | if (value < minValue) | ||
| 114 | minValue = value; | ||
| 115 | mdistTemp += nrows; | ||
| 116 | } | ||
| 117 | |||
| 118 | /* subtract the smallest element from each element | ||
| 119 | of the row */ | ||
| 120 | mdistTemp = mdist + row; | ||
| 121 | while (mdistTemp < mdistEnd) { | ||
| 122 | *mdistTemp -= minValue; | ||
| 123 | mdistTemp += nrows; | ||
| 124 | } | ||
| 125 | } | ||
| 126 | |||
| 127 | /* Steps 1 and 2a */ | ||
| 128 | for (row = 0; row < nrows; row++) { | ||
| 129 | for (col = 0; col < ncols; col++) { | ||
| 130 | if (mdist[row + nrows * col] != 0) | ||
| 131 | continue; | ||
| 132 | if (GET1(ccol, col)) | ||
| 133 | continue; | ||
| 134 | SET2(mstar, row, col); | ||
| 135 | SET1(ccol, col); | ||
| 136 | break; | ||
| 137 | } | ||
| 138 | } | ||
| 139 | } else { | ||
| 140 | dmin = ncols; | ||
| 141 | |||
| 142 | for (col = 0; col < ncols; col++) { | ||
| 143 | /* find the smallest element in the column */ | ||
| 144 | mdistTemp = mdist + nrows*col; | ||
| 145 | columnEnd = mdistTemp + nrows; | ||
| 146 | |||
| 147 | minValue = *mdistTemp++; | ||
| 148 | while (mdistTemp < columnEnd) { | ||
| 149 | value = *mdistTemp++; | ||
| 150 | if (value < minValue) | ||
| 151 | minValue = value; | ||
| 152 | } | ||
| 153 | |||
| 154 | /* subtract the smallest element from each element | ||
| 155 | of the column */ | ||
| 156 | mdistTemp = mdist + nrows*col; | ||
| 157 | while (mdistTemp < columnEnd) | ||
| 158 | *mdistTemp++ -= minValue; | ||
| 159 | } | ||
| 160 | |||
| 161 | /* Steps 1 and 2a */ | ||
| 162 | for (col = 0; col < ncols; col++) { | ||
| 163 | for (row = 0; row < nrows; row++) { | ||
| 164 | if (mdist[row + nrows * col] != 0) | ||
| 165 | continue; | ||
| 166 | if (GET1(crow, row)) | ||
| 167 | continue; | ||
| 168 | SET2(mstar, row, col); | ||
| 169 | SET1(ccol, col); | ||
| 170 | SET1(crow, row); | ||
| 171 | break; | ||
| 172 | } | ||
| 173 | } | ||
| 174 | memset(crow, 0, sizeof(col_t)); | ||
| 175 | } | ||
| 176 | |||
| 177 | /* move to step 2b */ | ||
| 178 | step2b(ix, mdist, mstar, nmstar, | ||
| 179 | mprime, ccol, crow, nrows, ncols, | ||
| 180 | dmin); | ||
| 181 | } | ||
| 182 | |||
| 183 | /********************************************************/ | ||
| 184 | static void step2a(int *ix, int *mdist, mat_t mstar, mat_t nmstar, | ||
| 185 | mat_t mprime, col_t ccol, col_t crow, int nrows, int ncols, | ||
| 186 | int dmin) | ||
| 187 | { | ||
| 188 | int col, row; | ||
| 189 | |||
| 190 | /* cover every column containing a starred zero */ | ||
| 191 | for (col = 0; col < ncols; col++) { | ||
| 192 | for (row = 0; row < nrows; row++) { | ||
| 193 | if (!GET2(mstar, row, col)) | ||
| 194 | continue; | ||
| 195 | SET1(ccol, col); | ||
| 196 | break; | ||
| 197 | } | ||
| 198 | } | ||
| 199 | |||
| 200 | /* move to step 3 */ | ||
| 201 | step2b(ix, mdist, mstar, nmstar, | ||
| 202 | mprime, ccol, crow, nrows, ncols, | ||
| 203 | dmin); | ||
| 204 | } | ||
| 205 | |||
| 206 | /********************************************************/ | ||
| 207 | static void step2b(int *ix, int *mdist, mat_t mstar, mat_t nmstar, | ||
| 208 | mat_t mprime, col_t ccol, col_t crow, int nrows, int ncols, | ||
| 209 | int dmin) | ||
| 210 | { | ||
| 211 | int col, ncc; | ||
| 212 | |||
| 213 | /* count covered columns */ | ||
| 214 | ncc = 0; | ||
| 215 | for (col = 0; col < ncols; col++) | ||
| 216 | if (GET1(ccol, col)) | ||
| 217 | ncc++; | ||
| 218 | |||
| 219 | if (ncc == dmin) { | ||
| 220 | /* algorithm finished */ | ||
| 221 | buildixvector(ix, mstar, nrows, ncols); | ||
| 222 | } else { | ||
| 223 | /* move to step 3 */ | ||
| 224 | step3(ix, mdist, mstar, nmstar, | ||
| 225 | mprime, ccol, crow, nrows, ncols, | ||
| 226 | dmin); | ||
| 227 | } | ||
| 228 | |||
| 229 | } | ||
| 230 | |||
| 231 | /********************************************************/ | ||
| 232 | static void step3(int *ix, int *mdist, mat_t mstar, mat_t nmstar, | ||
| 233 | mat_t mprime, col_t ccol, col_t crow, int nrows, int ncols, | ||
| 234 | int dmin) | ||
| 235 | { | ||
| 236 | int zerosFound; | ||
| 237 | int row, col, cstar; | ||
| 238 | |||
| 239 | zerosFound = 1; | ||
| 240 | while (zerosFound) { | ||
| 241 | zerosFound = 0; | ||
| 242 | for (col = 0; col < ncols; col++) { | ||
| 243 | if (GET1(ccol, col)) | ||
| 244 | continue; | ||
| 245 | for (row = 0; row < nrows; row++) { | ||
| 246 | if (mdist[row + nrows * col] != 0) | ||
| 247 | continue; | ||
| 248 | if (GET1(crow, row)) | ||
| 249 | continue; | ||
| 250 | |||
| 251 | /* prime zero */ | ||
| 252 | SET2(mprime, row, col); | ||
| 253 | |||
| 254 | /* find starred zero in current row */ | ||
| 255 | for (cstar = 0; cstar < ncols; cstar++) | ||
| 256 | if (GET2(mstar, row, cstar)) | ||
| 257 | break; | ||
| 258 | |||
| 259 | if (cstar == ncols) { /* no starred zero */ | ||
| 260 | /* move to step 4 */ | ||
| 261 | step4(ix, mdist, mstar, nmstar, | ||
| 262 | mprime, ccol, crow, nrows, ncols, | ||
| 263 | dmin, row, col); | ||
| 264 | return; | ||
| 265 | } else { | ||
| 266 | SET1(crow, row); | ||
| 267 | CLEAR1(ccol, cstar); | ||
| 268 | zerosFound = 1; | ||
| 269 | break; | ||
| 270 | } | ||
| 271 | } | ||
| 272 | } | ||
| 273 | } | ||
| 274 | |||
| 275 | /* move to step 5 */ | ||
| 276 | step5(ix, mdist, mstar, nmstar, | ||
| 277 | mprime, ccol, crow, nrows, ncols, | ||
| 278 | dmin); | ||
| 279 | } | ||
| 280 | |||
| 281 | /********************************************************/ | ||
| 282 | static void step4(int *ix, int *mdist, mat_t mstar, mat_t nmstar, | ||
| 283 | mat_t mprime, col_t ccol, col_t crow, int nrows, int ncols, | ||
| 284 | int dmin, int row, int col) | ||
| 285 | { | ||
| 286 | int n, rstar, cstar, primeRow, primeCol; | ||
| 287 | |||
| 288 | /* generate temporary copy of mstar */ | ||
| 289 | memcpy(nmstar, mstar, sizeof(mat_t)); | ||
| 290 | |||
| 291 | /* star current zero */ | ||
| 292 | SET2(nmstar, row, col); | ||
| 293 | |||
| 294 | /* find starred zero in current column */ | ||
| 295 | cstar = col; | ||
| 296 | for (rstar = 0; rstar < nrows; rstar++) | ||
| 297 | if (GET2(mstar, rstar, cstar)) | ||
| 298 | break; | ||
| 299 | |||
| 300 | while (rstar < nrows) { | ||
| 301 | /* unstar the starred zero */ | ||
| 302 | CLEAR2(nmstar, rstar, cstar); | ||
| 303 | |||
| 304 | /* find primed zero in current row */ | ||
| 305 | primeRow = rstar; | ||
| 306 | for (primeCol = 0; primeCol < ncols; primeCol++) | ||
| 307 | if (GET2(mprime, primeRow, primeCol)) | ||
| 308 | break; | ||
| 309 | |||
| 310 | /* star the primed zero */ | ||
| 311 | SET2(nmstar, primeRow, primeCol); | ||
| 312 | |||
| 313 | /* find starred zero in current column */ | ||
| 314 | cstar = primeCol; | ||
| 315 | for (rstar = 0; rstar < nrows; rstar++) | ||
| 316 | if (GET2(mstar, rstar, cstar)) | ||
| 317 | break; | ||
| 318 | } | ||
| 319 | |||
| 320 | /* use temporary copy as new mstar */ | ||
| 321 | /* delete all primes, uncover all rows */ | ||
| 322 | memcpy(mstar, nmstar, sizeof(mat_t)); | ||
| 323 | memset(mprime, 0, sizeof(mat_t)); | ||
| 324 | memset(crow, 0, sizeof(col_t)); | ||
| 325 | |||
| 326 | /* move to step 2a */ | ||
| 327 | step2a(ix, mdist, mstar, nmstar, | ||
| 328 | mprime, ccol, crow, nrows, ncols, | ||
| 329 | dmin); | ||
| 330 | } | ||
| 331 | |||
| 332 | /********************************************************/ | ||
| 333 | static void step5(int *ix, int *mdist, mat_t mstar, mat_t nmstar, | ||
| 334 | mat_t mprime, col_t ccol, col_t crow, int nrows, int ncols, | ||
| 335 | int dmin) | ||
| 336 | { | ||
| 337 | int h = 0, value; | ||
| 338 | int row, col, found = 0; | ||
| 339 | |||
| 340 | /* find smallest uncovered element h */ | ||
| 341 | for (row = 0; row < nrows; row++) { | ||
| 342 | if (GET1(crow, row)) | ||
| 343 | continue; | ||
| 344 | for (col = 0; col < ncols; col++) { | ||
| 345 | if (GET1(ccol, col)) | ||
| 346 | continue; | ||
| 347 | value = mdist[row + nrows * col]; | ||
| 348 | if (!found || value < h) { | ||
| 349 | h = value; | ||
| 350 | found = 1; | ||
| 351 | } | ||
| 352 | } | ||
| 353 | } | ||
| 354 | |||
| 355 | /* where to go if nothing uncovered? */ | ||
| 356 | if (!found) | ||
| 357 | return; | ||
| 358 | |||
| 359 | /* add h to each covered row */ | ||
| 360 | for (row = 0; row < nrows; row++) { | ||
| 361 | if (!GET1(crow, row)) | ||
| 362 | continue; | ||
| 363 | for (col = 0; col < ncols; col++) | ||
| 364 | mdist[row + nrows * col] += h; | ||
| 365 | } | ||
| 366 | |||
| 367 | /* subtract h from each uncovered column */ | ||
| 368 | for (col = 0; col < ncols; col++) { | ||
| 369 | if (GET1(ccol, col)) | ||
| 370 | continue; | ||
| 371 | for (row = 0; row < nrows; row++) | ||
| 372 | mdist[row + nrows * col] -= h; | ||
| 373 | } | ||
| 374 | |||
| 375 | /* move to step 3 */ | ||
| 376 | step3(ix, mdist, mstar, nmstar, | ||
| 377 | mprime, ccol, crow, nrows, ncols, | ||
| 378 | dmin); | ||
| 379 | } | ||
| 380 | |||
| 381 | void match_fingers(int ix[DIM_FINGER], int A[DIM2_FINGER], int nrow, int ncol) | ||
| 382 | { | ||
| 383 | ixoptimal(ix, A, nrow, ncol); | ||
| 384 | } | ||
| 385 | |||
diff --git a/match/test.c b/match/test.c deleted file mode 100644 index dabc083..0000000 --- a/match/test.c +++ /dev/null | |||
| @@ -1,135 +0,0 @@ | |||
| 1 | /*************************************************************************** | ||
| 2 | * | ||
| 3 | * Multitouch X driver | ||
| 4 | * Copyright (C) 2008 Henrik Rydberg <rydberg@euromail.se> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 19 | * | ||
| 20 | **************************************************************************/ | ||
| 21 | |||
| 22 | #include <match.h> | ||
| 23 | #include <xbypass.h> | ||
| 24 | #include <stdio.h> | ||
| 25 | #include <time.h> | ||
| 26 | |||
| 27 | #define ITS 1000000 | ||
| 28 | |||
| 29 | static void test1() | ||
| 30 | { | ||
| 31 | int A[] = { | ||
| 32 | 1013, | ||
| 33 | 3030660, | ||
| 34 | 3559354, | ||
| 35 | 12505925, | ||
| 36 | 19008450, | ||
| 37 | 6946421, | ||
| 38 | 6118613, | ||
| 39 | 698020, | ||
| 40 | 3021800, | ||
| 41 | 1017, | ||
| 42 | 37573, | ||
| 43 | 3242018, | ||
| 44 | 8152794, | ||
| 45 | 1266053, | ||
| 46 | 942941, | ||
| 47 | 462820, | ||
| 48 | }; | ||
| 49 | int index[DIM_FINGER], i; | ||
| 50 | match_fingers(index, A, 4, 4); | ||
| 51 | for (i = 0; i < 4; i++) | ||
| 52 | printf("match[%d] = %d\n", i, index[i]); | ||
| 53 | } | ||
| 54 | |||
| 55 | static void test2() | ||
| 56 | { | ||
| 57 | int A[] = { | ||
| 58 | 0, | ||
| 59 | 4534330, | ||
| 60 | 22653552, | ||
| 61 | 12252500, | ||
| 62 | 685352, | ||
| 63 | 4534330, | ||
| 64 | 0, | ||
| 65 | 9619317, | ||
| 66 | 28409530, | ||
| 67 | 6710170, | ||
| 68 | 22653552, | ||
| 69 | 9619317, | ||
| 70 | 0, | ||
| 71 | 47015292, | ||
| 72 | 29788572, | ||
| 73 | 2809040, | ||
| 74 | 10428866, | ||
| 75 | 38615920, | ||
| 76 | 17732500, | ||
| 77 | 719528, | ||
| 78 | 12113945, | ||
| 79 | 28196220, | ||
| 80 | 46778656, | ||
| 81 | 405, | ||
| 82 | 14175493, | ||
| 83 | }; | ||
| 84 | int index[DIM_FINGER], i; | ||
| 85 | match_fingers(index, A, 5, 5); | ||
| 86 | for (i = 0; i < 5; i++) | ||
| 87 | printf("match[%d] = %d\n", i, index[i]); | ||
| 88 | } | ||
| 89 | |||
| 90 | static void speed1() | ||
| 91 | { | ||
| 92 | /* column-by-column matrix */ | ||
| 93 | int A[DIM2_FINGER]; | ||
| 94 | int x1[DIM_FINGER] = { 1, 5, 2, 3, 4, 5, 6, 7, 8 }; | ||
| 95 | int y1[DIM_FINGER] = { 1, 5, 2, 3, 4, 6, 6, 7, 8 }; | ||
| 96 | int x2[DIM_FINGER] = { 1.1, 3, 2, 4, 5, 6, 7, 8 }; | ||
| 97 | int y2[DIM_FINGER] = { 1, 3, 2, 4, 5, 6, 7, 8 }; | ||
| 98 | int index[DIM_FINGER]; | ||
| 99 | int n1 = 4; | ||
| 100 | int n2 = 7; | ||
| 101 | |||
| 102 | int i, j; | ||
| 103 | |||
| 104 | for (i = 0; i < n1; i++) { | ||
| 105 | for (j = 0; j < n2; j++) { | ||
| 106 | A[i + n1 * j] = | ||
| 107 | (x1[i] - x2[j]) * (x1[i] - x2[j]) + | ||
| 108 | (y1[i] - y2[j]) * (y1[i] - y2[j]); | ||
| 109 | } | ||
| 110 | } | ||
| 111 | |||
| 112 | clock_t t1 = clock(); | ||
| 113 | for (i = 0; i < ITS; i++) | ||
| 114 | match_fingers(index, A, n1, n2); | ||
| 115 | clock_t t2 = clock(); | ||
| 116 | |||
| 117 | printf("%lf matches per second\n", | ||
| 118 | ITS * ((float)CLOCKS_PER_SEC / (t2 - t1))); | ||
| 119 | |||
| 120 | for (i = 0; i < n1; i++) | ||
| 121 | printf("match[%d] = %d\n", i, index[i]); | ||
| 122 | |||
| 123 | } | ||
| 124 | |||
| 125 | int main(int argc, char *argv[]) | ||
| 126 | { | ||
| 127 | printf("test1\n"); | ||
| 128 | test1(); | ||
| 129 | printf("test2\n"); | ||
| 130 | test2(); | ||
| 131 | printf("speed1\n"); | ||
| 132 | speed1(); | ||
| 133 | printf("done\n"); | ||
| 134 | return 0; | ||
| 135 | } | ||
diff --git a/mtdev/core.c b/mtdev/core.c deleted file mode 100644 index f13da13..0000000 --- a/mtdev/core.c +++ /dev/null | |||
| @@ -1,402 +0,0 @@ | |||
| 1 | /*************************************************************************** | ||
| 2 | * | ||
| 3 | * Multitouch X driver | ||
| 4 | * Copyright (C) 2008 Henrik Rydberg <rydberg@euromail.se> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 19 | * | ||
| 20 | **************************************************************************/ | ||
| 21 | |||
| 22 | #include "mtdev.h" | ||
| 23 | #include "mtbit.h" | ||
| 24 | |||
| 25 | /** | ||
| 26 | * struct MTSlot - represents the state of an input MT slot | ||
| 27 | * @abs: current values of ABS_MT axes for this slot | ||
| 28 | */ | ||
| 29 | struct MTSlot { | ||
| 30 | int abs[MT_ABS_SIZE]; | ||
| 31 | }; | ||
| 32 | |||
| 33 | /** | ||
| 34 | * struct MTDevState - MT slot parsing | ||
| 35 | * @data: array of scratch slot data | ||
| 36 | * @used: bitmask of currently used slots | ||
| 37 | * @slot: slot currently being modified | ||
| 38 | * @lastid: last used tracking id | ||
| 39 | */ | ||
| 40 | struct MTDevState { | ||
| 41 | struct MTSlot data[DIM_FINGER]; | ||
| 42 | bitmask_t used; | ||
| 43 | bitmask_t slot; | ||
| 44 | bitmask_t lastid; | ||
| 45 | }; | ||
| 46 | |||
| 47 | /** | ||
| 48 | * mtdev_init - init MT device | ||
| 49 | * @dev: device to initialize | ||
| 50 | * @caps: device capabilities | ||
| 51 | */ | ||
| 52 | int mtdev_init(struct MTDev *dev, const struct Capabilities *caps) | ||
| 53 | { | ||
| 54 | memset(dev, 0, sizeof(struct MTDev)); | ||
| 55 | if (!caps->has_mtdata) | ||
| 56 | return -ENODEV; | ||
| 57 | if (!caps->has_slot) { | ||
| 58 | dev->priv = calloc(1, sizeof(struct MTDevState)); | ||
| 59 | if (!dev->priv) | ||
| 60 | return -ENOMEM; | ||
| 61 | } | ||
| 62 | return 0; | ||
| 63 | } | ||
| 64 | |||
| 65 | static inline int istouch(const struct MTSlot *data, | ||
| 66 | const struct Capabilities *caps) | ||
| 67 | { | ||
| 68 | return data->abs[BIT_TOUCH_MAJOR] || !caps->has_abs[BIT_TOUCH_MAJOR]; | ||
| 69 | } | ||
| 70 | |||
| 71 | /* Dmitry Torokhov's code from kernel/driver/input/input.c */ | ||
| 72 | static int defuzz(int value, int old_val, int fuzz) | ||
| 73 | { | ||
| 74 | if (fuzz) { | ||
| 75 | if (value > old_val - fuzz / 2 && value < old_val + fuzz / 2) | ||
| 76 | return old_val; | ||
| 77 | |||
| 78 | if (value > old_val - fuzz && value < old_val + fuzz) | ||
| 79 | return (old_val * 3 + value) / 4; | ||
| 80 | |||
| 81 | if (value > old_val - fuzz * 2 && value < old_val + fuzz * 2) | ||
| 82 | return (old_val + value) / 2; | ||
| 83 | } | ||
| 84 | |||
| 85 | return value; | ||
| 86 | } | ||
| 87 | |||
| 88 | /* | ||
| 89 | * solve - solve contact matching problem | ||
| 90 | * @priv: parsing state | ||
| 91 | * @caps: device capabilities | ||
| 92 | * @sid: array of current tracking ids | ||
| 93 | * @sx: array of current position x | ||
| 94 | * @sy: array of current position y | ||
| 95 | * @sn: number of current contacts | ||
| 96 | * @nid: array of new or matched tracking ids, to be filled | ||
| 97 | * @nx: array of new position x | ||
| 98 | * @ny: array of new position y | ||
| 99 | * @nn: number of new contacts | ||
| 100 | * @touch: which of the new contacts to fill | ||
| 101 | */ | ||
| 102 | static void solve(struct MTDevState *priv, const struct Capabilities *caps, | ||
| 103 | const int *sid, const int *sx, const int *sy, int sn, | ||
| 104 | int *nid, const int *nx, const int *ny, int nn, | ||
| 105 | bitmask_t touch) | ||
| 106 | { | ||
| 107 | int A[DIM2_FINGER], *row; | ||
| 108 | int n2s[DIM_FINGER]; | ||
| 109 | int id, i, j; | ||
| 110 | |||
| 111 | /* setup distance matrix for contact matching */ | ||
| 112 | for (j = 0; j < sn; j++) { | ||
| 113 | row = A + nn * j; | ||
| 114 | for (i = 0; i < nn; i++) | ||
| 115 | row[i] = dist2(nx[i] - sx[j], ny[i] - sy[j]); | ||
| 116 | } | ||
| 117 | |||
| 118 | match_fingers(n2s, A, nn, sn); | ||
| 119 | |||
| 120 | /* update matched contacts and create new ones */ | ||
| 121 | foreach_bit(i, touch) { | ||
| 122 | j = n2s[i]; | ||
| 123 | id = j >= 0 ? sid[j] : caps->nullid; | ||
| 124 | while (id == caps->nullid) | ||
| 125 | id = ++priv->lastid; | ||
| 126 | nid[i] = id; | ||
| 127 | } | ||
| 128 | } | ||
| 129 | |||
| 130 | /* | ||
| 131 | * assign_tracking_id - assign tracking ids to all contacts | ||
| 132 | * @priv: parsing state | ||
| 133 | * @caps: device capabilities | ||
| 134 | * @data: array of all present contacts, to be filled | ||
| 135 | * @prop: array of all set contacts properties | ||
| 136 | * @size: number of contacts in array | ||
| 137 | * @touch: which of the contacts are actual touches | ||
| 138 | */ | ||
| 139 | static void assign_tracking_id(struct MTDevState *priv, | ||
| 140 | const struct Capabilities *caps, | ||
| 141 | struct MTSlot *data, bitmask_t *prop, | ||
| 142 | int size, bitmask_t touch) | ||
| 143 | { | ||
| 144 | int sid[DIM_FINGER], sx[DIM_FINGER], sy[DIM_FINGER], sn = 0; | ||
| 145 | int nid[DIM_FINGER], nx[DIM_FINGER], ny[DIM_FINGER], i; | ||
| 146 | foreach_bit(i, priv->used) { | ||
| 147 | sid[sn] = priv->data[i].abs[BIT_TRACKING_ID]; | ||
| 148 | sx[sn] = priv->data[i].abs[BIT_POSITION_X]; | ||
| 149 | sy[sn] = priv->data[i].abs[BIT_POSITION_Y]; | ||
| 150 | sn++; | ||
| 151 | } | ||
| 152 | for (i = 0; i < size; i++) { | ||
| 153 | nx[i] = data[i].abs[BIT_POSITION_X]; | ||
| 154 | ny[i] = data[i].abs[BIT_POSITION_Y]; | ||
| 155 | } | ||
| 156 | solve(priv, caps, sid, sx, sy, sn, nid, nx, ny, size, touch); | ||
| 157 | for (i = 0; i < size; i++) { | ||
| 158 | data[i].abs[BIT_TRACKING_ID] = | ||
| 159 | GETBIT(touch, i) ? nid[i] : caps->nullid; | ||
| 160 | prop[i] |= BITMASK(BIT_TRACKING_ID); | ||
| 161 | } | ||
| 162 | } | ||
| 163 | |||
| 164 | /* | ||
| 165 | * process_typeA - consume MT events and update parsing state | ||
| 166 | * @dev: MT device | ||
| 167 | * @data: array of all present contacts, to be filled | ||
| 168 | * @prop: array of all set contacts properties, to be filled | ||
| 169 | * | ||
| 170 | * This function is called when a SYN_REPORT is seen, right before | ||
| 171 | * that event is pushed to the queue. | ||
| 172 | * | ||
| 173 | * Returns -1 if the packet is not MT related and should not affect | ||
| 174 | * the current parsing state. | ||
| 175 | */ | ||
| 176 | static int process_typeA(struct MTDev *dev, | ||
| 177 | struct MTSlot *data, bitmask_t *prop) | ||
| 178 | { | ||
| 179 | struct input_event ev; | ||
| 180 | int consumed, mtcode; | ||
| 181 | int mtcnt = 0, size = 0; | ||
| 182 | prop[size] = 0; | ||
| 183 | while (!evbuf_empty(&dev->inbuf)) { | ||
| 184 | evbuf_get(&dev->inbuf, &ev); | ||
| 185 | consumed = 0; | ||
| 186 | switch (ev.type) { | ||
| 187 | case EV_SYN: | ||
| 188 | switch (ev.code) { | ||
| 189 | case SYN_MT_REPORT: | ||
| 190 | if (size < DIM_FINGER && | ||
| 191 | GETBIT(prop[size], BIT_POSITION_X) && | ||
| 192 | GETBIT(prop[size], BIT_POSITION_Y)) | ||
| 193 | size++; | ||
| 194 | if (size < DIM_FINGER) | ||
| 195 | prop[size] = 0; | ||
| 196 | mtcnt++; | ||
| 197 | consumed = 1; | ||
| 198 | break; | ||
| 199 | } | ||
| 200 | break; | ||
| 201 | case EV_KEY: | ||
| 202 | switch (ev.code) { | ||
| 203 | case BTN_TOUCH: | ||
| 204 | mtcnt++; | ||
| 205 | break; | ||
| 206 | } | ||
| 207 | break; | ||
| 208 | case EV_ABS: | ||
| 209 | if (size < DIM_FINGER && has_abs2mt(ev.code)) { | ||
| 210 | mtcode = abs2mt(ev.code); | ||
| 211 | data[size].abs[mtcode] = ev.value; | ||
| 212 | prop[size] |= BITMASK(mtcode); | ||
| 213 | mtcnt++; | ||
| 214 | consumed = 1; | ||
| 215 | } | ||
| 216 | break; | ||
| 217 | } | ||
| 218 | if (!consumed) | ||
| 219 | evbuf_put(&dev->outbuf, &ev); | ||
| 220 | } | ||
| 221 | return mtcnt ? size : -1; | ||
| 222 | } | ||
| 223 | |||
| 224 | /* | ||
| 225 | * process_typeB - propagate events without parsing | ||
| 226 | * @dev: MT device | ||
| 227 | * | ||
| 228 | * This function is called when a SYN_REPORT is seen, right before | ||
| 229 | * that event is pushed to the queue. | ||
| 230 | */ | ||
| 231 | static void process_typeB(struct MTDev *dev) | ||
| 232 | { | ||
| 233 | struct input_event ev; | ||
| 234 | while (!evbuf_empty(&dev->inbuf)) { | ||
| 235 | evbuf_get(&dev->inbuf, &ev); | ||
| 236 | evbuf_put(&dev->outbuf, &ev); | ||
| 237 | } | ||
| 238 | } | ||
| 239 | |||
| 240 | /* | ||
| 241 | * filter_data - apply input filtering on new incoming data | ||
| 242 | * @priv: parsing state | ||
| 243 | * @caps: device capabilities | ||
| 244 | * @data: the incoming data to filter | ||
| 245 | * @prop: the properties to filter | ||
| 246 | * @slot: the slot the data refers to | ||
| 247 | */ | ||
| 248 | static void filter_data(const struct MTDevState *priv, | ||
| 249 | const struct Capabilities *caps, | ||
| 250 | struct MTSlot *data, bitmask_t prop, | ||
| 251 | int slot) | ||
| 252 | { | ||
| 253 | int i; | ||
| 254 | foreach_bit(i, prop) { | ||
| 255 | int fuzz = caps->abs[i].fuzz; | ||
| 256 | int oldval = priv->data[slot].abs[i]; | ||
| 257 | data->abs[i] = defuzz(data->abs[i], oldval, fuzz); | ||
| 258 | } | ||
| 259 | } | ||
| 260 | |||
| 261 | /* | ||
| 262 | * push_slot_changes - propagate state changes | ||
| 263 | * @dev: MT device | ||
| 264 | * @data: the incoming data to propagate | ||
| 265 | * @prop: the properties to propagate | ||
| 266 | * @slot: the slot the data refers to | ||
| 267 | * @syn: reference to the SYN_REPORT event | ||
| 268 | */ | ||
| 269 | static void push_slot_changes(struct MTDev *dev, | ||
| 270 | const struct MTSlot *data, bitmask_t prop, | ||
| 271 | int slot, const struct input_event *syn) | ||
| 272 | { | ||
| 273 | struct MTDevState *priv = dev->priv; | ||
| 274 | struct input_event ev; | ||
| 275 | int i, count = 0; | ||
| 276 | foreach_bit(i, prop) | ||
| 277 | if (priv->data[slot].abs[i] != data->abs[i]) | ||
| 278 | count++; | ||
| 279 | if (!count) | ||
| 280 | return; | ||
| 281 | ev.time = syn->time; | ||
| 282 | ev.type = EV_ABS; | ||
| 283 | ev.code = ABS_MT_SLOT; | ||
| 284 | ev.value = slot; | ||
| 285 | if (priv->slot != ev.value) { | ||
| 286 | evbuf_put(&dev->outbuf, &ev); | ||
| 287 | priv->slot = ev.value; | ||
| 288 | } | ||
| 289 | foreach_bit(i, prop) { | ||
| 290 | ev.code = mt2abs(i); | ||
| 291 | ev.value = data->abs[i]; | ||
| 292 | if (priv->data[slot].abs[i] != ev.value) { | ||
| 293 | evbuf_put(&dev->outbuf, &ev); | ||
| 294 | priv->data[slot].abs[i] = ev.value; | ||
| 295 | } | ||
| 296 | } | ||
| 297 | } | ||
| 298 | |||
| 299 | /* | ||
| 300 | * apply_typeA_changes - parse and propagate state changes | ||
| 301 | * @dev: MT device | ||
| 302 | * @caps: device capabilities | ||
| 303 | * @data: array of data to apply | ||
| 304 | * @prop: array of properties to apply | ||
| 305 | * @size: number of contacts in array | ||
| 306 | * @syn: reference to the SYN_REPORT event | ||
| 307 | */ | ||
| 308 | static void apply_typeA_changes(struct MTDev *dev, | ||
| 309 | const struct Capabilities *caps, | ||
| 310 | struct MTSlot *data, const bitmask_t *prop, | ||
| 311 | int size, const struct input_event *syn) | ||
| 312 | { | ||
| 313 | struct MTDevState *priv = dev->priv; | ||
| 314 | bitmask_t unused = ~priv->used; | ||
| 315 | bitmask_t used = 0; | ||
| 316 | int i, slot, id; | ||
| 317 | for (i = 0; i < size; i++) { | ||
| 318 | id = data[i].abs[BIT_TRACKING_ID]; | ||
| 319 | foreach_bit(slot, priv->used) { | ||
| 320 | if (priv->data[slot].abs[BIT_TRACKING_ID] != id) | ||
| 321 | continue; | ||
| 322 | filter_data(priv, caps, &data[i], prop[i], slot); | ||
| 323 | push_slot_changes(dev, &data[i], prop[i], slot, syn); | ||
| 324 | SETBIT(used, slot); | ||
| 325 | id = caps->nullid; | ||
| 326 | break; | ||
| 327 | } | ||
| 328 | if (id != caps->nullid) { | ||
| 329 | slot = firstbit(unused); | ||
| 330 | push_slot_changes(dev, &data[i], prop[i], slot, syn); | ||
| 331 | SETBIT(used, slot); | ||
| 332 | CLEARBIT(unused, slot); | ||
| 333 | } | ||
| 334 | } | ||
| 335 | |||
| 336 | /* clear unused slots and update slot usage */ | ||
| 337 | foreach_bit(slot, priv->used & ~used) { | ||
| 338 | struct MTSlot tdata = priv->data[slot]; | ||
| 339 | bitmask_t tprop = BITMASK(BIT_TRACKING_ID); | ||
| 340 | tdata.abs[BIT_TRACKING_ID] = caps->nullid; | ||
| 341 | push_slot_changes(dev, &tdata, tprop, slot, syn); | ||
| 342 | } | ||
| 343 | priv->used = used; | ||
| 344 | } | ||
| 345 | |||
| 346 | /* | ||
| 347 | * convert_A_to_B - propagate a type A packet as a type B packet | ||
| 348 | * @dev: MT device | ||
| 349 | * @caps: device capabilities | ||
| 350 | * @syn: reference to the SYN_REPORT event | ||
| 351 | */ | ||
| 352 | static void convert_A_to_B(struct MTDev *dev, | ||
| 353 | const struct Capabilities *caps, | ||
| 354 | const struct input_event *syn) | ||
| 355 | { | ||
| 356 | struct MTSlot data[DIM_FINGER]; | ||
| 357 | bitmask_t prop[DIM_FINGER]; | ||
| 358 | int size = process_typeA(dev, data, prop); | ||
| 359 | if (size < 0) | ||
| 360 | return; | ||
| 361 | if (!caps->has_abs[BIT_TRACKING_ID]) { | ||
| 362 | bitmask_t touch = 0; | ||
| 363 | int i; | ||
| 364 | for (i = 0; i < size; i++) | ||
| 365 | MODBIT(touch, i, istouch(&data[i], caps)); | ||
| 366 | assign_tracking_id(dev->priv, caps, data, prop, size, touch); | ||
| 367 | } | ||
| 368 | apply_typeA_changes(dev, caps, data, prop, size, syn); | ||
| 369 | } | ||
| 370 | |||
| 371 | /** | ||
| 372 | * mtdev_put - insert event into MT device | ||
| 373 | * @dev: MT device | ||
| 374 | * @caps: device capabilities | ||
| 375 | * @syn: reference to the SYN_REPORT event | ||
| 376 | */ | ||
| 377 | void mtdev_put(struct MTDev *dev, | ||
| 378 | const struct Capabilities *caps, | ||
| 379 | const struct input_event *ev) | ||
| 380 | { | ||
| 381 | if (ev->type == EV_SYN && ev->code == SYN_REPORT) { | ||
| 382 | bitmask_t head = dev->outbuf.head; | ||
| 383 | if (dev->priv) | ||
| 384 | convert_A_to_B(dev, caps, ev); | ||
| 385 | else | ||
| 386 | process_typeB(dev); | ||
| 387 | if (dev->outbuf.head != head) | ||
| 388 | evbuf_put(&dev->outbuf, ev); | ||
| 389 | } else { | ||
| 390 | evbuf_put(&dev->inbuf, ev); | ||
| 391 | } | ||
| 392 | } | ||
| 393 | |||
| 394 | /** | ||
| 395 | * mtdev_destroy - destroy MT device | ||
| 396 | * @dev: MT device | ||
| 397 | */ | ||
| 398 | void mtdev_destroy(struct MTDev *dev) | ||
| 399 | { | ||
| 400 | free(dev->priv); | ||
| 401 | memset(dev, 0, sizeof(struct MTDev)); | ||
| 402 | } | ||
diff --git a/mtdev/iobuf.c b/mtdev/iobuf.c deleted file mode 100644 index 65c33f6..0000000 --- a/mtdev/iobuf.c +++ /dev/null | |||
| @@ -1,63 +0,0 @@ | |||
| 1 | /*************************************************************************** | ||
| 2 | * | ||
| 3 | * Multitouch X driver | ||
| 4 | * Copyright (C) 2008 Henrik Rydberg <rydberg@euromail.se> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 19 | * | ||
| 20 | **************************************************************************/ | ||
| 21 | |||
| 22 | #include <mtdev-iobuf.h> | ||
| 23 | #include <sys/poll.h> | ||
| 24 | |||
| 25 | void init_iobuf(struct IOBuffer *buf) | ||
| 26 | { | ||
| 27 | memset(buf, 0, sizeof(struct IOBuffer)); | ||
| 28 | buf->at = buf->begin; | ||
| 29 | buf->top = buf->at; | ||
| 30 | buf->end = buf->begin + DIM_BUFFER; | ||
| 31 | } | ||
| 32 | |||
| 33 | const struct input_event *get_iobuf_event(struct IOBuffer *buf, int fd) | ||
| 34 | { | ||
| 35 | const struct input_event *ev; | ||
| 36 | int n = buf->top - buf->at; | ||
| 37 | if (n < EVENT_SIZE) { | ||
| 38 | /* partial event is available: save it */ | ||
| 39 | if (buf->at != buf->begin && n > 0) | ||
| 40 | memmove(buf->begin, buf->at, n); | ||
| 41 | /* start from the beginning */ | ||
| 42 | buf->at = buf->begin; | ||
| 43 | buf->top = buf->at + n; | ||
| 44 | /* read more data */ | ||
| 45 | SYSCALL(n = read(fd, buf->top, buf->end - buf->top)); | ||
| 46 | if (n <= 0) | ||
| 47 | return NULL; | ||
| 48 | buf->top += n; | ||
| 49 | } | ||
| 50 | if (buf->top - buf->at < EVENT_SIZE) | ||
| 51 | return NULL; | ||
| 52 | ev = (const struct input_event *)buf->at; | ||
| 53 | buf->at += EVENT_SIZE; | ||
| 54 | return ev; | ||
| 55 | } | ||
| 56 | |||
| 57 | int poll_iobuf(struct IOBuffer *buf, int fd, int ms) | ||
| 58 | { | ||
| 59 | struct pollfd fds = { fd, POLLIN, 0 }; | ||
| 60 | if (buf->top != buf->at) | ||
| 61 | return 1; | ||
| 62 | return poll(&fds, 1, ms); | ||
| 63 | } | ||
diff --git a/mtdev/mapgen.c b/mtdev/mapgen.c deleted file mode 100644 index efb3524..0000000 --- a/mtdev/mapgen.c +++ /dev/null | |||
| @@ -1,69 +0,0 @@ | |||
| 1 | /*************************************************************************** | ||
| 2 | * | ||
| 3 | * Multitouch X driver | ||
| 4 | * Copyright (C) 2008 Henrik Rydberg <rydberg@euromail.se> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 19 | * | ||
| 20 | **************************************************************************/ | ||
| 21 | |||
| 22 | #include <common.h> | ||
| 23 | #include <fcntl.h> | ||
| 24 | #include <xbypass.h> | ||
| 25 | |||
| 26 | #define BIT_DEF(name) \ | ||
| 27 | printf("#define BIT_"#name" %d\n", \ | ||
| 28 | cabs2mt[ABS_MT_##name] - 1) | ||
| 29 | |||
| 30 | static unsigned int cabs2mt[ABS_CNT]; | ||
| 31 | static unsigned int cmt2abs[MT_ABS_SIZE]; | ||
| 32 | |||
| 33 | void init_caps() | ||
| 34 | { | ||
| 35 | static const int init_abs_map[MT_ABS_SIZE] = MT_SLOT_ABS_EVENTS; | ||
| 36 | int i; | ||
| 37 | for (i = 0; i < MT_ABS_SIZE; i++) { | ||
| 38 | cabs2mt[init_abs_map[i]] = i + 1; | ||
| 39 | cmt2abs[i] = init_abs_map[i]; | ||
| 40 | } | ||
| 41 | } | ||
| 42 | |||
| 43 | static inline const char *newln(int i, int n) | ||
| 44 | { | ||
| 45 | return i == n - 1 || i % 8 == 7 ? "\n" : ""; | ||
| 46 | } | ||
| 47 | |||
| 48 | int main(int argc, char *argv[]) | ||
| 49 | { | ||
| 50 | int i; | ||
| 51 | init_caps(); | ||
| 52 | printf("static const unsigned int map_abs2mt[ABS_CNT] = {\n"); | ||
| 53 | for (i = 0; i < ABS_CNT; i++) | ||
| 54 | printf(" 0x%04x,%s", cabs2mt[i], newln(i, ABS_CNT)); | ||
| 55 | printf("};\n\n"); | ||
| 56 | printf("static const unsigned int map_mt2abs[MT_ABS_SIZE] = {\n"); | ||
| 57 | for (i = 0; i < MT_ABS_SIZE; i++) | ||
| 58 | printf(" 0x%04x,%s", cmt2abs[i], newln(i, MT_ABS_SIZE)); | ||
| 59 | printf("};\n\n"); | ||
| 60 | BIT_DEF(TRACKING_ID); | ||
| 61 | BIT_DEF(POSITION_X); | ||
| 62 | BIT_DEF(POSITION_Y); | ||
| 63 | BIT_DEF(TOUCH_MAJOR); | ||
| 64 | BIT_DEF(TOUCH_MINOR); | ||
| 65 | BIT_DEF(WIDTH_MAJOR); | ||
| 66 | BIT_DEF(WIDTH_MINOR); | ||
| 67 | printf("\n"); | ||
| 68 | return 0; | ||
| 69 | } | ||
diff --git a/mtdev/test.c b/mtdev/test.c deleted file mode 100644 index 9f73fcd..0000000 --- a/mtdev/test.c +++ /dev/null | |||
| @@ -1,79 +0,0 @@ | |||
| 1 | /*************************************************************************** | ||
| 2 | * | ||
| 3 | * Multitouch X driver | ||
| 4 | * Copyright (C) 2008 Henrik Rydberg <rydberg@euromail.se> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 19 | * | ||
| 20 | **************************************************************************/ | ||
| 21 | |||
| 22 | #include "mtdev-iobuf.h" | ||
| 23 | #include "mtdev.h" | ||
| 24 | #include <fcntl.h> | ||
| 25 | #include <xbypass.h> | ||
| 26 | |||
| 27 | static void print_event(const struct input_event *ev) | ||
| 28 | { | ||
| 29 | static const mstime_t ms = 1000; | ||
| 30 | static int slot; | ||
| 31 | mstime_t evtime = ev->time.tv_usec / ms + ev->time.tv_sec * ms; | ||
| 32 | if (ev->type == EV_ABS && ev->code == ABS_MT_SLOT) | ||
| 33 | slot = ev->value; | ||
| 34 | fprintf(stderr, "%012llx: %04d: %04x %04x %d\n", | ||
| 35 | evtime, slot, ev->type, ev->code, ev->value); | ||
| 36 | } | ||
| 37 | |||
| 38 | static void loop_device(int fd) | ||
| 39 | { | ||
| 40 | struct Capabilities caps; | ||
| 41 | struct IOBuffer iobuf; | ||
| 42 | struct MTDev mtdev; | ||
| 43 | const struct input_event *ev; | ||
| 44 | struct input_event event; | ||
| 45 | if (read_capabilities(&caps, fd)) { | ||
| 46 | fprintf(stderr, "error: could not read device capabilities\n"); | ||
| 47 | return; | ||
| 48 | } | ||
| 49 | output_capabilities(&caps); | ||
| 50 | if (mtdev_init(&mtdev, &caps)) { | ||
| 51 | fprintf(stderr, "error: could not initialize device\n"); | ||
| 52 | return; | ||
| 53 | } | ||
| 54 | init_iobuf(&iobuf); | ||
| 55 | while (ev = get_iobuf_event(&iobuf, fd)) { | ||
| 56 | mtdev_put(&mtdev, &caps, ev); | ||
| 57 | while (!mtdev_empty(&mtdev)) { | ||
| 58 | mtdev_get(&mtdev, &event); | ||
| 59 | print_event(&event); | ||
| 60 | } | ||
| 61 | } | ||
| 62 | mtdev_destroy(&mtdev); | ||
| 63 | } | ||
| 64 | |||
| 65 | int main(int argc, char *argv[]) | ||
| 66 | { | ||
| 67 | if (argc < 2) { | ||
| 68 | fprintf(stderr, "Usage: test <mtdev>\n"); | ||
| 69 | return -1; | ||
| 70 | } | ||
| 71 | int fd = open(argv[1], O_RDONLY); | ||
| 72 | if (fd < 0) { | ||
| 73 | fprintf(stderr, "error: could not open file\n"); | ||
| 74 | return -1; | ||
| 75 | } | ||
| 76 | loop_device(fd); | ||
| 77 | close(fd); | ||
| 78 | return 0; | ||
| 79 | } | ||
diff --git a/mtdev/caps.c b/src/capabilities.c index 069816e..0d11669 100644 --- a/mtdev/caps.c +++ b/src/capabilities.c | |||
| @@ -19,8 +19,7 @@ | |||
| 19 | * | 19 | * |
| 20 | **************************************************************************/ | 20 | **************************************************************************/ |
| 21 | 21 | ||
| 22 | #include "mtdev-caps.h" | 22 | #include "capabilities.h" |
| 23 | #include "mtbit.h" | ||
| 24 | 23 | ||
| 25 | #define SETABS(c, x, map, key, fd) \ | 24 | #define SETABS(c, x, map, key, fd) \ |
| 26 | (c->has_##x = getbit(map, key) && getabs(&c->x, key, fd)) | 25 | (c->has_##x = getbit(map, key) && getabs(&c->x, key, fd)) |
| @@ -52,7 +51,7 @@ static int getabs(struct input_absinfo *abs, int key, int fd) | |||
| 52 | 51 | ||
| 53 | static int has_mt_data(const struct Capabilities *cap) | 52 | static int has_mt_data(const struct Capabilities *cap) |
| 54 | { | 53 | { |
| 55 | return cap->has_abs[BIT_POSITION_X] && cap->has_abs[BIT_POSITION_Y]; | 54 | return cap->has_abs[MTDEV_POSITION_X] && cap->has_abs[MTDEV_POSITION_Y]; |
| 56 | } | 55 | } |
| 57 | 56 | ||
| 58 | static int has_integrated_button(const struct Capabilities *cap) | 57 | static int has_integrated_button(const struct Capabilities *cap) |
| @@ -65,7 +64,7 @@ static int has_integrated_button(const struct Capabilities *cap) | |||
| 65 | 64 | ||
| 66 | static void default_fuzz(struct Capabilities *cap, unsigned int code, int sn) | 65 | static void default_fuzz(struct Capabilities *cap, unsigned int code, int sn) |
| 67 | { | 66 | { |
| 68 | int bit = abs2mt(code); | 67 | int bit = mtdev_abs2mt(code); |
| 69 | if (cap->has_abs[bit] && cap->abs[bit].fuzz == 0) | 68 | if (cap->has_abs[bit] && cap->abs[bit].fuzz == 0) |
| 70 | cap->abs[bit].fuzz = | 69 | cap->abs[bit].fuzz = |
| 71 | (cap->abs[bit].maximum - cap->abs[bit].minimum) / sn; | 70 | (cap->abs[bit].maximum - cap->abs[bit].minimum) / sn; |
| @@ -102,14 +101,11 @@ int read_capabilities(struct Capabilities *cap, int fd) | |||
| 102 | 101 | ||
| 103 | SETABS(cap, slot, absbits, ABS_MT_SLOT, fd); | 102 | SETABS(cap, slot, absbits, ABS_MT_SLOT, fd); |
| 104 | for (i = 0; i < MT_ABS_SIZE; i++) | 103 | for (i = 0; i < MT_ABS_SIZE; i++) |
| 105 | SETABS(cap, abs[i], absbits, mt2abs(i), fd); | 104 | SETABS(cap, abs[i], absbits, mtdev_mt2abs(i), fd); |
| 106 | 105 | ||
| 107 | cap->has_mtdata = has_mt_data(cap); | 106 | cap->has_mtdata = has_mt_data(cap); |
| 108 | cap->has_ibt = has_integrated_button(cap); | 107 | cap->has_ibt = has_integrated_button(cap); |
| 109 | 108 | ||
| 110 | if (cap->has_abs[BIT_TRACKING_ID]) | ||
| 111 | cap->nullid = cap->abs[BIT_TRACKING_ID].minimum - 1; | ||
| 112 | |||
| 113 | default_fuzz(cap, ABS_MT_POSITION_X, SN_COORD); | 109 | default_fuzz(cap, ABS_MT_POSITION_X, SN_COORD); |
| 114 | default_fuzz(cap, ABS_MT_POSITION_Y, SN_COORD); | 110 | default_fuzz(cap, ABS_MT_POSITION_Y, SN_COORD); |
| 115 | default_fuzz(cap, ABS_MT_TOUCH_MAJOR, SN_WIDTH); | 111 | default_fuzz(cap, ABS_MT_TOUCH_MAJOR, SN_WIDTH); |
| @@ -123,31 +119,31 @@ int read_capabilities(struct Capabilities *cap, int fd) | |||
| 123 | 119 | ||
| 124 | int get_cap_xsize(const struct Capabilities *cap) | 120 | int get_cap_xsize(const struct Capabilities *cap) |
| 125 | { | 121 | { |
| 126 | const struct input_absinfo *x = &cap->abs[BIT_POSITION_X]; | 122 | const struct input_absinfo *x = &cap->abs[MTDEV_POSITION_X]; |
| 127 | return x->maximum - x->minimum; | 123 | return x->maximum - x->minimum; |
| 128 | } | 124 | } |
| 129 | 125 | ||
| 130 | int get_cap_ysize(const struct Capabilities *cap) | 126 | int get_cap_ysize(const struct Capabilities *cap) |
| 131 | { | 127 | { |
| 132 | const struct input_absinfo *y = &cap->abs[BIT_POSITION_Y]; | 128 | const struct input_absinfo *y = &cap->abs[MTDEV_POSITION_Y]; |
| 133 | return y->maximum - y->minimum; | 129 | return y->maximum - y->minimum; |
| 134 | } | 130 | } |
| 135 | 131 | ||
| 136 | int get_cap_wsize(const struct Capabilities *cap) | 132 | int get_cap_wsize(const struct Capabilities *cap) |
| 137 | { | 133 | { |
| 138 | const struct input_absinfo *w = &cap->abs[BIT_TOUCH_MAJOR]; | 134 | const struct input_absinfo *w = &cap->abs[MTDEV_TOUCH_MAJOR]; |
| 139 | return w->maximum - w->minimum; | 135 | return w->maximum - w->minimum; |
| 140 | } | 136 | } |
| 141 | 137 | ||
| 142 | int get_cap_xmid(const struct Capabilities *cap) | 138 | int get_cap_xmid(const struct Capabilities *cap) |
| 143 | { | 139 | { |
| 144 | const struct input_absinfo *x = &cap->abs[BIT_POSITION_X]; | 140 | const struct input_absinfo *x = &cap->abs[MTDEV_POSITION_X]; |
| 145 | return (x->maximum + x->minimum) >> 1; | 141 | return (x->maximum + x->minimum) >> 1; |
| 146 | } | 142 | } |
| 147 | 143 | ||
| 148 | int get_cap_ymid(const struct Capabilities *cap) | 144 | int get_cap_ymid(const struct Capabilities *cap) |
| 149 | { | 145 | { |
| 150 | const struct input_absinfo *y = &cap->abs[BIT_POSITION_Y]; | 146 | const struct input_absinfo *y = &cap->abs[MTDEV_POSITION_Y]; |
| 151 | return (y->maximum + y->minimum) >> 1; | 147 | return (y->maximum + y->minimum) >> 1; |
| 152 | } | 148 | } |
| 153 | 149 | ||
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) | |||
| 26 | int i; | 26 | int i; |
| 27 | memset(s, 0, sizeof(struct HWState)); | 27 | memset(s, 0, sizeof(struct HWState)); |
| 28 | for (i = 0; i < DIM_FINGER; i++) | 28 | for (i = 0; i < DIM_FINGER; i++) |
| 29 | s->data[i].tracking_id = caps->nullid; | 29 | s->data[i].tracking_id = MT_ID_NULL; |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | static void finish_packet(struct HWState *s, const struct Capabilities *caps, | 32 | 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, | |||
| 35 | static const mstime_t ms = 1000; | 35 | static const mstime_t ms = 1000; |
| 36 | int i; | 36 | int i; |
| 37 | foreach_bit(i, s->used) { | 37 | foreach_bit(i, s->used) { |
| 38 | if (!caps->has_abs[BIT_TOUCH_MINOR]) | 38 | if (!caps->has_abs[MTDEV_TOUCH_MINOR]) |
| 39 | s->data[i].touch_minor = s->data[i].touch_major; | 39 | s->data[i].touch_minor = s->data[i].touch_major; |
| 40 | if (!caps->has_abs[BIT_WIDTH_MINOR]) | 40 | if (!caps->has_abs[MTDEV_WIDTH_MINOR]) |
| 41 | s->data[i].width_minor = s->data[i].width_major; | 41 | s->data[i].width_minor = s->data[i].width_major; |
| 42 | } | 42 | } |
| 43 | s->evtime = syn->time.tv_usec / ms + syn->time.tv_sec * ms; | 43 | s->evtime = syn->time.tv_usec / ms + syn->time.tv_sec * ms; |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | int hwstate_read(struct HWState *s, const struct Capabilities *caps, | 46 | static int read_event(struct HWState *s, const struct Capabilities *caps, |
| 47 | const struct input_event *ev) | 47 | const struct input_event *ev) |
| 48 | { | 48 | { |
| 49 | switch (ev->type) { | 49 | switch (ev->type) { |
| 50 | case EV_SYN: | 50 | case EV_SYN: |
| @@ -99,11 +99,21 @@ int hwstate_read(struct HWState *s, const struct Capabilities *caps, | |||
| 99 | break; | 99 | break; |
| 100 | case ABS_MT_TRACKING_ID: | 100 | case ABS_MT_TRACKING_ID: |
| 101 | s->data[s->slot].tracking_id = ev->value; | 101 | s->data[s->slot].tracking_id = ev->value; |
| 102 | MODBIT(s->used, s->slot, | 102 | MODBIT(s->used, s->slot, ev->value != MT_ID_NULL); |
| 103 | ev->value != caps->nullid); | ||
| 104 | break; | 103 | break; |
| 105 | } | 104 | } |
| 106 | break; | 105 | break; |
| 107 | } | 106 | } |
| 108 | return 0; | 107 | return 0; |
| 109 | } | 108 | } |
| 109 | |||
| 110 | int modify_hwstate(struct HWState *s, struct mtdev *dev, int fd, | ||
| 111 | const struct Capabilities *caps) | ||
| 112 | { | ||
| 113 | struct input_event ev; | ||
| 114 | int ret; | ||
| 115 | while ((ret = mtdev_get(dev, fd, &ev, 1)) > 0) | ||
| 116 | if (read_event(s, caps, &ev)) | ||
| 117 | return 1; | ||
| 118 | return ret; | ||
| 119 | } | ||
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, | |||
| 119 | const struct Capabilities *caps) | 119 | const struct Capabilities *caps) |
| 120 | { | 120 | { |
| 121 | const struct FingerState *f = state->finger; | 121 | const struct FingerState *f = state->finger; |
| 122 | int yclick = caps->abs[BIT_POSITION_Y].maximum - CLICK_AREA(caps); | 122 | int yclick = caps->abs[MTDEV_POSITION_Y].maximum - CLICK_AREA(caps); |
| 123 | 123 | ||
| 124 | int i; | 124 | int i; |
| 125 | 125 | ||
| 126 | if (state->nfinger < 2) { | 126 | if (state->nfinger < 2) { |
| 127 | m->pointing = m->fingers; | 127 | m->pointing = m->fingers; |
| 128 | m->ybar = caps->abs[BIT_POSITION_Y].maximum; | 128 | m->ybar = caps->abs[MTDEV_POSITION_Y].maximum; |
| 129 | return; | 129 | return; |
| 130 | } | 130 | } |
| 131 | 131 | ||
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) | |||
| 34 | 34 | ||
| 35 | int open_mtouch(struct MTouch *mt, int fd) | 35 | int open_mtouch(struct MTouch *mt, int fd) |
| 36 | { | 36 | { |
| 37 | mtdev_init(&mt->dev, &mt->caps); | 37 | mtdev_open(&mt->dev, fd); |
| 38 | init_iobuf(&mt->buf); | ||
| 39 | init_hwstate(&mt->hs, &mt->caps); | 38 | init_hwstate(&mt->hs, &mt->caps); |
| 40 | init_mtstate(&mt->prev_state); | 39 | init_mtstate(&mt->prev_state); |
| 41 | init_mtstate(&mt->state); | 40 | init_mtstate(&mt->state); |
| @@ -48,40 +47,19 @@ int open_mtouch(struct MTouch *mt, int fd) | |||
| 48 | return 0; | 47 | return 0; |
| 49 | } | 48 | } |
| 50 | 49 | ||
| 51 | |||
| 52 | int get_mtouch(struct MTouch *mt, int fd, struct input_event* ev, int ev_max) | ||
| 53 | { | ||
| 54 | const struct input_event *kev; | ||
| 55 | int count = 0; | ||
| 56 | while (count < ev_max) { | ||
| 57 | while (mtdev_empty(&mt->dev)) { | ||
| 58 | kev = get_iobuf_event(&mt->buf, fd); | ||
| 59 | if (!kev) | ||
| 60 | return count; | ||
| 61 | mtdev_put(&mt->dev, &mt->caps, kev); | ||
| 62 | } | ||
| 63 | mtdev_get(&mt->dev, &ev[count++]); | ||
| 64 | } | ||
| 65 | return count; | ||
| 66 | } | ||
| 67 | |||
| 68 | int close_mtouch(struct MTouch *mt, int fd) | 50 | int close_mtouch(struct MTouch *mt, int fd) |
| 69 | { | 51 | { |
| 70 | if (use_grab) { | 52 | if (use_grab) { |
| 71 | int rc; | 53 | int rc; |
| 72 | SYSCALL(rc = ioctl(fd, EVIOCGRAB, (pointer)0)); | 54 | SYSCALL(rc = ioctl(fd, EVIOCGRAB, (pointer)0)); |
| 73 | } | 55 | } |
| 74 | mtdev_destroy(&mt->dev); | 56 | mtdev_close(&mt->dev); |
| 75 | return 0; | 57 | return 0; |
| 76 | } | 58 | } |
| 77 | 59 | ||
| 78 | int read_packet(struct MTouch *mt, int fd) | 60 | int read_packet(struct MTouch *mt, int fd) |
| 79 | { | 61 | { |
| 80 | struct input_event ev; | 62 | int ret = modify_hwstate(&mt->hs, &mt->dev, fd, &mt->caps); |
| 81 | int ret; | ||
| 82 | while ((ret = get_mtouch(mt, fd, &ev, 1)) > 0) | ||
| 83 | if (hwstate_read(&mt->hs, &mt->caps, &ev)) | ||
| 84 | break; | ||
| 85 | if (ret <= 0) | 63 | if (ret <= 0) |
| 86 | return ret; | 64 | return ret; |
| 87 | extract_mtstate(&mt->state, &mt->hs, &mt->caps); | 65 | extract_mtstate(&mt->state, &mt->hs, &mt->caps); |
| @@ -97,7 +75,5 @@ int read_packet(struct MTouch *mt, int fd) | |||
| 97 | 75 | ||
| 98 | int has_delayed_gestures(struct MTouch *mt, int fd) | 76 | int has_delayed_gestures(struct MTouch *mt, int fd) |
| 99 | { | 77 | { |
| 100 | return mt->mem.wait && | 78 | return mt->mem.wait && mtdev_idle(&mt->dev, fd, mt->mem.wait); |
| 101 | mtdev_empty(&mt->dev) && | ||
| 102 | poll_iobuf(&mt->buf, fd, mt->mem.wait) == 0; | ||
| 103 | } | 79 | } |
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 @@ | |||
| 22 | #include "mtstate.h" | 22 | #include "mtstate.h" |
| 23 | 23 | ||
| 24 | #define TOUCH_WIDTH(hw) (0.05 * hw->width_major) | 24 | #define TOUCH_WIDTH(hw) (0.05 * hw->width_major) |
| 25 | #define TOUCH_SCALE(caps) (0.05 * caps->abs[BIT_TOUCH_MAJOR].maximum) | 25 | #define TOUCH_SCALE(caps) (0.05 * caps->abs[MTDEV_TOUCH_MAJOR].maximum) |
| 26 | 26 | ||
| 27 | #define THUMB_TOUCH(hw) (1.2 * hw->touch_minor) | 27 | #define THUMB_TOUCH(hw) (1.2 * hw->touch_minor) |
| 28 | #define THUMB_WIDTH_TOUCH(hw) (3 * hw->touch_major) | 28 | #define THUMB_WIDTH_TOUCH(hw) (3 * hw->touch_major) |
| @@ -37,9 +37,9 @@ void init_mtstate(struct MTState *s) | |||
| 37 | static int touching_finger(const struct FingerState *hw, | 37 | static int touching_finger(const struct FingerState *hw, |
| 38 | const struct Capabilities *caps) | 38 | const struct Capabilities *caps) |
| 39 | { | 39 | { |
| 40 | if (caps->has_abs[BIT_TOUCH_MAJOR] && caps->has_abs[BIT_WIDTH_MAJOR]) | 40 | if (caps->has_abs[MTDEV_TOUCH_MAJOR] && caps->has_abs[MTDEV_WIDTH_MAJOR]) |
| 41 | return hw->touch_major > TOUCH_WIDTH(hw); | 41 | return hw->touch_major > TOUCH_WIDTH(hw); |
| 42 | if (caps->has_abs[BIT_TOUCH_MAJOR]) | 42 | if (caps->has_abs[MTDEV_TOUCH_MAJOR]) |
| 43 | return hw->touch_major > TOUCH_SCALE(caps); | 43 | return hw->touch_major > TOUCH_SCALE(caps); |
| 44 | return 1; | 44 | return 1; |
| 45 | } | 45 | } |
| @@ -55,10 +55,10 @@ static int touching_finger(const struct FingerState *hw, | |||
| 55 | static int is_thumb(const struct FingerState *hw, | 55 | static int is_thumb(const struct FingerState *hw, |
| 56 | const struct Capabilities *caps) | 56 | const struct Capabilities *caps) |
| 57 | { | 57 | { |
| 58 | if (!caps->has_abs[BIT_TOUCH_MAJOR] || | 58 | if (!caps->has_abs[MTDEV_TOUCH_MAJOR] || |
| 59 | !caps->has_abs[BIT_TOUCH_MINOR] || | 59 | !caps->has_abs[MTDEV_TOUCH_MINOR] || |
| 60 | !caps->has_abs[BIT_WIDTH_MAJOR] || | 60 | !caps->has_abs[MTDEV_WIDTH_MAJOR] || |
| 61 | !caps->has_abs[BIT_WIDTH_MINOR]) | 61 | !caps->has_abs[MTDEV_WIDTH_MINOR]) |
| 62 | return 0; | 62 | return 0; |
| 63 | return hw->touch_major > THUMB_TOUCH(hw) && | 63 | return hw->touch_major > THUMB_TOUCH(hw) && |
| 64 | hw->width_major > THUMB_WIDTH_TOUCH(hw) && | 64 | hw->width_major > THUMB_WIDTH_TOUCH(hw) && |
| @@ -35,8 +35,8 @@ static void loop_device(int fd) | |||
| 35 | fprintf(stderr, "error: could not open device\n"); | 35 | fprintf(stderr, "error: could not open device\n"); |
| 36 | return; | 36 | return; |
| 37 | } | 37 | } |
| 38 | while (poll_iobuf(&mt.buf, fd, 5000)) { | 38 | while (mtdev_pull(&mt.dev, fd, 1) > 0) { |
| 39 | while (read_packet(&mt, fd) > 0) { | 39 | if (parse_event(&mt)) { |
| 40 | extract_gestures(&gs, &mt); | 40 | extract_gestures(&gs, &mt); |
| 41 | output_gesture(&gs); | 41 | output_gesture(&gs); |
| 42 | } | 42 | } |
