diff options
| author | Henrik Rydberg <rydberg@euromail.se> | 2010-08-19 20:03:15 +0200 |
|---|---|---|
| committer | Henrik Rydberg <rydberg@euromail.se> | 2010-08-19 20:03:15 +0200 |
| commit | a704984e03d28b4be40e12c43be1b163bc9e09e2 (patch) | |
| tree | c4720a59aa77918ffef742d7ec7ef2a7e2eda16e /src/touch-dev.c | |
| parent | cb2cad3b8c506a08a6bdad548a10ff47f85ef38b (diff) | |
Simplify touch machinery
To be able to model touch information uniformly across all supported
devices, the semantics of the touch attributes has to be treated
explicitly. Drop the generic touch property array and replace it
by an actual structure. In addition, the touch-engine abstraction
turned out to not be needed, so drop it as well.
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'src/touch-dev.c')
| -rw-r--r-- | src/touch-dev.c | 164 |
1 files changed, 64 insertions, 100 deletions
diff --git a/src/touch-dev.c b/src/touch-dev.c index b88cb8d..287076a 100644 --- a/src/touch-dev.c +++ b/src/touch-dev.c | |||
| @@ -25,128 +25,97 @@ | |||
| 25 | #include <string.h> | 25 | #include <string.h> |
| 26 | #include <errno.h> | 26 | #include <errno.h> |
| 27 | 27 | ||
| 28 | /* from mtdev-mapping.h */ | 28 | #define SET_PROP(name, value) \ |
| 29 | #define MT_TOUCH_MAJOR 0 | 29 | if (t->name != value) { \ |
| 30 | #define MT_TOUCH_MINOR 1 | 30 | t->name = value; \ |
| 31 | #define MT_WIDTH_MAJOR 2 | 31 | frame->nmodify++; \ |
| 32 | #define MT_WIDTH_MINOR 3 | 32 | } |
| 33 | #define MT_ORIENTATION 4 | ||
| 34 | #define MT_POSITION_X 5 | ||
| 35 | #define MT_POSITION_Y 6 | ||
| 36 | #define MT_TRACKING_ID 9 | ||
| 37 | #define MT_PRESSURE 10 | ||
| 38 | |||
| 39 | struct touch_dev_impl { | ||
| 40 | int id[DIM_TOUCH]; | ||
| 41 | int slot; | ||
| 42 | int status; | ||
| 43 | grail_mask_t mask[DIM_TOUCH_BYTES]; | ||
| 44 | touch_prop_t prop[DIM_TOUCH_PROP]; | ||
| 45 | struct mtdev mtdev; | ||
| 46 | }; | ||
| 47 | |||
| 48 | static inline void set_info(struct touch_dev_caps *caps, int code, | ||
| 49 | const struct input_absinfo *info) | ||
| 50 | { | ||
| 51 | grail_mask_set(caps->mask, code); | ||
| 52 | caps->info[code] = *info; | ||
| 53 | } | ||
| 54 | |||
| 55 | static void set_caps(struct touch_dev_caps *caps, | ||
| 56 | const struct mtdev_caps *mtcaps) | ||
| 57 | { | ||
| 58 | if (mtcaps->has_abs[MT_POSITION_X]) | ||
| 59 | set_info(caps, TP_POS_X, &mtcaps->abs[MT_POSITION_X]); | ||
| 60 | if (mtcaps->has_abs[MT_POSITION_Y]) | ||
| 61 | set_info(caps, TP_POS_Y, &mtcaps->abs[MT_POSITION_Y]); | ||
| 62 | if (mtcaps->has_abs[MT_TOUCH_MAJOR]) | ||
| 63 | set_info(caps, TP_TOUCH_MAJOR, &mtcaps->abs[MT_TOUCH_MAJOR]); | ||
| 64 | if (mtcaps->has_abs[MT_TOUCH_MINOR]) | ||
| 65 | set_info(caps, TP_TOUCH_MINOR, &mtcaps->abs[MT_TOUCH_MINOR]); | ||
| 66 | if (mtcaps->has_abs[MT_WIDTH_MAJOR]) | ||
| 67 | set_info(caps, TP_WIDTH_MAJOR, &mtcaps->abs[MT_WIDTH_MAJOR]); | ||
| 68 | if (mtcaps->has_abs[MT_WIDTH_MINOR]) | ||
| 69 | set_info(caps, TP_WIDTH_MINOR, &mtcaps->abs[MT_WIDTH_MINOR]); | ||
| 70 | if (mtcaps->has_abs[MT_ORIENTATION]) | ||
| 71 | set_info(caps, TP_ORIENTATION, &mtcaps->abs[MT_ORIENTATION]); | ||
| 72 | if (mtcaps->has_abs[MT_PRESSURE]) | ||
| 73 | set_info(caps, TP_PRESSURE, &mtcaps->abs[MT_PRESSURE]); | ||
| 74 | } | ||
| 75 | |||
| 76 | static inline void set_prop(struct touch_dev_impl *x, int code, int value) | ||
| 77 | { | ||
| 78 | grail_mask_set(x->mask, code); | ||
| 79 | x->prop[code] = value; | ||
| 80 | } | ||
| 81 | 33 | ||
| 82 | static void finish_touch(struct touch_dev *dev, | 34 | static void finish_touch(struct touch_dev *dev, struct touch_frame *frame) |
| 83 | struct touch_dev_impl *x) | ||
| 84 | { | 35 | { |
| 85 | if (x->status < 0 && dev->destroy) | 36 | struct touch *t = &frame->touch[dev->slot]; |
| 86 | dev->destroy(dev, x->slot); | 37 | if (dev->state > 0) { |
| 87 | if (x->status > 0 && dev->create) | 38 | t->active = 1; |
| 88 | dev->create(dev, x->slot, x->mask, x->prop); | 39 | grail_mask_set(frame->touches, dev->slot); |
| 89 | if (x->status == 0 && dev->modify && | 40 | frame->ncreate++; |
| 90 | grail_mask_count(x->mask, sizeof(x->mask))) | 41 | } |
| 91 | dev->modify(dev, x->slot, x->mask, x->prop); | 42 | if (dev->state < 0) { |
| 92 | x->status = 0; | 43 | t->active = 0; |
| 93 | memset(x->mask, 0, sizeof(x->mask)); | 44 | grail_mask_clear(frame->touches, dev->slot); |
| 45 | frame->ndestroy++; | ||
| 46 | } | ||
| 47 | dev->state = 0; | ||
| 94 | } | 48 | } |
| 95 | 49 | ||
| 96 | static void finish_packet(struct touch_dev *dev, | 50 | static void finish_packet(struct touch_dev *dev, |
| 97 | const struct input_event *syn) | 51 | const struct input_event *syn) |
| 98 | { | 52 | { |
| 99 | finish_touch(dev, dev->impl); | 53 | static const touch_time_t ms = 1000; |
| 54 | struct touch_frame *frame = &dev->frame; | ||
| 55 | int i, nslot = 0; | ||
| 56 | finish_touch(dev, frame); | ||
| 57 | grail_mask_foreach(i, frame->touches, DIM_TOUCH_BYTES) | ||
| 58 | frame->active[nslot++] = &frame->touch[i]; | ||
| 59 | frame->nactive = nslot; | ||
| 60 | frame->time = syn->time.tv_usec / ms + syn->time.tv_sec * ms; | ||
| 100 | if (dev->sync) | 61 | if (dev->sync) |
| 101 | dev->sync(dev, syn); | 62 | dev->sync(dev, syn); |
| 63 | frame->ncreate = 0; | ||
| 64 | frame->nmodify = 0; | ||
| 65 | frame->ndestroy = 0; | ||
| 102 | } | 66 | } |
| 103 | 67 | ||
| 104 | static int handle_abs_event(struct touch_dev *dev, | 68 | static int handle_abs_event(struct touch_dev *dev, |
| 105 | const struct input_event *ev) | 69 | const struct input_event *ev) |
| 106 | { | 70 | { |
| 107 | struct touch_dev_impl *x = dev->impl; | 71 | struct touch_frame *frame = &dev->frame; |
| 72 | struct touch *t = &frame->touch[dev->slot]; | ||
| 108 | switch (ev->code) { | 73 | switch (ev->code) { |
| 109 | case ABS_MT_SLOT: | 74 | case ABS_MT_SLOT: |
| 110 | if (ev->value >= 0 && ev->value < DIM_TOUCH) { | 75 | if (ev->value >= 0 && ev->value < DIM_TOUCH) { |
| 111 | if (x->slot != ev->value) | 76 | if (dev->slot != ev->value) |
| 112 | finish_touch(dev, x); | 77 | finish_touch(dev, frame); |
| 113 | x->slot = ev->value; | 78 | dev->slot = ev->value; |
| 79 | t = &frame->touch[dev->slot]; | ||
| 114 | } | 80 | } |
| 115 | return 1; | 81 | return 1; |
| 116 | case ABS_MT_POSITION_X: | 82 | case ABS_MT_POSITION_X: |
| 117 | set_prop(x, TP_POS_X, ev->value); | 83 | SET_PROP(x, ev->value); |
| 118 | return 1; | 84 | return 1; |
| 119 | case ABS_MT_POSITION_Y: | 85 | case ABS_MT_POSITION_Y: |
| 120 | set_prop(x, TP_POS_Y, ev->value); | 86 | SET_PROP(y, ev->value); |
| 121 | return 1; | 87 | return 1; |
| 122 | case ABS_MT_TOUCH_MAJOR: | 88 | case ABS_MT_TOUCH_MAJOR: |
| 123 | set_prop(x, TP_TOUCH_MAJOR, ev->value); | 89 | SET_PROP(touch_major, ev->value); |
| 124 | return 1; | 90 | return 1; |
| 125 | case ABS_MT_TOUCH_MINOR: | 91 | case ABS_MT_TOUCH_MINOR: |
| 126 | set_prop(x, TP_TOUCH_MINOR, ev->value); | 92 | SET_PROP(touch_minor, ev->value); |
| 127 | return 1; | 93 | return 1; |
| 128 | case ABS_MT_WIDTH_MAJOR: | 94 | case ABS_MT_WIDTH_MAJOR: |
| 129 | set_prop(x, TP_WIDTH_MAJOR, ev->value); | 95 | SET_PROP(width_major, ev->value); |
| 130 | return 1; | 96 | return 1; |
| 131 | case ABS_MT_WIDTH_MINOR: | 97 | case ABS_MT_WIDTH_MINOR: |
| 132 | set_prop(x, TP_WIDTH_MINOR, ev->value); | 98 | SET_PROP(width_minor, ev->value); |
| 133 | return 1; | 99 | return 1; |
| 134 | case ABS_MT_ORIENTATION: | 100 | case ABS_MT_ORIENTATION: |
| 135 | set_prop(x, TP_ORIENTATION, ev->value); | 101 | SET_PROP(orientation, ev->value); |
| 136 | return 1; | 102 | return 1; |
| 137 | case ABS_MT_PRESSURE: | 103 | case ABS_MT_PRESSURE: |
| 138 | set_prop(x, TP_PRESSURE, ev->value); | 104 | SET_PROP(pressure, ev->value); |
| 105 | return 1; | ||
| 106 | case ABS_MT_TOOL_TYPE: | ||
| 107 | SET_PROP(tool_type, ev->value); | ||
| 139 | return 1; | 108 | return 1; |
| 140 | case ABS_MT_TRACKING_ID: | 109 | case ABS_MT_TRACKING_ID: |
| 141 | if (x->id[x->slot] != ev->value) { | 110 | if (t->id != ev->value) { |
| 142 | if (x->id[x->slot] != MT_ID_NULL) { | 111 | if (t->id != MT_ID_NULL) { |
| 143 | x->status = -1; | 112 | dev->state = -1; |
| 144 | finish_touch(dev, x); | 113 | finish_touch(dev, frame); |
| 145 | } | 114 | } |
| 146 | if (ev->value != MT_ID_NULL) | 115 | if (ev->value != MT_ID_NULL) |
| 147 | x->status = 1; | 116 | dev->state = 1; |
| 117 | t->id = ev->value; | ||
| 148 | } | 118 | } |
| 149 | x->id[x->slot] = ev->value; | ||
| 150 | return 1; | 119 | return 1; |
| 151 | default: | 120 | default: |
| 152 | return 0; | 121 | return 0; |
| @@ -155,38 +124,35 @@ static int handle_abs_event(struct touch_dev *dev, | |||
| 155 | 124 | ||
| 156 | int touch_dev_open(struct touch_dev *dev, int fd) | 125 | int touch_dev_open(struct touch_dev *dev, int fd) |
| 157 | { | 126 | { |
| 158 | struct touch_dev_impl *x; | 127 | struct touch_frame *frame = &dev->frame; |
| 159 | int ret, i; | 128 | int ret, i; |
| 160 | memset(dev, 0, sizeof(*dev)); | 129 | memset(dev, 0, sizeof(*dev)); |
| 161 | x = calloc(1, sizeof(*x)); | 130 | for (i = 0; i < DIM_TOUCH; i++) { |
| 162 | if (!x) | 131 | struct touch *t = &frame->touch[i]; |
| 163 | return -ENOMEM; | 132 | t->slot = i; |
| 164 | ret = mtdev_open(&x->mtdev, fd); | 133 | t->id = MT_ID_NULL; |
| 165 | if (!ret && !x->mtdev.caps.has_mtdata) | 134 | } |
| 135 | ret = mtdev_open(&dev->mtdev, fd); | ||
| 136 | if (!ret && !dev->mtdev.caps.has_mtdata) | ||
| 166 | ret = -ENODEV; | 137 | ret = -ENODEV; |
| 167 | if (ret) | 138 | if (ret) |
| 168 | goto error; | 139 | goto error; |
| 169 | for (i = 0; i < DIM_TOUCH; i++) | 140 | touch_caps_init(dev); |
| 170 | x->id[i] = MT_ID_NULL; | ||
| 171 | set_caps(&dev->caps, &x->mtdev.caps); | ||
| 172 | dev->impl = x; | ||
| 173 | return 0; | 141 | return 0; |
| 174 | error: | 142 | error: |
| 175 | free(x); | ||
| 176 | return ret; | 143 | return ret; |
| 177 | } | 144 | } |
| 178 | 145 | ||
| 179 | int touch_dev_idle(struct touch_dev *dev, int fd, int ms) | 146 | int touch_dev_idle(struct touch_dev *dev, int fd, int ms) |
| 180 | { | 147 | { |
| 181 | return mtdev_idle(&dev->impl->mtdev, fd, ms); | 148 | return mtdev_idle(&dev->mtdev, fd, ms); |
| 182 | } | 149 | } |
| 183 | 150 | ||
| 184 | int touch_dev_pull(struct touch_dev *dev, int fd) | 151 | int touch_dev_pull(struct touch_dev *dev, int fd) |
| 185 | { | 152 | { |
| 186 | struct touch_dev_impl *x = dev->impl; | ||
| 187 | struct input_event ev; | 153 | struct input_event ev; |
| 188 | int ret, count = 0, consumed; | 154 | int ret, count = 0, consumed; |
| 189 | while ((ret = mtdev_get(&x->mtdev, fd, &ev, 1)) > 0) { | 155 | while ((ret = mtdev_get(&dev->mtdev, fd, &ev, 1)) > 0) { |
| 190 | consumed = 0; | 156 | consumed = 0; |
| 191 | if (ev.type == EV_SYN) { | 157 | if (ev.type == EV_SYN) { |
| 192 | if (ev.code == SYN_REPORT) | 158 | if (ev.code == SYN_REPORT) |
| @@ -204,8 +170,6 @@ int touch_dev_pull(struct touch_dev *dev, int fd) | |||
| 204 | 170 | ||
| 205 | void touch_dev_close(struct touch_dev *dev, int fd) | 171 | void touch_dev_close(struct touch_dev *dev, int fd) |
| 206 | { | 172 | { |
| 207 | struct touch_dev_impl *x = dev->impl; | 173 | mtdev_close(&dev->mtdev); |
| 208 | mtdev_close(&x->mtdev); | ||
| 209 | free(x); | ||
| 210 | memset(dev, 0, sizeof(*dev)); | 174 | memset(dev, 0, sizeof(*dev)); |
| 211 | } | 175 | } |
