diff options
| -rw-r--r-- | include/grail-touch.h | 1 | ||||
| -rw-r--r-- | src/touch-caps.c | 37 | ||||
| -rw-r--r-- | src/touch-dev.c | 87 |
3 files changed, 123 insertions, 2 deletions
diff --git a/include/grail-touch.h b/include/grail-touch.h index acfc779..9c63c80 100644 --- a/include/grail-touch.h +++ b/include/grail-touch.h | |||
| @@ -72,6 +72,7 @@ struct touch_dev { | |||
| 72 | int state; | 72 | int state; |
| 73 | }; | 73 | }; |
| 74 | 74 | ||
| 75 | int touch_caps_is_supported(struct touch_dev *dev, int fd); | ||
| 75 | void touch_caps_init(struct touch_dev *dev); | 76 | void touch_caps_init(struct touch_dev *dev); |
| 76 | float touch_angle(const struct touch_dev *dev, int orientation); | 77 | float touch_angle(const struct touch_dev *dev, int orientation); |
| 77 | float touch_pressure(const struct touch_dev *dev, int pressure); | 78 | float touch_pressure(const struct touch_dev *dev, int pressure); |
diff --git a/src/touch-caps.c b/src/touch-caps.c index 7f243c5..a51912c 100644 --- a/src/touch-caps.c +++ b/src/touch-caps.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | ****************************************************************************/ | 21 | ****************************************************************************/ |
| 22 | 22 | ||
| 23 | #include <grail-touch.h> | 23 | #include <grail-touch.h> |
| 24 | #include <errno.h> | ||
| 24 | #include <math.h> | 25 | #include <math.h> |
| 25 | 26 | ||
| 26 | /* see mtdev-mapping.h */ | 27 | /* see mtdev-mapping.h */ |
| @@ -29,6 +30,42 @@ | |||
| 29 | #define MTDEV_ORIENTATION 4 | 30 | #define MTDEV_ORIENTATION 4 |
| 30 | #define MTDEV_PRESSURE 10 | 31 | #define MTDEV_PRESSURE 10 |
| 31 | 32 | ||
| 33 | #define SYSCALL(call) while (((call) == -1) && (errno == EINTR)) | ||
| 34 | |||
| 35 | static const int bits_per_long = 8 * sizeof(long); | ||
| 36 | |||
| 37 | static inline int nlongs(int nbit) | ||
| 38 | { | ||
| 39 | return (nbit + bits_per_long - 1) / bits_per_long; | ||
| 40 | } | ||
| 41 | |||
| 42 | static inline int getbit(const unsigned long *map, int key) | ||
| 43 | { | ||
| 44 | return (map[key / bits_per_long] >> (key % bits_per_long)) & 0x01; | ||
| 45 | } | ||
| 46 | |||
| 47 | int touch_caps_is_supported(struct touch_dev *dev, int fd) | ||
| 48 | { | ||
| 49 | unsigned long keybits[nlongs(KEY_MAX)]; | ||
| 50 | unsigned long absbits[nlongs(ABS_MAX)]; | ||
| 51 | int rc; | ||
| 52 | |||
| 53 | if (dev->mtdev.caps.has_mtdata) | ||
| 54 | return 1; | ||
| 55 | |||
| 56 | SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits)); | ||
| 57 | if (rc < 0) | ||
| 58 | return 0; | ||
| 59 | SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbits)), absbits)); | ||
| 60 | if (rc < 0) | ||
| 61 | return 0; | ||
| 62 | |||
| 63 | return getbit(absbits, ABS_X) && | ||
| 64 | getbit(absbits, ABS_Y) && | ||
| 65 | getbit(keybits, BTN_TOUCH) && | ||
| 66 | getbit(keybits, BTN_TOOL_DOUBLETAP); | ||
| 67 | } | ||
| 68 | |||
| 32 | void touch_caps_init(struct touch_dev *dev) | 69 | void touch_caps_init(struct touch_dev *dev) |
| 33 | { | 70 | { |
| 34 | const struct mtdev_caps *mt = &dev->mtdev.caps; | 71 | const struct mtdev_caps *mt = &dev->mtdev.caps; |
diff --git a/src/touch-dev.c b/src/touch-dev.c index 17082ed..d8e192e 100644 --- a/src/touch-dev.c +++ b/src/touch-dev.c | |||
| @@ -53,13 +53,45 @@ static void finish_touch(struct touch_dev *dev, struct touch_frame *frame) | |||
| 53 | dev->state = 0; | 53 | dev->state = 0; |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | static void finish_legacy(struct touch_dev *dev, struct touch_frame *frame) | ||
| 57 | { | ||
| 58 | static int trkid; | ||
| 59 | int i; | ||
| 60 | for (i = 0; i < frame->nactive; i++) { | ||
| 61 | struct touch *t = &frame->touch[i]; | ||
| 62 | t->active = 1; | ||
| 63 | if (t->id < 0) { | ||
| 64 | t->id = trkid++ & 0xffff; | ||
| 65 | frame->ncreate++; | ||
| 66 | } | ||
| 67 | if (i > 0) { | ||
| 68 | SET_PROP(x, frame->touch[0].x); | ||
| 69 | SET_PROP(y, frame->touch[0].y); | ||
| 70 | SET_PROP(pressure, frame->touch[0].pressure); | ||
| 71 | } | ||
| 72 | grail_mask_set(frame->touches, i); | ||
| 73 | } | ||
| 74 | for (i = frame->nactive; i < DIM_TOUCH; i++) { | ||
| 75 | struct touch *t = &frame->touch[i]; | ||
| 76 | t->active = 0; | ||
| 77 | if (t->id >= 0) { | ||
| 78 | t->id = -1; | ||
| 79 | frame->ndestroy++; | ||
| 80 | } | ||
| 81 | grail_mask_clear(frame->touches, i); | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 56 | static void finish_packet(struct touch_dev *dev, | 85 | static void finish_packet(struct touch_dev *dev, |
| 57 | const struct input_event *syn) | 86 | const struct input_event *syn) |
| 58 | { | 87 | { |
| 59 | static const touch_time_t ms = 1000; | 88 | static const touch_time_t ms = 1000; |
| 60 | struct touch_frame *frame = &dev->frame; | 89 | struct touch_frame *frame = &dev->frame; |
| 61 | int i, nslot = 0; | 90 | int i, nslot = 0; |
| 62 | finish_touch(dev, frame); | 91 | if (dev->mtdev.caps.has_mtdata) |
| 92 | finish_touch(dev, frame); | ||
| 93 | else | ||
| 94 | finish_legacy(dev, frame); | ||
| 63 | grail_mask_foreach(i, frame->touches, DIM_TOUCH_BYTES) | 95 | grail_mask_foreach(i, frame->touches, DIM_TOUCH_BYTES) |
| 64 | frame->active[nslot++] = &frame->touch[i]; | 96 | frame->active[nslot++] = &frame->touch[i]; |
| 65 | frame->nactive = nslot; | 97 | frame->nactive = nslot; |
| @@ -77,6 +109,21 @@ static int handle_abs_event(struct touch_dev *dev, | |||
| 77 | struct touch_frame *frame = &dev->frame; | 109 | struct touch_frame *frame = &dev->frame; |
| 78 | struct touch *t = &frame->touch[dev->slot]; | 110 | struct touch *t = &frame->touch[dev->slot]; |
| 79 | switch (ev->code) { | 111 | switch (ev->code) { |
| 112 | case ABS_X: | ||
| 113 | if (dev->mtdev.caps.has_mtdata) | ||
| 114 | return 0; | ||
| 115 | SET_PROP(x, ev->value); | ||
| 116 | return 0; | ||
| 117 | case ABS_Y: | ||
| 118 | if (dev->mtdev.caps.has_mtdata) | ||
| 119 | return 0; | ||
| 120 | SET_PROP(y, ev->value); | ||
| 121 | return 0; | ||
| 122 | case ABS_PRESSURE: | ||
| 123 | if (dev->mtdev.caps.has_mtdata) | ||
| 124 | return 0; | ||
| 125 | SET_PROP(pressure, ev->value); | ||
| 126 | return 0; | ||
| 80 | case ABS_MT_SLOT: | 127 | case ABS_MT_SLOT: |
| 81 | if (ev->value >= 0 && ev->value < DIM_TOUCH) { | 128 | if (ev->value >= 0 && ev->value < DIM_TOUCH) { |
| 82 | if (dev->slot != ev->value) | 129 | if (dev->slot != ev->value) |
| @@ -128,6 +175,40 @@ static int handle_abs_event(struct touch_dev *dev, | |||
| 128 | } | 175 | } |
| 129 | } | 176 | } |
| 130 | 177 | ||
| 178 | static int handle_key_event(struct touch_dev *dev, | ||
| 179 | const struct input_event *ev) | ||
| 180 | { | ||
| 181 | struct touch_frame *frame = &dev->frame; | ||
| 182 | if (dev->mtdev.caps.has_mtdata) | ||
| 183 | return 0; | ||
| 184 | switch (ev->code) { | ||
| 185 | case BTN_TOUCH: | ||
| 186 | if (ev->value && !frame->nactive) | ||
| 187 | frame->nactive = 1; | ||
| 188 | else if (!ev->value && frame->nactive) | ||
| 189 | frame->nactive = 0; | ||
| 190 | return 0; | ||
| 191 | case BTN_TOOL_FINGER: | ||
| 192 | if (ev->value) | ||
| 193 | frame->nactive = 1; | ||
| 194 | return 0; | ||
| 195 | case BTN_TOOL_DOUBLETAP: | ||
| 196 | if (ev->value) | ||
| 197 | frame->nactive = 2; | ||
| 198 | return 0; | ||
| 199 | case BTN_TOOL_TRIPLETAP: | ||
| 200 | if (ev->value) | ||
| 201 | frame->nactive = 3; | ||
| 202 | return 0; | ||
| 203 | case BTN_TOOL_QUADTAP: | ||
| 204 | if (ev->value) | ||
| 205 | frame->nactive = 4; | ||
| 206 | return 0; | ||
| 207 | default: | ||
| 208 | return 0; | ||
| 209 | } | ||
| 210 | } | ||
| 211 | |||
| 131 | int touch_dev_open(struct touch_dev *dev, int fd) | 212 | int touch_dev_open(struct touch_dev *dev, int fd) |
| 132 | { | 213 | { |
| 133 | struct touch_frame *frame = &dev->frame; | 214 | struct touch_frame *frame = &dev->frame; |
| @@ -139,7 +220,7 @@ int touch_dev_open(struct touch_dev *dev, int fd) | |||
| 139 | t->id = MT_ID_NULL; | 220 | t->id = MT_ID_NULL; |
| 140 | } | 221 | } |
| 141 | ret = mtdev_open(&dev->mtdev, fd); | 222 | ret = mtdev_open(&dev->mtdev, fd); |
| 142 | if (!ret && !dev->mtdev.caps.has_mtdata) | 223 | if (!ret && !touch_caps_is_supported(dev, fd)) |
| 143 | ret = -ENODEV; | 224 | ret = -ENODEV; |
| 144 | if (ret) | 225 | if (ret) |
| 145 | goto error; | 226 | goto error; |
| @@ -166,6 +247,8 @@ int touch_dev_pull(struct touch_dev *dev, int fd) | |||
| 166 | consumed++; | 247 | consumed++; |
| 167 | } else if (ev.type == EV_ABS) { | 248 | } else if (ev.type == EV_ABS) { |
| 168 | consumed += handle_abs_event(dev, &ev); | 249 | consumed += handle_abs_event(dev, &ev); |
| 250 | } else if (ev.type == EV_KEY) { | ||
| 251 | consumed += handle_key_event(dev, &ev); | ||
| 169 | } | 252 | } |
| 170 | if (!consumed && dev->event) | 253 | if (!consumed && dev->event) |
| 171 | dev->event(dev, &ev); | 254 | dev->event(dev, &ev); |
