diff options
| author | Henrik Rydberg <rydberg@euromail.se> | 2011-01-02 11:00:52 +0100 |
|---|---|---|
| committer | Henrik Rydberg <rydberg@euromail.se> | 2011-01-02 12:39:07 +0100 |
| commit | c0666a895e7fe8e488332263fd106ced0ed7cab7 (patch) | |
| tree | fca88fbee4aaed6e1eed050a749ce6246a7f1966 /src/grail-api.c | |
| parent | 1e07054fbeab6e90f104c279d3246097dd838a17 (diff) | |
Replace touch logic with utouch frame engine
The original grail uses an internal touch framework and exports some
touch information as extended attributes to gesture events. This was
never quite the intention, but rather to expose gestures and touches
on a similar footing, such that grail can be input agnostic. This
patch starts off by replacing the internal touch framework with the
utouch-frame engine.
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'src/grail-api.c')
| -rw-r--r-- | src/grail-api.c | 280 |
1 files changed, 158 insertions, 122 deletions
diff --git a/src/grail-api.c b/src/grail-api.c index f38ca18..3aca75d 100644 --- a/src/grail-api.c +++ b/src/grail-api.c | |||
| @@ -30,27 +30,124 @@ | |||
| 30 | #include <malloc.h> | 30 | #include <malloc.h> |
| 31 | #include <errno.h> | 31 | #include <errno.h> |
| 32 | 32 | ||
| 33 | static void tp_event(struct touch_dev *dev, | 33 | #define DIM_FRAMES 100 |
| 34 | const struct input_event *ev) | 34 | #define FRAME_RATE 100 |
| 35 | |||
| 36 | void grail_filter_abs_events(struct grail *ge, int usage) | ||
| 35 | { | 37 | { |
| 36 | struct grail *ge = dev->priv; | ||
| 37 | struct grail_impl *x = ge->impl; | 38 | struct grail_impl *x = ge->impl; |
| 38 | if (ev->type == EV_ABS) { | 39 | x->filter_abs = usage; |
| 39 | return; | 40 | } |
| 41 | |||
| 42 | static void init_impl(struct grail_impl *x) | ||
| 43 | { | ||
| 44 | int i; | ||
| 45 | |||
| 46 | if (evemu_has_event(x->evemu, EV_ABS, ABS_X)) { | ||
| 47 | x->emin_x = evemu_get_abs_minimum(x->evemu, ABS_X); | ||
| 48 | x->emin_y = evemu_get_abs_minimum(x->evemu, ABS_Y); | ||
| 49 | x->emax_x = evemu_get_abs_maximum(x->evemu, ABS_X); | ||
| 50 | x->emax_y = evemu_get_abs_maximum(x->evemu, ABS_Y); | ||
| 51 | } else { | ||
| 52 | struct utouch_surface *s = utouch_frame_get_surface(x->fh); | ||
| 53 | x->emin_x = s->min_x; | ||
| 54 | x->emin_y = s->min_y; | ||
| 55 | x->emax_x = s->max_x; | ||
| 56 | x->emax_y = s->max_y; | ||
| 40 | } | 57 | } |
| 41 | if (ev->type == EV_KEY) { | 58 | } |
| 42 | switch (ev->code) { | 59 | |
| 43 | case BTN_TOUCH: | 60 | int grail_open(struct grail *ge, int fd) |
| 44 | case BTN_TOOL_FINGER: | 61 | { |
| 45 | case BTN_TOOL_DOUBLETAP: | 62 | struct grail_impl *x; |
| 46 | case BTN_TOOL_TRIPLETAP: | 63 | int ret; |
| 47 | case BTN_TOOL_QUADTAP: | 64 | x = calloc(1, sizeof(*x)); |
| 48 | return; | 65 | if (!x) |
| 49 | } | 66 | return -ENOMEM; |
| 67 | |||
| 68 | x->evemu = evemu_new(0); | ||
| 69 | if (!x->evemu) { | ||
| 70 | ret = -ENOMEM; | ||
| 71 | goto freemem; | ||
| 50 | } | 72 | } |
| 51 | evbuf_put(&x->evbuf, ev); | 73 | ret = evemu_extract(x->evemu, fd); |
| 74 | if (ret) | ||
| 75 | goto freemem; | ||
| 76 | if (!utouch_frame_is_supported_mtdev(x->evemu)) { | ||
| 77 | ret = -ENODEV; | ||
| 78 | goto freemem; | ||
| 79 | } | ||
| 80 | x->mtdev = mtdev_new_open(fd); | ||
| 81 | if (!x->mtdev) { | ||
| 82 | ret = -ENOMEM; | ||
| 83 | goto freemem; | ||
| 84 | } | ||
| 85 | |||
| 86 | x->fh = utouch_frame_new_engine(DIM_FRAMES, DIM_TOUCH, FRAME_RATE); | ||
| 87 | if (!x->fh) { | ||
| 88 | ret = -ENOMEM; | ||
| 89 | goto freedev; | ||
| 90 | } | ||
| 91 | ret = utouch_frame_init_mtdev(x->fh, x->evemu); | ||
| 92 | if (ret) | ||
| 93 | goto freeframe; | ||
| 94 | |||
| 95 | init_impl(x); | ||
| 96 | ge->impl = x; | ||
| 97 | |||
| 98 | ret = gin_init(ge); | ||
| 99 | if (ret) | ||
| 100 | goto freeframe; | ||
| 101 | |||
| 102 | ret = gru_init(ge); | ||
| 103 | if (ret) | ||
| 104 | goto freegin; | ||
| 105 | |||
| 106 | return 0; | ||
| 107 | freegin: | ||
| 108 | gin_destroy(ge); | ||
| 109 | freeframe: | ||
| 110 | utouch_frame_delete_engine(x->fh); | ||
| 111 | freedev: | ||
| 112 | mtdev_close_delete(x->mtdev); | ||
| 113 | freemem: | ||
| 114 | evemu_delete(x->evemu); | ||
| 115 | free(x); | ||
| 116 | ge->impl = 0; | ||
| 117 | return ret; | ||
| 118 | } | ||
| 119 | |||
| 120 | void grail_close(struct grail *ge, int fd) | ||
| 121 | { | ||
| 122 | struct grail_impl *x = ge->impl; | ||
| 123 | void *status; | ||
| 124 | gru_destroy(ge); | ||
| 125 | gin_destroy(ge); | ||
| 126 | utouch_frame_delete_engine(x->fh); | ||
| 127 | mtdev_close_delete(x->mtdev); | ||
| 128 | evemu_delete(x->evemu); | ||
| 129 | free(x); | ||
| 130 | ge->impl = 0; | ||
| 52 | } | 131 | } |
| 53 | 132 | ||
| 133 | int grail_idle(struct grail *ge, int fd, int ms) | ||
| 134 | { | ||
| 135 | struct grail_impl *x = ge->impl; | ||
| 136 | return mtdev_idle(x->mtdev, fd, ms); | ||
| 137 | } | ||
| 138 | |||
| 139 | void grail_get_units(const struct grail *ge, | ||
| 140 | struct grail_coord *min, struct grail_coord *max) | ||
| 141 | { | ||
| 142 | struct utouch_surface *s = utouch_frame_get_surface(ge->impl->fh); | ||
| 143 | min->x = s->min_x; | ||
| 144 | min->y = s->min_y; | ||
| 145 | max->x = s->max_x; | ||
| 146 | max->y = s->max_y; | ||
| 147 | } | ||
| 148 | |||
| 149 | // legacy glue below | ||
| 150 | |||
| 54 | static void evput(struct grail_impl *x, struct timeval time, | 151 | static void evput(struct grail_impl *x, struct timeval time, |
| 55 | unsigned type, unsigned code, int value) | 152 | unsigned type, unsigned code, int value) |
| 56 | { | 153 | { |
| @@ -76,47 +173,19 @@ static void report_up(struct grail_impl *impl, const struct input_event *syn) | |||
| 76 | impl->report_status = 0; | 173 | impl->report_status = 0; |
| 77 | } | 174 | } |
| 78 | 175 | ||
| 79 | #define SYSCALL(call) while (((call) == -1) && (errno == EINTR)) | ||
| 80 | |||
| 81 | static int getabs(struct input_absinfo *abs, int key, int fd) | ||
| 82 | { | ||
| 83 | int rc; | ||
| 84 | SYSCALL(rc = ioctl(fd, EVIOCGABS(key), abs)); | ||
| 85 | return rc >= 0; | ||
| 86 | } | ||
| 87 | |||
| 88 | static void set_emulation_caps(struct grail_impl *impl, int fd) | ||
| 89 | { | ||
| 90 | struct touch_caps *emu = &impl->emu; | ||
| 91 | struct input_absinfo info; | ||
| 92 | |||
| 93 | memset(emu, 0, sizeof(*emu)); | ||
| 94 | |||
| 95 | if (getabs(&info, ABS_X, fd)) { | ||
| 96 | emu->min_x = info.minimum; | ||
| 97 | emu->max_x = info.maximum; | ||
| 98 | } | ||
| 99 | if (getabs(&info, ABS_Y, fd)) { | ||
| 100 | emu->min_y = info.minimum; | ||
| 101 | emu->max_y = info.maximum; | ||
| 102 | } | ||
| 103 | } | ||
| 104 | |||
| 105 | static void set_pointer(struct grail_impl *impl) | 176 | static void set_pointer(struct grail_impl *impl) |
| 106 | { | 177 | { |
| 107 | struct touch_dev *dev = &impl->dev; | 178 | struct utouch_surface *s = utouch_frame_get_surface(impl->fh); |
| 108 | struct touch_caps *caps = &dev->caps; | 179 | const struct utouch_frame *frame = impl->frame; |
| 109 | struct touch_caps *emu = &impl->emu; | ||
| 110 | struct touch_frame *frame = &dev->frame; | ||
| 111 | int best_x, best_y, best_d = -1; | 180 | int best_x, best_y, best_d = -1; |
| 112 | int i; | 181 | int i; |
| 113 | 182 | ||
| 114 | for (i = 0; i < frame->nactive; i++) { | 183 | for (i = 0; i < frame->num_active; i++) { |
| 115 | struct touch *t = frame->active[i]; | 184 | const struct utouch_contact *t = frame->active[i]; |
| 116 | float u = (t->x - caps->min_x) / (caps->max_x - caps->min_x); | 185 | float u = (t->x - s->min_x) / (s->max_x - s->min_x); |
| 117 | float v = (t->y - caps->min_y) / (caps->max_y - caps->min_y); | 186 | float v = (t->y - s->min_y) / (s->max_y - s->min_y); |
| 118 | int x = emu->min_x + u * (emu->max_x - emu->min_x); | 187 | int x = impl->emin_x + u * (impl->emax_x - impl->emin_x); |
| 119 | int y = emu->min_y + v * (emu->max_y - emu->min_y); | 188 | int y = impl->emin_y + v * (impl->emax_y - impl->emin_y); |
| 120 | int d = abs(x - impl->pointer_x) + abs(y - impl->pointer_y); | 189 | int d = abs(x - impl->pointer_x) + abs(y - impl->pointer_y); |
| 121 | if (best_d < 0 || d < best_d) { | 190 | if (best_d < 0 || d < best_d) { |
| 122 | best_x = x; | 191 | best_x = x; |
| @@ -181,15 +250,18 @@ static void handle_abs_events(struct grail *ge, const struct input_event *syn) | |||
| 181 | } | 250 | } |
| 182 | } | 251 | } |
| 183 | 252 | ||
| 184 | static void tp_sync(struct touch_dev *dev, | 253 | static void report_frame(struct grail *ge, |
| 185 | const struct input_event *syn) | 254 | const struct utouch_frame *frame, |
| 255 | const struct input_event *syn) | ||
| 186 | { | 256 | { |
| 187 | struct grail *ge = dev->priv; | 257 | |
| 188 | struct grail_impl *impl = ge->impl; | 258 | struct grail_impl *impl = ge->impl; |
| 189 | int head = impl->evbuf.head; | 259 | int head = impl->evbuf.head; |
| 190 | struct input_event iev; | 260 | struct input_event iev; |
| 191 | struct grail_event gev; | 261 | struct grail_event gev; |
| 192 | struct touch_frame *frame = &dev->frame; | 262 | |
| 263 | ge->impl->frame = frame; | ||
| 264 | |||
| 193 | gin_frame_begin(ge, frame); | 265 | gin_frame_begin(ge, frame); |
| 194 | gru_recognize(ge, frame); | 266 | gru_recognize(ge, frame); |
| 195 | gin_frame_end(ge, frame); | 267 | gin_frame_end(ge, frame); |
| @@ -211,78 +283,42 @@ static void tp_sync(struct touch_dev *dev, | |||
| 211 | } | 283 | } |
| 212 | } | 284 | } |
| 213 | 285 | ||
| 214 | void grail_filter_abs_events(struct grail *ge, int usage) | 286 | static void grail_pump_mtdev(struct grail *ge, const struct input_event *ev) |
| 215 | { | ||
| 216 | struct grail_impl *x = ge->impl; | ||
| 217 | x->filter_abs = usage; | ||
| 218 | } | ||
| 219 | |||
| 220 | int grail_open(struct grail *ge, int fd) | ||
| 221 | { | ||
| 222 | struct grail_impl *x; | ||
| 223 | int ret; | ||
| 224 | x = calloc(1, sizeof(*x)); | ||
| 225 | if (!x) | ||
| 226 | return -ENOMEM; | ||
| 227 | ge->impl = x; | ||
| 228 | |||
| 229 | ret = touch_dev_open(&x->dev, fd); | ||
| 230 | if (ret) | ||
| 231 | goto freemem; | ||
| 232 | set_emulation_caps(x, fd); | ||
| 233 | x->dev.event = tp_event; | ||
| 234 | x->dev.sync = tp_sync; | ||
| 235 | x->dev.priv = ge; | ||
| 236 | |||
| 237 | ret = gin_init(ge); | ||
| 238 | if (ret) | ||
| 239 | goto freedev; | ||
| 240 | |||
| 241 | ret = gru_init(ge); | ||
| 242 | if (ret) | ||
| 243 | goto freegin; | ||
| 244 | |||
| 245 | return 0; | ||
| 246 | freegin: | ||
| 247 | gin_destroy(ge); | ||
| 248 | freedev: | ||
| 249 | touch_dev_close(&x->dev, fd); | ||
| 250 | freemem: | ||
| 251 | free(x); | ||
| 252 | ge->impl = 0; | ||
| 253 | return ret; | ||
| 254 | } | ||
| 255 | |||
| 256 | void grail_close(struct grail *ge, int fd) | ||
| 257 | { | 287 | { |
| 258 | struct grail_impl *x = ge->impl; | 288 | struct grail_impl *impl = ge->impl; |
| 259 | void *status; | 289 | const struct utouch_frame *frame; |
| 260 | gru_destroy(ge); | ||
| 261 | gin_destroy(ge); | ||
| 262 | touch_dev_close(&x->dev, fd); | ||
| 263 | free(ge->impl); | ||
| 264 | ge->impl = 0; | ||
| 265 | } | ||
| 266 | 290 | ||
| 267 | int grail_idle(struct grail *ge, int fd, int ms) | 291 | if (ev->type == EV_SYN || ev->type == EV_ABS) { |
| 268 | { | 292 | frame = utouch_frame_pump_mtdev(impl->fh, ev); |
| 269 | struct grail_impl *x = ge->impl; | 293 | if (frame) |
| 270 | return touch_dev_idle(&x->dev, fd, ms); | 294 | report_frame(ge, frame, ev); |
| 295 | } else if (ev->type == EV_KEY) { | ||
| 296 | switch (ev->code) { | ||
| 297 | case BTN_TOUCH: | ||
| 298 | case BTN_TOOL_FINGER: | ||
| 299 | case BTN_TOOL_DOUBLETAP: | ||
| 300 | case BTN_TOOL_TRIPLETAP: | ||
| 301 | case BTN_TOOL_QUADTAP: | ||
| 302 | break; | ||
| 303 | default: | ||
| 304 | evbuf_put(&impl->evbuf, ev); | ||
| 305 | break; | ||
| 306 | } | ||
| 307 | } else { | ||
| 308 | evbuf_put(&impl->evbuf, ev); | ||
| 309 | } | ||
| 271 | } | 310 | } |
| 272 | 311 | ||
| 273 | int grail_pull(struct grail *ge, int fd) | 312 | int grail_pull(struct grail *ge, int fd) |
| 274 | { | 313 | { |
| 275 | struct grail_impl *x = ge->impl; | 314 | struct grail_impl *impl = ge->impl; |
| 276 | return touch_dev_pull(&x->dev, fd); | 315 | struct input_event ev; |
| 277 | } | 316 | int ret, count = 0; |
| 278 | 317 | ||
| 279 | void grail_get_units(const struct grail *ge, | 318 | while ((ret = mtdev_get(impl->mtdev, fd, &ev, 1)) > 0) { |
| 280 | struct grail_coord *min, struct grail_coord *max) | 319 | grail_pump_mtdev(ge, &ev); |
| 281 | { | 320 | count++; |
| 282 | const struct touch_caps *caps = &ge->impl->dev.caps; | 321 | } |
| 283 | min->x = caps->min_x; | ||
| 284 | min->y = caps->min_y; | ||
| 285 | max->x = caps->max_x; | ||
| 286 | max->y = caps->max_y; | ||
| 287 | } | ||
| 288 | 322 | ||
| 323 | return count > 0 ? count : ret; | ||
| 324 | } | ||
