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 | |
| 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>
| -rw-r--r-- | INSTALL | 4 | ||||
| -rw-r--r-- | configure.ac | 4 | ||||
| -rw-r--r-- | include/grail-touch.h | 85 | ||||
| -rw-r--r-- | src/Makefile.am | 7 | ||||
| -rw-r--r-- | src/gebuf.h | 4 | ||||
| -rw-r--r-- | src/gestures-drag.c | 6 | ||||
| -rw-r--r-- | src/gestures-pinch.c | 6 | ||||
| -rw-r--r-- | src/gestures-rotate.c | 6 | ||||
| -rw-r--r-- | src/gestures-tapping.c | 4 | ||||
| -rw-r--r-- | src/grail-api.c | 280 | ||||
| -rw-r--r-- | src/grail-event.c | 33 | ||||
| -rw-r--r-- | src/grail-gestures.c | 38 | ||||
| -rw-r--r-- | src/grail-gestures.h | 16 | ||||
| -rw-r--r-- | src/grail-impl.h | 17 | ||||
| -rw-r--r-- | src/grail-inserter.c | 31 | ||||
| -rw-r--r-- | src/grail-inserter.h | 17 | ||||
| -rw-r--r-- | src/grail-recognizer.c | 3 | ||||
| -rw-r--r-- | src/grail-recognizer.h | 3 | ||||
| -rw-r--r-- | src/touch-caps.c | 117 | ||||
| -rw-r--r-- | src/touch-dev.c | 264 | ||||
| -rw-r--r-- | tools/Makefile.am | 2 |
21 files changed, 259 insertions, 688 deletions
| @@ -1,7 +1,7 @@ | |||
| 1 | grail - Gesture Recognition And Instantiation Library | 1 | grail - Gesture Recognition And Instantiation Library |
| 2 | 2 | ||
| 3 | To build, you need to have the autoconf, libtool and mtdev-dev packages | 3 | To build, you need to have the autoconf, libtool, mtdev-dev, |
| 4 | installed. Then, do | 4 | libutouch-evemu-dev and libutouch-frame packages installed. Then, do |
| 5 | 5 | ||
| 6 | ./autogen.sh | 6 | ./autogen.sh |
| 7 | ./configure | 7 | ./configure |
diff --git a/configure.ac b/configure.ac index 0f75818..ceb9258 100644 --- a/configure.ac +++ b/configure.ac | |||
| @@ -22,7 +22,9 @@ AC_PROG_LIBTOOL | |||
| 22 | AC_PROG_CC | 22 | AC_PROG_CC |
| 23 | AC_PROG_INSTALL | 23 | AC_PROG_INSTALL |
| 24 | 24 | ||
| 25 | PKG_CHECK_MODULES([MTDEV], [mtdev >= 1.0]) | 25 | PKG_CHECK_MODULES([MTDEV], [mtdev >= 1.1]) |
| 26 | PKG_CHECK_MODULES([EVEMU], [utouch-evemu >= 1.0]) | ||
| 27 | PKG_CHECK_MODULES([FRAME], [utouch-frame >= 1.0]) | ||
| 26 | 28 | ||
| 27 | AC_CONFIG_FILES([Makefile | 29 | AC_CONFIG_FILES([Makefile |
| 28 | src/Makefile | 30 | src/Makefile |
diff --git a/include/grail-touch.h b/include/grail-touch.h deleted file mode 100644 index 9c63c80..0000000 --- a/include/grail-touch.h +++ /dev/null | |||
| @@ -1,85 +0,0 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * | ||
| 3 | * grail - Gesture Recognition And Instantiation Library | ||
| 4 | * | ||
| 5 | * Copyright (C) 2010 Canonical Ltd. | ||
| 6 | * Copyright (C) 2010 Henrik Rydberg <rydberg@bitmath.org> | ||
| 7 | * | ||
| 8 | * This program is free software: you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the | ||
| 10 | * Free Software Foundation, either version 3 of the License, or (at your | ||
| 11 | * option) any later version. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, but | ||
| 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 16 | * General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License along | ||
| 19 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 20 | * | ||
| 21 | ****************************************************************************/ | ||
| 22 | |||
| 23 | #ifndef _GRAIL_TOUCH_H | ||
| 24 | #define _GRAIL_TOUCH_H | ||
| 25 | |||
| 26 | #include <grail-bits.h> | ||
| 27 | #include <mtdev.h> | ||
| 28 | |||
| 29 | #define DIM_TOUCH 32 | ||
| 30 | #define DIM_TOUCH_BYTES ((DIM_TOUCH + 7) >> 3) | ||
| 31 | |||
| 32 | typedef __u64 touch_time_t; | ||
| 33 | |||
| 34 | struct touch { | ||
| 35 | int active; | ||
| 36 | int slot; | ||
| 37 | int id; | ||
| 38 | int tool_type; | ||
| 39 | int x, y; | ||
| 40 | int touch_major; | ||
| 41 | int touch_minor; | ||
| 42 | int width_major; | ||
| 43 | int width_minor; | ||
| 44 | int orientation; | ||
| 45 | int pressure; | ||
| 46 | }; | ||
| 47 | |||
| 48 | struct touch_frame { | ||
| 49 | int nactive; | ||
| 50 | int ncreate, nmodify, ndestroy; | ||
| 51 | touch_time_t time; | ||
| 52 | grail_mask_t touches[DIM_TOUCH_BYTES]; | ||
| 53 | struct touch *active[DIM_TOUCH]; | ||
| 54 | struct touch touch[DIM_TOUCH]; | ||
| 55 | }; | ||
| 56 | |||
| 57 | struct touch_caps { | ||
| 58 | float min_x, max_x; | ||
| 59 | float min_y, max_y; | ||
| 60 | float min_orient, max_orient; | ||
| 61 | float min_press, max_press; | ||
| 62 | }; | ||
| 63 | |||
| 64 | struct touch_dev { | ||
| 65 | void (*event)(struct touch_dev *dev, const struct input_event *ev); | ||
| 66 | void (*sync)(struct touch_dev *dev, const struct input_event *syn); | ||
| 67 | void *priv; | ||
| 68 | struct mtdev mtdev; | ||
| 69 | struct touch_frame frame; | ||
| 70 | struct touch_caps caps; | ||
| 71 | int slot; | ||
| 72 | int state; | ||
| 73 | }; | ||
| 74 | |||
| 75 | int touch_caps_is_supported(struct touch_dev *dev, int fd); | ||
| 76 | void touch_caps_init(struct touch_dev *dev); | ||
| 77 | float touch_angle(const struct touch_dev *dev, int orientation); | ||
| 78 | float touch_pressure(const struct touch_dev *dev, int pressure); | ||
| 79 | |||
| 80 | int touch_dev_open(struct touch_dev *dev, int fd); | ||
| 81 | int touch_dev_idle(struct touch_dev *dev, int fd, int ms); | ||
| 82 | int touch_dev_pull(struct touch_dev *dev, int fd); | ||
| 83 | void touch_dev_close(struct touch_dev *dev, int fd); | ||
| 84 | |||
| 85 | #endif | ||
diff --git a/src/Makefile.am b/src/Makefile.am index dd2af2b..bb1c4c5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am | |||
| @@ -3,14 +3,14 @@ lib_LTLIBRARIES = libutouch-grail.la | |||
| 3 | libutouch_grail_la_LDFLAGS = \ | 3 | libutouch_grail_la_LDFLAGS = \ |
| 4 | -version-info @LIB_VERSION@ \ | 4 | -version-info @LIB_VERSION@ \ |
| 5 | -lm \ | 5 | -lm \ |
| 6 | $(MTDEV_LIBS) | 6 | $(MTDEV_LIBS) \ |
| 7 | $(EVEMU_LIBS) \ | ||
| 8 | $(FRAME_LIBS) | ||
| 7 | 9 | ||
| 8 | libutouch_grail_la_SOURCES = \ | 10 | libutouch_grail_la_SOURCES = \ |
| 9 | evbuf.h \ | 11 | evbuf.h \ |
| 10 | gebuf.h \ | 12 | gebuf.h \ |
| 11 | grailbuf.h \ | 13 | grailbuf.h \ |
| 12 | touch-dev.c \ | ||
| 13 | touch-caps.c \ | ||
| 14 | grail-bits.c \ | 14 | grail-bits.c \ |
| 15 | grail-inserter.c \ | 15 | grail-inserter.c \ |
| 16 | grail-inserter.h \ | 16 | grail-inserter.h \ |
| @@ -34,5 +34,4 @@ libutouch_grailincludedir = $(includedir) | |||
| 34 | libutouch_grailinclude_HEADERS = \ | 34 | libutouch_grailinclude_HEADERS = \ |
| 35 | $(top_srcdir)/include/grail-bits.h \ | 35 | $(top_srcdir)/include/grail-bits.h \ |
| 36 | $(top_srcdir)/include/grail-types.h \ | 36 | $(top_srcdir)/include/grail-types.h \ |
| 37 | $(top_srcdir)/include/grail-touch.h \ | ||
| 38 | $(top_srcdir)/include/grail.h | 37 | $(top_srcdir)/include/grail.h |
diff --git a/src/gebuf.h b/src/gebuf.h index 460e134..0cd9219 100644 --- a/src/gebuf.h +++ b/src/gebuf.h | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | #ifndef _GRAIL_GESTURE_BUFFER_H | 23 | #ifndef _GRAIL_GESTURE_BUFFER_H |
| 24 | #define _GRAIL_GESTURE_BUFFER_H | 24 | #define _GRAIL_GESTURE_BUFFER_H |
| 25 | 25 | ||
| 26 | #include <grail.h> | 26 | #include "grail-impl.h" |
| 27 | 27 | ||
| 28 | #define DIM_GESTURE_EVENTS 512 | 28 | #define DIM_GESTURE_EVENTS 512 |
| 29 | 29 | ||
| @@ -31,7 +31,7 @@ struct gesture_event { | |||
| 31 | int status; | 31 | int status; |
| 32 | int ntouch; | 32 | int ntouch; |
| 33 | int nprop; | 33 | int nprop; |
| 34 | touch_time_t time; | 34 | utouch_frame_time_t time; |
| 35 | struct grail_coord pos; | 35 | struct grail_coord pos; |
| 36 | grail_prop_t prop[DIM_GRAIL_PROP]; | 36 | grail_prop_t prop[DIM_GRAIL_PROP]; |
| 37 | }; | 37 | }; |
diff --git a/src/gestures-drag.c b/src/gestures-drag.c index 2ced765..05272da 100644 --- a/src/gestures-drag.c +++ b/src/gestures-drag.c | |||
| @@ -35,7 +35,7 @@ static const int getype[DIM_TOUCH + 1] = { | |||
| 35 | 35 | ||
| 36 | static void set_props(const struct gesture_inserter *gin, | 36 | static void set_props(const struct gesture_inserter *gin, |
| 37 | struct combo_model *s, const struct move_model *m, | 37 | struct combo_model *s, const struct move_model *m, |
| 38 | const struct touch_frame *frame) | 38 | const struct utouch_frame *frame) |
| 39 | { | 39 | { |
| 40 | if (m->single) { | 40 | if (m->single) { |
| 41 | s->prop[GRAIL_PROP_DRAG_DX] = | 41 | s->prop[GRAIL_PROP_DRAG_DX] = |
| @@ -59,7 +59,7 @@ static void set_props(const struct gesture_inserter *gin, | |||
| 59 | static const int fm_mask = 0x03; | 59 | static const int fm_mask = 0x03; |
| 60 | 60 | ||
| 61 | int gru_drag(struct grail *ge, | 61 | int gru_drag(struct grail *ge, |
| 62 | const struct touch_frame *frame) | 62 | const struct utouch_frame *frame) |
| 63 | { | 63 | { |
| 64 | struct gesture_recognizer *gru = ge->gru; | 64 | struct gesture_recognizer *gru = ge->gru; |
| 65 | struct combo_model *state = &gru->drag; | 65 | struct combo_model *state = &gru->drag; |
| @@ -89,7 +89,7 @@ int gru_drag(struct grail *ge, | |||
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | int gru_windrag(struct grail *ge, | 91 | int gru_windrag(struct grail *ge, |
| 92 | const struct touch_frame *frame) | 92 | const struct utouch_frame *frame) |
| 93 | { | 93 | { |
| 94 | struct gesture_recognizer *gru = ge->gru; | 94 | struct gesture_recognizer *gru = ge->gru; |
| 95 | struct combo_model *state = &gru->windrag; | 95 | struct combo_model *state = &gru->windrag; |
diff --git a/src/gestures-pinch.c b/src/gestures-pinch.c index 45f1cb3..fa8a626 100644 --- a/src/gestures-pinch.c +++ b/src/gestures-pinch.c | |||
| @@ -38,7 +38,7 @@ static const int fm_mask = 0x04; | |||
| 38 | static void set_props(const struct gesture_inserter *gin, | 38 | static void set_props(const struct gesture_inserter *gin, |
| 39 | struct combo_model *s, | 39 | struct combo_model *s, |
| 40 | const struct move_model *m, | 40 | const struct move_model *m, |
| 41 | const struct touch_frame *frame) | 41 | const struct utouch_frame *frame) |
| 42 | { | 42 | { |
| 43 | s->prop[GRAIL_PROP_PINCH_DR] = gin->scale_r * m->fm[FM_R].action_delta; | 43 | s->prop[GRAIL_PROP_PINCH_DR] = gin->scale_r * m->fm[FM_R].action_delta; |
| 44 | s->prop[GRAIL_PROP_PINCH_VR] = gin->scale_r * m->fm[FM_R].velocity; | 44 | s->prop[GRAIL_PROP_PINCH_VR] = gin->scale_r * m->fm[FM_R].velocity; |
| @@ -48,7 +48,7 @@ static void set_props(const struct gesture_inserter *gin, | |||
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | int gru_pinch(struct grail *ge, | 50 | int gru_pinch(struct grail *ge, |
| 51 | const struct touch_frame *frame) | 51 | const struct utouch_frame *frame) |
| 52 | { | 52 | { |
| 53 | struct gesture_recognizer *gru = ge->gru; | 53 | struct gesture_recognizer *gru = ge->gru; |
| 54 | struct combo_model *state = &gru->pinch; | 54 | struct combo_model *state = &gru->pinch; |
| @@ -79,7 +79,7 @@ int gru_pinch(struct grail *ge, | |||
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | int gru_winpinch(struct grail *ge, | 81 | int gru_winpinch(struct grail *ge, |
| 82 | const struct touch_frame *frame) | 82 | const struct utouch_frame *frame) |
| 83 | { | 83 | { |
| 84 | struct gesture_recognizer *gru = ge->gru; | 84 | struct gesture_recognizer *gru = ge->gru; |
| 85 | struct combo_model *state = &gru->winpinch; | 85 | struct combo_model *state = &gru->winpinch; |
diff --git a/src/gestures-rotate.c b/src/gestures-rotate.c index 8985257..fde0db8 100644 --- a/src/gestures-rotate.c +++ b/src/gestures-rotate.c | |||
| @@ -37,7 +37,7 @@ static const int fm_mask = 0x08; | |||
| 37 | 37 | ||
| 38 | static void set_props(const struct gesture_inserter *gin, | 38 | static void set_props(const struct gesture_inserter *gin, |
| 39 | struct combo_model *s, const struct move_model *m, | 39 | struct combo_model *s, const struct move_model *m, |
| 40 | const struct touch_frame *frame) | 40 | const struct utouch_frame *frame) |
| 41 | { | 41 | { |
| 42 | s->prop[GRAIL_PROP_ROTATE_DA] = m->fm[FM_A].action_delta; | 42 | s->prop[GRAIL_PROP_ROTATE_DA] = m->fm[FM_A].action_delta; |
| 43 | s->prop[GRAIL_PROP_ROTATE_VA] = m->fm[FM_A].velocity; | 43 | s->prop[GRAIL_PROP_ROTATE_VA] = m->fm[FM_A].velocity; |
| @@ -47,7 +47,7 @@ static void set_props(const struct gesture_inserter *gin, | |||
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | int gru_rotate(struct grail *ge, | 49 | int gru_rotate(struct grail *ge, |
| 50 | const struct touch_frame *frame) | 50 | const struct utouch_frame *frame) |
| 51 | { | 51 | { |
| 52 | struct gesture_recognizer *gru = ge->gru; | 52 | struct gesture_recognizer *gru = ge->gru; |
| 53 | struct combo_model *state = &gru->rotate; | 53 | struct combo_model *state = &gru->rotate; |
| @@ -78,7 +78,7 @@ int gru_rotate(struct grail *ge, | |||
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | int gru_winrotate(struct grail *ge, | 80 | int gru_winrotate(struct grail *ge, |
| 81 | const struct touch_frame *frame) | 81 | const struct utouch_frame *frame) |
| 82 | { | 82 | { |
| 83 | struct gesture_recognizer *gru = ge->gru; | 83 | struct gesture_recognizer *gru = ge->gru; |
| 84 | struct combo_model *state = &gru->winrotate; | 84 | struct combo_model *state = &gru->winrotate; |
diff --git a/src/gestures-tapping.c b/src/gestures-tapping.c index aa8e6d6..6d71642 100644 --- a/src/gestures-tapping.c +++ b/src/gestures-tapping.c | |||
| @@ -30,7 +30,7 @@ static const int fm_mask = 0x07; | |||
| 30 | 30 | ||
| 31 | static void set_props(const struct gesture_inserter *gin, | 31 | static void set_props(const struct gesture_inserter *gin, |
| 32 | struct tapping_model *s, const struct move_model *m, | 32 | struct tapping_model *s, const struct move_model *m, |
| 33 | const struct touch_frame *frame) | 33 | const struct utouch_frame *frame) |
| 34 | { | 34 | { |
| 35 | s->prop[GRAIL_PROP_TAP_DT] = m->time - s->start; | 35 | s->prop[GRAIL_PROP_TAP_DT] = m->time - s->start; |
| 36 | s->prop[GRAIL_PROP_TAP_X] = gin_prop_x(gin, m->fm[FM_X].value); | 36 | s->prop[GRAIL_PROP_TAP_X] = gin_prop_x(gin, m->fm[FM_X].value); |
| @@ -40,7 +40,7 @@ static void set_props(const struct gesture_inserter *gin, | |||
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | int gru_tapping(struct grail *ge, | 42 | int gru_tapping(struct grail *ge, |
| 43 | const struct touch_frame *frame) | 43 | const struct utouch_frame *frame) |
| 44 | { | 44 | { |
| 45 | struct gesture_recognizer *gru = ge->gru; | 45 | struct gesture_recognizer *gru = ge->gru; |
| 46 | struct tapping_model *state = &gru->tapping; | 46 | struct tapping_model *state = &gru->tapping; |
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 | } | ||
diff --git a/src/grail-event.c b/src/grail-event.c index 23fdbb3..9c0e437 100644 --- a/src/grail-event.c +++ b/src/grail-event.c | |||
| @@ -28,17 +28,17 @@ | |||
| 28 | #include <math.h> | 28 | #include <math.h> |
| 29 | 29 | ||
| 30 | static void compute_bbox(struct grail_coord *min, struct grail_coord *max, | 30 | static void compute_bbox(struct grail_coord *min, struct grail_coord *max, |
| 31 | const struct touch_frame *frame) | 31 | const struct utouch_frame *frame) |
| 32 | { | 32 | { |
| 33 | float x, y; | 33 | float x, y; |
| 34 | int i; | 34 | int i; |
| 35 | if (frame->nactive < 1) | 35 | if (frame->num_active < 1) |
| 36 | return; | 36 | return; |
| 37 | x = frame->active[0]->x; | 37 | x = frame->active[0]->x; |
| 38 | y = frame->active[0]->y; | 38 | y = frame->active[0]->y; |
| 39 | min->x = max->x = x; | 39 | min->x = max->x = x; |
| 40 | min->y = max->y = y; | 40 | min->y = max->y = y; |
| 41 | for (i = 1; i < frame->nactive; i++) { | 41 | for (i = 1; i < frame->num_active; i++) { |
| 42 | x = frame->active[i]->x; | 42 | x = frame->active[i]->x; |
| 43 | y = frame->active[i]->y; | 43 | y = frame->active[i]->y; |
| 44 | if (x < min->x) | 44 | if (x < min->x) |
| @@ -53,10 +53,10 @@ static void compute_bbox(struct grail_coord *min, struct grail_coord *max, | |||
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | int gin_add_contact_props(const struct gesture_inserter *gin, | 55 | int gin_add_contact_props(const struct gesture_inserter *gin, |
| 56 | grail_prop_t *prop, const struct touch_frame *frame) | 56 | grail_prop_t *prop, const struct utouch_frame *frame) |
| 57 | { | 57 | { |
| 58 | struct grail_coord min, max; | 58 | struct grail_coord min, max; |
| 59 | int i, n = 0, ntouch = frame->nactive; | 59 | int i, n = 0, ntouch = frame->num_active; |
| 60 | if (!ntouch) | 60 | if (!ntouch) |
| 61 | return n; | 61 | return n; |
| 62 | if (ntouch > 5) | 62 | if (ntouch > 5) |
| @@ -67,7 +67,7 @@ int gin_add_contact_props(const struct gesture_inserter *gin, | |||
| 67 | prop[n++] = gin_prop_x(gin, max.x); | 67 | prop[n++] = gin_prop_x(gin, max.x); |
| 68 | prop[n++] = gin_prop_y(gin, max.y); | 68 | prop[n++] = gin_prop_y(gin, max.y); |
| 69 | for (i = 0; i < ntouch; i++) { | 69 | for (i = 0; i < ntouch; i++) { |
| 70 | const struct touch *ct = frame->active[i]; | 70 | const struct utouch_contact *ct = frame->active[i]; |
| 71 | prop[n++] = ct->id; | 71 | prop[n++] = ct->id; |
| 72 | prop[n++] = gin_prop_x(gin, ct->x); | 72 | prop[n++] = gin_prop_x(gin, ct->x); |
| 73 | prop[n++] = gin_prop_y(gin, ct->y); | 73 | prop[n++] = gin_prop_y(gin, ct->y); |
| @@ -79,15 +79,15 @@ int gin_get_clients(struct grail *ge, | |||
| 79 | struct grail_client_info *info, int maxinfo, | 79 | struct grail_client_info *info, int maxinfo, |
| 80 | const grail_mask_t* types, int btypes, | 80 | const grail_mask_t* types, int btypes, |
| 81 | const grail_mask_t* span, int bspan, | 81 | const grail_mask_t* span, int bspan, |
| 82 | const struct touch_frame *frame) | 82 | const struct utouch_frame *frame) |
| 83 | { | 83 | { |
| 84 | struct grail_coord pos[DIM_TOUCH]; | 84 | struct grail_coord pos[DIM_TOUCH]; |
| 85 | int i, npos = 0; | 85 | int i, npos = 0; |
| 86 | if (!ge->get_clients) | 86 | if (!ge->get_clients) |
| 87 | return 0; | 87 | return 0; |
| 88 | grail_mask_foreach(i, span, bspan) { | 88 | grail_mask_foreach(i, span, bspan) { |
| 89 | pos[npos].x = gin_prop_x(ge->gin, frame->touch[i].x); | 89 | pos[npos].x = gin_prop_x(ge->gin, frame->slots[i]->x); |
| 90 | pos[npos].y = gin_prop_y(ge->gin, frame->touch[i].y); | 90 | pos[npos].y = gin_prop_y(ge->gin, frame->slots[i]->y); |
| 91 | npos++; | 91 | npos++; |
| 92 | } | 92 | } |
| 93 | return ge->get_clients(ge, info, maxinfo, pos, npos, types, btypes); | 93 | return ge->get_clients(ge, info, maxinfo, pos, npos, types, btypes); |
| @@ -95,7 +95,7 @@ int gin_get_clients(struct grail *ge, | |||
| 95 | 95 | ||
| 96 | void gin_send_event(struct grail *ge, struct slot_state *s, | 96 | void gin_send_event(struct grail *ge, struct slot_state *s, |
| 97 | const struct gesture_event *ev, | 97 | const struct gesture_event *ev, |
| 98 | const struct touch_frame *frame) | 98 | const struct utouch_frame *frame) |
| 99 | { | 99 | { |
| 100 | struct grail_impl *impl = ge->impl; | 100 | struct grail_impl *impl = ge->impl; |
| 101 | const struct gesture_inserter *gin = ge->gin; | 101 | const struct gesture_inserter *gin = ge->gin; |
| @@ -121,15 +121,14 @@ void gin_send_event(struct grail *ge, struct slot_state *s, | |||
| 121 | int grail_get_contacts(const struct grail *ge, | 121 | int grail_get_contacts(const struct grail *ge, |
| 122 | struct grail_contact *touch, int max_touch) | 122 | struct grail_contact *touch, int max_touch) |
| 123 | { | 123 | { |
| 124 | const struct touch_dev *dev = &ge->impl->dev; | ||
| 125 | const struct gesture_inserter *gin = ge->gin; | 124 | const struct gesture_inserter *gin = ge->gin; |
| 126 | const struct touch_frame *frame = &dev->frame; | 125 | const struct utouch_frame *frame = ge->impl->frame; |
| 127 | int i; | 126 | int i; |
| 128 | if (frame->nactive < max_touch) | 127 | if (frame->num_active < max_touch) |
| 129 | max_touch = frame->nactive; | 128 | max_touch = frame->num_active; |
| 130 | for (i = 0; i < max_touch; i++) { | 129 | for (i = 0; i < max_touch; i++) { |
| 131 | struct grail_contact *t = &touch[i]; | 130 | struct grail_contact *t = &touch[i]; |
| 132 | const struct touch *ct = frame->active[i]; | 131 | const struct utouch_contact *ct = frame->active[i]; |
| 133 | t->id = ct->id; | 132 | t->id = ct->id; |
| 134 | t->tool_type = ct->tool_type; | 133 | t->tool_type = ct->tool_type; |
| 135 | t->pos.x = gin_prop_x(gin, ct->x); | 134 | t->pos.x = gin_prop_x(gin, ct->x); |
| @@ -138,8 +137,8 @@ int grail_get_contacts(const struct grail *ge, | |||
| 138 | t->touch_minor = gin->scale_r * ct->touch_minor; | 137 | t->touch_minor = gin->scale_r * ct->touch_minor; |
| 139 | t->width_major = gin->scale_r * ct->width_major; | 138 | t->width_major = gin->scale_r * ct->width_major; |
| 140 | t->width_minor = gin->scale_r * ct->width_minor; | 139 | t->width_minor = gin->scale_r * ct->width_minor; |
| 141 | t->angle = touch_angle(dev, ct->orientation); | 140 | t->angle = ct->orientation; |
| 142 | t->pressure = touch_pressure(dev, ct->pressure); | 141 | t->pressure = ct->pressure; |
| 143 | } | 142 | } |
| 144 | return max_touch; | 143 | return max_touch; |
| 145 | } | 144 | } |
diff --git a/src/grail-gestures.c b/src/grail-gestures.c index ed937a4..035a199 100644 --- a/src/grail-gestures.c +++ b/src/grail-gestures.c | |||
| @@ -31,15 +31,15 @@ static const grail_time_t SAMPLE_MS = 10; | |||
| 31 | static const float EPS = 1e-3; | 31 | static const float EPS = 1e-3; |
| 32 | 32 | ||
| 33 | static void compute_position(float *x, float *y, | 33 | static void compute_position(float *x, float *y, |
| 34 | const struct touch_frame *frame) | 34 | const struct utouch_frame *frame) |
| 35 | { | 35 | { |
| 36 | int i, n = frame->nactive; | 36 | int i, n = frame->num_active; |
| 37 | *x = 0; | 37 | *x = 0; |
| 38 | *y = 0; | 38 | *y = 0; |
| 39 | if (n < 1) | 39 | if (n < 1) |
| 40 | return; | 40 | return; |
| 41 | for (i = 0; i < n; i++) { | 41 | for (i = 0; i < n; i++) { |
| 42 | const struct touch *t = frame->active[i]; | 42 | const struct utouch_contact *t = frame->active[i]; |
| 43 | *x += t->x; | 43 | *x += t->x; |
| 44 | *y += t->y; | 44 | *y += t->y; |
| 45 | } | 45 | } |
| @@ -48,14 +48,14 @@ static void compute_position(float *x, float *y, | |||
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | static float compute_radius(float x, float y, | 50 | static float compute_radius(float x, float y, |
| 51 | const struct touch_frame *frame) | 51 | const struct utouch_frame *frame) |
| 52 | { | 52 | { |
| 53 | int i, n = frame->nactive; | 53 | int i, n = frame->num_active; |
| 54 | float r = 0, r2 = 0; | 54 | float r = 0, r2 = 0; |
| 55 | if (n < 2) | 55 | if (n < 2) |
| 56 | return r; | 56 | return r; |
| 57 | for (i = 0; i < n; i++) { | 57 | for (i = 0; i < n; i++) { |
| 58 | const struct touch *t = frame->active[i]; | 58 | const struct utouch_contact *t = frame->active[i]; |
| 59 | float dx = t->x - x; | 59 | float dx = t->x - x; |
| 60 | float dy = t->y - y; | 60 | float dy = t->y - y; |
| 61 | r2 += dx * dx + dy * dy; | 61 | r2 += dx * dx + dy * dy; |
| @@ -66,16 +66,15 @@ static float compute_radius(float x, float y, | |||
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | static float compute_rotation(float x, float y, float r, | 68 | static float compute_rotation(float x, float y, float r, |
| 69 | const struct touch_frame *prev, | 69 | const struct utouch_frame *frame) |
| 70 | const struct touch_frame *frame) | ||
| 71 | { | 70 | { |
| 72 | int i, n = frame->nactive; | 71 | int i, n = frame->num_active; |
| 73 | float da = 0, darc2 = 0; | 72 | float da = 0, darc2 = 0; |
| 74 | if (n < 2) | 73 | if (n < 2) |
| 75 | return da; | 74 | return da; |
| 76 | for (i = 0; i < n; i++) { | 75 | for (i = 0; i < n; i++) { |
| 77 | const struct touch *t = frame->active[i]; | 76 | const struct utouch_contact *t = frame->active[i]; |
| 78 | const struct touch *ot = &prev->touch[t->slot]; | 77 | const struct utouch_contact *ot = t->prev; |
| 79 | float dx = t->x - x; | 78 | float dx = t->x - x; |
| 80 | float dy = t->y - y; | 79 | float dy = t->y - y; |
| 81 | float mx = t->x - ot->x; | 80 | float mx = t->x - ot->x; |
| @@ -142,13 +141,13 @@ static void move_update(struct move_model *m, int i, float x, grail_time_t t) | |||
| 142 | 141 | ||
| 143 | void gru_init_motion(struct grail *ge) | 142 | void gru_init_motion(struct grail *ge) |
| 144 | { | 143 | { |
| 145 | struct touch_caps *caps = &ge->impl->dev.caps; | 144 | struct utouch_surface *s = utouch_frame_get_surface(ge->impl->fh); |
| 146 | struct gesture_recognizer *gru = ge->gru; | 145 | struct gesture_recognizer *gru = ge->gru; |
| 147 | struct move_model *m = &gru->move; | 146 | struct move_model *m = &gru->move; |
| 148 | float D[DIM_FM]; | 147 | float D[DIM_FM]; |
| 149 | int i; | 148 | int i; |
| 150 | D[FM_X] = caps->max_x - caps->min_x; | 149 | D[FM_X] = s->max_x - s->min_x; |
| 151 | D[FM_Y] = caps->max_y - caps->min_y; | 150 | D[FM_Y] = s->max_y - s->min_y; |
| 152 | D[FM_R] = sqrt(D[FM_X] * D[FM_X] + D[FM_Y] * D[FM_Y]); | 151 | D[FM_R] = sqrt(D[FM_X] * D[FM_X] + D[FM_Y] * D[FM_Y]); |
| 153 | D[FM_A] = 2 * M_PI; | 152 | D[FM_A] = 2 * M_PI; |
| 154 | for (i = 0; i < DIM_FM; i++) { | 153 | for (i = 0; i < DIM_FM; i++) { |
| @@ -159,14 +158,15 @@ void gru_init_motion(struct grail *ge) | |||
| 159 | } | 158 | } |
| 160 | 159 | ||
| 161 | void gru_motion(struct grail *ge, | 160 | void gru_motion(struct grail *ge, |
| 162 | const struct touch_frame *frame) | 161 | const struct utouch_frame *frame) |
| 163 | { | 162 | { |
| 164 | struct gesture_recognizer *gru = ge->gru; | 163 | struct gesture_recognizer *gru = ge->gru; |
| 165 | struct move_model *m = &gru->move; | 164 | struct move_model *m = &gru->move; |
| 166 | grail_time_t t = frame->time; | 165 | grail_time_t t = frame->time; |
| 167 | float x, y, r, a; | 166 | float x, y, r, a; |
| 167 | |||
| 168 | compute_position(&x, &y, frame); | 168 | compute_position(&x, &y, frame); |
| 169 | if (frame->ncreate || frame->ndestroy) { | 169 | if (frame->prev->revision != frame->revision) { |
| 170 | r = compute_radius(x, y, frame); | 170 | r = compute_radius(x, y, frame); |
| 171 | a = 0; | 171 | a = 0; |
| 172 | move_reset(m, FM_X, x, t); | 172 | move_reset(m, FM_X, x, t); |
| @@ -175,7 +175,7 @@ void gru_motion(struct grail *ge, | |||
| 175 | move_reset(m, FM_A, a, t); | 175 | move_reset(m, FM_A, a, t); |
| 176 | m->single = 0; | 176 | m->single = 0; |
| 177 | m->multi = 0; | 177 | m->multi = 0; |
| 178 | } else if (frame->nactive < 2) { | 178 | } else if (frame->num_active < 2) { |
| 179 | r = 0; | 179 | r = 0; |
| 180 | a = 0; | 180 | a = 0; |
| 181 | move_update(m, FM_X, x, t); | 181 | move_update(m, FM_X, x, t); |
| @@ -190,7 +190,7 @@ void gru_motion(struct grail *ge, | |||
| 190 | r = compute_radius(x, y, frame); | 190 | r = compute_radius(x, y, frame); |
| 191 | r = move_filter(&m->fm[FM_R], r); | 191 | r = move_filter(&m->fm[FM_R], r); |
| 192 | a = m->fm[FM_A].value; | 192 | a = m->fm[FM_A].value; |
| 193 | a += compute_rotation(x, y, r, &gru->frame, frame); | 193 | a += compute_rotation(x, y, r, frame); |
| 194 | a = move_filter(&m->fm[FM_A], a); | 194 | a = move_filter(&m->fm[FM_A], a); |
| 195 | move_update(m, FM_X, x, t); | 195 | move_update(m, FM_X, x, t); |
| 196 | move_update(m, FM_Y, y, t); | 196 | move_update(m, FM_Y, y, t); |
| @@ -199,7 +199,7 @@ void gru_motion(struct grail *ge, | |||
| 199 | m->single = 0; | 199 | m->single = 0; |
| 200 | m->multi = 1; | 200 | m->multi = 1; |
| 201 | } | 201 | } |
| 202 | m->ntouch = frame->nactive; | 202 | m->ntouch = frame->num_active; |
| 203 | m->time = t; | 203 | m->time = t; |
| 204 | } | 204 | } |
| 205 | 205 | ||
diff --git a/src/grail-gestures.h b/src/grail-gestures.h index 27108e9..69dd7e4 100644 --- a/src/grail-gestures.h +++ b/src/grail-gestures.h | |||
| @@ -61,7 +61,7 @@ struct move_model { | |||
| 61 | 61 | ||
| 62 | void gru_init_motion(struct grail *ge); | 62 | void gru_init_motion(struct grail *ge); |
| 63 | void gru_motion(struct grail *ge, | 63 | void gru_motion(struct grail *ge, |
| 64 | const struct touch_frame *frame); | 64 | const struct utouch_frame *frame); |
| 65 | void gru_event(struct grail *ge, int gid, | 65 | void gru_event(struct grail *ge, int gid, |
| 66 | const struct move_model *move, | 66 | const struct move_model *move, |
| 67 | const grail_prop_t *prop, int nprop); | 67 | const grail_prop_t *prop, int nprop); |
| @@ -77,11 +77,11 @@ struct combo_model { | |||
| 77 | }; | 77 | }; |
| 78 | 78 | ||
| 79 | int gru_drag(struct grail *ge, | 79 | int gru_drag(struct grail *ge, |
| 80 | const struct touch_frame *frame); | 80 | const struct utouch_frame *frame); |
| 81 | int gru_pinch(struct grail *ge, | 81 | int gru_pinch(struct grail *ge, |
| 82 | const struct touch_frame *frame); | 82 | const struct utouch_frame *frame); |
| 83 | int gru_rotate(struct grail *ge, | 83 | int gru_rotate(struct grail *ge, |
| 84 | const struct touch_frame *frame); | 84 | const struct utouch_frame *frame); |
| 85 | 85 | ||
| 86 | static inline int out_of_bounds(const struct combo_model *s, | 86 | static inline int out_of_bounds(const struct combo_model *s, |
| 87 | const struct move_model *m) | 87 | const struct move_model *m) |
| @@ -90,11 +90,11 @@ static inline int out_of_bounds(const struct combo_model *s, | |||
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | int gru_windrag(struct grail *ge, | 92 | int gru_windrag(struct grail *ge, |
| 93 | const struct touch_frame *frame); | 93 | const struct utouch_frame *frame); |
| 94 | int gru_winpinch(struct grail *ge, | 94 | int gru_winpinch(struct grail *ge, |
| 95 | const struct touch_frame *frame); | 95 | const struct utouch_frame *frame); |
| 96 | int gru_winrotate(struct grail *ge, | 96 | int gru_winrotate(struct grail *ge, |
| 97 | const struct touch_frame *frame); | 97 | const struct utouch_frame *frame); |
| 98 | 98 | ||
| 99 | struct tapping_model { | 99 | struct tapping_model { |
| 100 | grail_time_t start, end; | 100 | grail_time_t start, end; |
| @@ -105,7 +105,7 @@ struct tapping_model { | |||
| 105 | }; | 105 | }; |
| 106 | 106 | ||
| 107 | int gru_tapping(struct grail *ge, | 107 | int gru_tapping(struct grail *ge, |
| 108 | const struct touch_frame *frame); | 108 | const struct utouch_frame *frame); |
| 109 | 109 | ||
| 110 | #endif | 110 | #endif |
| 111 | 111 | ||
diff --git a/src/grail-impl.h b/src/grail-impl.h index 2859186..dcbaedd 100644 --- a/src/grail-impl.h +++ b/src/grail-impl.h | |||
| @@ -23,15 +23,26 @@ | |||
| 23 | #ifndef _GRAIL_IMPL_H | 23 | #ifndef _GRAIL_IMPL_H |
| 24 | #define _GRAIL_IMPL_H | 24 | #define _GRAIL_IMPL_H |
| 25 | 25 | ||
| 26 | #include <grail-touch.h> | 26 | #define MTDEV_NO_LEGACY_API |
| 27 | #define GRAIL_NO_LEGACY_API | ||
| 28 | |||
| 29 | #include <grail.h> | ||
| 30 | #include <utouch/frame-mtdev.h> | ||
| 27 | #include "evbuf.h" | 31 | #include "evbuf.h" |
| 28 | #include "grailbuf.h" | 32 | #include "grailbuf.h" |
| 29 | 33 | ||
| 34 | #define DIM_TOUCH 32 | ||
| 35 | #define DIM_TOUCH_BYTES ((DIM_TOUCH + 7) >> 3) | ||
| 36 | |||
| 30 | struct grail_impl { | 37 | struct grail_impl { |
| 31 | struct touch_dev dev; | 38 | struct evemu_device *evemu; |
| 32 | struct touch_caps emu; | 39 | struct mtdev *mtdev; |
| 40 | utouch_frame_handle fh; | ||
| 41 | const struct utouch_frame *frame; | ||
| 33 | struct evbuf evbuf; | 42 | struct evbuf evbuf; |
| 34 | struct grailbuf gbuf; | 43 | struct grailbuf gbuf; |
| 44 | float emin_x, emin_y; | ||
| 45 | float emax_x, emax_y; | ||
| 35 | int filter_abs; | 46 | int filter_abs; |
| 36 | int pointer_status; | 47 | int pointer_status; |
| 37 | int pointer_x, pointer_y; | 48 | int pointer_x, pointer_y; |
diff --git a/src/grail-inserter.c b/src/grail-inserter.c index 847995a..6f9a034 100644 --- a/src/grail-inserter.c +++ b/src/grail-inserter.c | |||
| @@ -40,7 +40,7 @@ static int find_gslot(const struct gesture_inserter *gin, int gid) | |||
| 40 | 40 | ||
| 41 | // todo: spanning tree for multi-user case | 41 | // todo: spanning tree for multi-user case |
| 42 | static void setup_new_gestures(struct grail *ge, | 42 | static void setup_new_gestures(struct grail *ge, |
| 43 | const struct touch_frame *frame) | 43 | const struct utouch_frame *frame) |
| 44 | { | 44 | { |
| 45 | struct gesture_inserter *gin = ge->gin; | 45 | struct gesture_inserter *gin = ge->gin; |
| 46 | grail_mask_t types[DIM_GRAIL_TYPE_BYTES]; | 46 | grail_mask_t types[DIM_GRAIL_TYPE_BYTES]; |
| @@ -100,14 +100,14 @@ void gin_destroy(struct grail *ge) | |||
| 100 | ge->gin = NULL; | 100 | ge->gin = NULL; |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | void gin_frame_begin(struct grail *ge, const struct touch_frame *frame) | 103 | void gin_frame_begin(struct grail *ge, const struct utouch_frame *frame) |
| 104 | { | 104 | { |
| 105 | struct gesture_inserter *gin = ge->gin; | 105 | struct gesture_inserter *gin = ge->gin; |
| 106 | memset(gin->types, 0, sizeof(gin->types)); | 106 | memset(gin->types, 0, sizeof(gin->types)); |
| 107 | gin->time = frame->time; | 107 | gin->time = frame->time; |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | void gin_frame_end(struct grail *ge, const struct touch_frame *frame) | 110 | void gin_frame_end(struct grail *ge, const struct utouch_frame *frame) |
| 111 | { | 111 | { |
| 112 | struct gesture_inserter *gin = ge->gin; | 112 | struct gesture_inserter *gin = ge->gin; |
| 113 | int i, hold = 0, discard = 0; | 113 | int i, hold = 0, discard = 0; |
| @@ -151,11 +151,12 @@ void gin_frame_end(struct grail *ge, const struct touch_frame *frame) | |||
| 151 | } | 151 | } |
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | int gin_gid_begin_select(struct grail *ge, int type, int priority, | 154 | int gin_gid_begin(struct grail *ge, int type, int priority, |
| 155 | const grail_mask_t *span, int nspan) | 155 | const struct utouch_frame *frame) |
| 156 | { | 156 | { |
| 157 | struct gesture_inserter *gin = ge->gin; | 157 | struct gesture_inserter *gin = ge->gin; |
| 158 | struct slot_state *s; | 158 | struct slot_state *s; |
| 159 | int slot; | ||
| 159 | int i = grail_mask_get_first(gin->unused, sizeof(gin->unused)); | 160 | int i = grail_mask_get_first(gin->unused, sizeof(gin->unused)); |
| 160 | if (i < 0) | 161 | if (i < 0) |
| 161 | return -1; | 162 | return -1; |
| @@ -165,7 +166,8 @@ int gin_gid_begin_select(struct grail *ge, int type, int priority, | |||
| 165 | s->id = gin->gestureid++ & MAX_GESTURE_ID; | 166 | s->id = gin->gestureid++ & MAX_GESTURE_ID; |
| 166 | s->status = GRAIL_STATUS_BEGIN; | 167 | s->status = GRAIL_STATUS_BEGIN; |
| 167 | s->nclient = 0; | 168 | s->nclient = 0; |
| 168 | memcpy(s->span, span, nspan); | 169 | for (slot = 0; slot < DIM_TOUCH; slot++) |
| 170 | grail_mask_modify(s->span, slot, frame->slots[slot]->active); | ||
| 169 | gebuf_clear(&s->buf); | 171 | gebuf_clear(&s->buf); |
| 170 | grail_mask_clear(gin->unused, i); | 172 | grail_mask_clear(gin->unused, i); |
| 171 | grail_mask_set(gin->fresh, i); | 173 | grail_mask_set(gin->fresh, i); |
| @@ -173,13 +175,6 @@ int gin_gid_begin_select(struct grail *ge, int type, int priority, | |||
| 173 | return s->id; | 175 | return s->id; |
| 174 | } | 176 | } |
| 175 | 177 | ||
| 176 | int gin_gid_begin(struct grail *ge, int type, int priority, | ||
| 177 | const struct touch_frame *frame) | ||
| 178 | { | ||
| 179 | return gin_gid_begin_select(ge, type, priority, | ||
| 180 | frame->touches, sizeof(frame->touches)); | ||
| 181 | } | ||
| 182 | |||
| 183 | void gin_gid_discard(struct grail *ge, int gid) | 178 | void gin_gid_discard(struct grail *ge, int gid) |
| 184 | { | 179 | { |
| 185 | struct gesture_inserter *gin = ge->gin; | 180 | struct gesture_inserter *gin = ge->gin; |
| @@ -248,18 +243,18 @@ void grail_set_bbox(struct grail *ge, | |||
| 248 | const struct grail_coord *tmin, | 243 | const struct grail_coord *tmin, |
| 249 | const struct grail_coord *tmax) | 244 | const struct grail_coord *tmax) |
| 250 | { | 245 | { |
| 251 | struct touch_caps *caps = &ge->impl->dev.caps; | 246 | struct utouch_surface *s = utouch_frame_get_surface(ge->impl->fh); |
| 252 | struct gesture_inserter *gin = ge->gin; | 247 | struct gesture_inserter *gin = ge->gin; |
| 253 | double tx, ty, dx, dy, sx, sy; | 248 | double tx, ty, dx, dy, sx, sy; |
| 254 | tx = tmax->x - tmin->x; | 249 | tx = tmax->x - tmin->x; |
| 255 | ty = tmax->y - tmin->y; | 250 | ty = tmax->y - tmin->y; |
| 256 | dx = caps->max_x - caps->min_x; | 251 | dx = s->max_x - s->min_x; |
| 257 | dy = caps->max_y - caps->min_y; | 252 | dy = s->max_y - s->min_y; |
| 258 | sx = tx / dx; | 253 | sx = tx / dx; |
| 259 | sy = ty / dy; | 254 | sy = ty / dy; |
| 260 | gin->scale_x = sx; | 255 | gin->scale_x = sx; |
| 261 | gin->scale_y = sy; | 256 | gin->scale_y = sy; |
| 262 | gin->scale_r = sqrt((tx * tx + ty * ty) / (dx * dx + dy * dy)); | 257 | gin->scale_r = sqrt((tx * tx + ty * ty) / (dx * dx + dy * dy)); |
| 263 | gin->trans_x = tmin->x - caps->min_x * sx; | 258 | gin->trans_x = tmin->x - s->min_x * sx; |
| 264 | gin->trans_y = tmin->y - caps->min_y * sy; | 259 | gin->trans_y = tmin->y - s->min_y * sy; |
| 265 | } | 260 | } |
diff --git a/src/grail-inserter.h b/src/grail-inserter.h index 9baecb7..3b8cd77 100644 --- a/src/grail-inserter.h +++ b/src/grail-inserter.h | |||
| @@ -23,8 +23,7 @@ | |||
| 23 | #ifndef _GRAIL_INSERTER_H | 23 | #ifndef _GRAIL_INSERTER_H |
| 24 | #define _GRAIL_INSERTER_H | 24 | #define _GRAIL_INSERTER_H |
| 25 | 25 | ||
| 26 | #include <grail-touch.h> | 26 | #include "grail-impl.h" |
| 27 | #include <grail.h> | ||
| 28 | #include "gebuf.h" | 27 | #include "gebuf.h" |
| 29 | 28 | ||
| 30 | #define DIM_EV_TYPE EV_CNT | 29 | #define DIM_EV_TYPE EV_CNT |
| @@ -69,27 +68,25 @@ static inline float gin_prop_y(const struct gesture_inserter *gin, float y) | |||
| 69 | } | 68 | } |
| 70 | 69 | ||
| 71 | int gin_add_contact_props(const struct gesture_inserter *gin, | 70 | int gin_add_contact_props(const struct gesture_inserter *gin, |
| 72 | grail_prop_t *prop, const struct touch_frame *frame); | 71 | grail_prop_t *prop, const struct utouch_frame *frame); |
| 73 | 72 | ||
| 74 | int gin_get_clients(struct grail *ge, | 73 | int gin_get_clients(struct grail *ge, |
| 75 | struct grail_client_info *info, int maxinfo, | 74 | struct grail_client_info *info, int maxinfo, |
| 76 | const grail_mask_t* types, int btypes, | 75 | const grail_mask_t* types, int btypes, |
| 77 | const grail_mask_t* span, int bspan, | 76 | const grail_mask_t* span, int bspan, |
| 78 | const struct touch_frame *frame); | 77 | const struct utouch_frame *frame); |
| 79 | void gin_send_event(struct grail *ge, struct slot_state *s, | 78 | void gin_send_event(struct grail *ge, struct slot_state *s, |
| 80 | const struct gesture_event *ev, | 79 | const struct gesture_event *ev, |
| 81 | const struct touch_frame *frame); | 80 | const struct utouch_frame *frame); |
| 82 | 81 | ||
| 83 | int gin_init(struct grail *ge); | 82 | int gin_init(struct grail *ge); |
| 84 | void gin_destroy(struct grail *ge); | 83 | void gin_destroy(struct grail *ge); |
| 85 | 84 | ||
| 86 | void gin_frame_begin(struct grail *ge, const struct touch_frame *frame); | 85 | void gin_frame_begin(struct grail *ge, const struct utouch_frame *frame); |
| 87 | void gin_frame_end(struct grail *ge, const struct touch_frame *frame); | 86 | void gin_frame_end(struct grail *ge, const struct utouch_frame *frame); |
| 88 | 87 | ||
| 89 | int gin_gid_begin_select(struct grail *ge, int type, int priority, | ||
| 90 | const grail_mask_t *span, int nspan); | ||
| 91 | int gin_gid_begin(struct grail *ge, int type, int priority, | 88 | int gin_gid_begin(struct grail *ge, int type, int priority, |
| 92 | const struct touch_frame *frame); | 89 | const struct utouch_frame *frame); |
| 93 | void gin_gid_discard(struct grail *ge, int gid); | 90 | void gin_gid_discard(struct grail *ge, int gid); |
| 94 | 91 | ||
| 95 | void gin_gid_event(struct grail *ge, int gid, | 92 | void gin_gid_event(struct grail *ge, int gid, |
diff --git a/src/grail-recognizer.c b/src/grail-recognizer.c index 932f28a..fb0ae85 100644 --- a/src/grail-recognizer.c +++ b/src/grail-recognizer.c | |||
| @@ -42,7 +42,7 @@ void gru_destroy(struct grail *ge) | |||
| 42 | ge->gru = NULL; | 42 | ge->gru = NULL; |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | void gru_recognize(struct grail *ge, const struct touch_frame *frame) | 45 | void gru_recognize(struct grail *ge, const struct utouch_frame *frame) |
| 46 | { | 46 | { |
| 47 | if (!ge->gin || !ge->gru) | 47 | if (!ge->gin || !ge->gru) |
| 48 | return; | 48 | return; |
| @@ -54,5 +54,4 @@ void gru_recognize(struct grail *ge, const struct touch_frame *frame) | |||
| 54 | gru_winpinch(ge, frame); | 54 | gru_winpinch(ge, frame); |
| 55 | gru_winrotate(ge, frame); | 55 | gru_winrotate(ge, frame); |
| 56 | gru_tapping(ge, frame); | 56 | gru_tapping(ge, frame); |
| 57 | ge->gru->frame = *frame; | ||
| 58 | } | 57 | } |
diff --git a/src/grail-recognizer.h b/src/grail-recognizer.h index 1a9edd1..56e5b8d 100644 --- a/src/grail-recognizer.h +++ b/src/grail-recognizer.h | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | #include "grail-gestures.h" | 26 | #include "grail-gestures.h" |
| 27 | 27 | ||
| 28 | struct gesture_recognizer { | 28 | struct gesture_recognizer { |
| 29 | struct touch_frame frame; | ||
| 30 | struct move_model move; | 29 | struct move_model move; |
| 31 | struct combo_model drag; | 30 | struct combo_model drag; |
| 32 | struct combo_model pinch; | 31 | struct combo_model pinch; |
| @@ -38,7 +37,7 @@ struct gesture_recognizer { | |||
| 38 | }; | 37 | }; |
| 39 | 38 | ||
| 40 | int gru_init(struct grail *ge); | 39 | int gru_init(struct grail *ge); |
| 41 | void gru_recognize(struct grail *ge, const struct touch_frame *frame); | 40 | void gru_recognize(struct grail *ge, const struct utouch_frame *frame); |
| 42 | void gru_destroy(struct grail *ge); | 41 | void gru_destroy(struct grail *ge); |
| 43 | 42 | ||
| 44 | #endif | 43 | #endif |
diff --git a/src/touch-caps.c b/src/touch-caps.c deleted file mode 100644 index f99b0d7..0000000 --- a/src/touch-caps.c +++ /dev/null | |||
| @@ -1,117 +0,0 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * | ||
| 3 | * grail - Gesture Recognition And Instantiation Library | ||
| 4 | * | ||
| 5 | * Copyright (C) 2010 Canonical Ltd. | ||
| 6 | * Copyright (C) 2010 Henrik Rydberg <rydberg@bitmath.org> | ||
| 7 | * | ||
| 8 | * This program is free software: you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the | ||
| 10 | * Free Software Foundation, either version 3 of the License, or (at your | ||
| 11 | * option) any later version. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, but | ||
| 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 16 | * General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License along | ||
| 19 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 20 | * | ||
| 21 | ****************************************************************************/ | ||
| 22 | |||
| 23 | #include <grail-touch.h> | ||
| 24 | #include <errno.h> | ||
| 25 | #include <math.h> | ||
| 26 | |||
| 27 | /* see mtdev-mapping.h */ | ||
| 28 | #define MTDEV_POSITION_X 5 | ||
| 29 | #define MTDEV_POSITION_Y 6 | ||
| 30 | #define MTDEV_ORIENTATION 4 | ||
| 31 | #define MTDEV_PRESSURE 10 | ||
| 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 | unsigned long relbits[nlongs(REL_CNT)]; | ||
| 52 | int rc; | ||
| 53 | |||
| 54 | SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits)); | ||
| 55 | if (rc < 0) | ||
| 56 | return 0; | ||
| 57 | SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbits)), absbits)); | ||
| 58 | if (rc < 0) | ||
| 59 | return 0; | ||
| 60 | SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relbits)), relbits)); | ||
| 61 | if (rc < 0) | ||
| 62 | return 0; | ||
| 63 | |||
| 64 | /* only support pure absolute devices at this time */ | ||
| 65 | if (getbit(relbits, REL_X) || getbit(relbits, REL_Y)) | ||
| 66 | return 0; | ||
| 67 | |||
| 68 | if (dev->mtdev.caps.has_mtdata) | ||
| 69 | return 1; | ||
| 70 | |||
| 71 | return getbit(absbits, ABS_X) && | ||
| 72 | getbit(absbits, ABS_Y) && | ||
| 73 | getbit(keybits, BTN_TOUCH) && | ||
| 74 | getbit(keybits, BTN_TOOL_DOUBLETAP); | ||
| 75 | } | ||
| 76 | |||
| 77 | void touch_caps_init(struct touch_dev *dev) | ||
| 78 | { | ||
| 79 | const struct mtdev_caps *mt = &dev->mtdev.caps; | ||
| 80 | struct touch_caps *caps = &dev->caps; | ||
| 81 | caps->min_x = mt->abs[MTDEV_POSITION_X].minimum; | ||
| 82 | caps->max_x = mt->abs[MTDEV_POSITION_X].maximum; | ||
| 83 | caps->min_y = mt->abs[MTDEV_POSITION_Y].minimum; | ||
| 84 | caps->max_y = mt->abs[MTDEV_POSITION_Y].maximum; | ||
| 85 | caps->min_orient = mt->abs[MTDEV_ORIENTATION].minimum; | ||
| 86 | caps->max_orient = mt->abs[MTDEV_ORIENTATION].maximum; | ||
| 87 | caps->min_press = mt->abs[MTDEV_PRESSURE].minimum; | ||
| 88 | caps->max_press = mt->abs[MTDEV_PRESSURE].maximum; | ||
| 89 | if (caps->min_x == caps->max_x) { | ||
| 90 | caps->min_x = 0; | ||
| 91 | caps->max_x = 1024; | ||
| 92 | } | ||
| 93 | if (caps->min_y == caps->max_y) { | ||
| 94 | caps->min_y = 0; | ||
| 95 | caps->max_y = 768; | ||
| 96 | } | ||
| 97 | if (caps->min_orient == caps->max_orient) | ||
| 98 | caps->max_orient = 1; | ||
| 99 | if (caps->min_orient + caps->max_orient != 0) | ||
| 100 | caps->min_orient = -caps->max_orient; | ||
| 101 | if (caps->min_press == caps->max_press) { | ||
| 102 | caps->min_press = 0; | ||
| 103 | caps->max_press = 256; | ||
| 104 | } | ||
| 105 | } | ||
| 106 | |||
| 107 | float touch_angle(const struct touch_dev *dev, int orient) | ||
| 108 | { | ||
| 109 | const struct touch_caps *caps = &dev->caps; | ||
| 110 | return orient / caps->max_orient * M_PI_2; | ||
| 111 | } | ||
| 112 | |||
| 113 | float touch_pressure(const struct touch_dev *dev, int press) | ||
| 114 | { | ||
| 115 | const struct touch_caps *caps = &dev->caps; | ||
| 116 | return (press - caps->min_press) / (caps->max_press - caps->min_press); | ||
| 117 | } | ||
diff --git a/src/touch-dev.c b/src/touch-dev.c deleted file mode 100644 index d8e192e..0000000 --- a/src/touch-dev.c +++ /dev/null | |||
| @@ -1,264 +0,0 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * | ||
| 3 | * grail - Gesture Recognition And Instantiation Library | ||
| 4 | * | ||
| 5 | * Copyright (C) 2010 Canonical Ltd. | ||
| 6 | * Copyright (C) 2010 Henrik Rydberg <rydberg@bitmath.org> | ||
| 7 | * | ||
| 8 | * This program is free software: you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the | ||
| 10 | * Free Software Foundation, either version 3 of the License, or (at your | ||
| 11 | * option) any later version. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, but | ||
| 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 16 | * General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License along | ||
| 19 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 20 | * | ||
| 21 | ****************************************************************************/ | ||
| 22 | |||
| 23 | #include <grail-touch.h> | ||
| 24 | #include <malloc.h> | ||
| 25 | #include <string.h> | ||
| 26 | #include <errno.h> | ||
| 27 | |||
| 28 | /* see mtdev-mapping.h */ | ||
| 29 | #define MTDEV_TOUCH_MINOR 1 | ||
| 30 | |||
| 31 | #define SET_PROP(name, value) \ | ||
| 32 | if (t->name != value) { \ | ||
| 33 | t->name = value; \ | ||
| 34 | frame->nmodify++; \ | ||
| 35 | } | ||
| 36 | |||
| 37 | static void finish_touch(struct touch_dev *dev, struct touch_frame *frame) | ||
| 38 | { | ||
| 39 | struct touch *t = &frame->touch[dev->slot]; | ||
| 40 | if (t->touch_major && !t->touch_minor || | ||
| 41 | !dev->mtdev.caps.has_abs[MTDEV_TOUCH_MINOR]) | ||
| 42 | SET_PROP(touch_minor, t->touch_major); | ||
| 43 | if (dev->state > 0) { | ||
| 44 | t->active = 1; | ||
| 45 | grail_mask_set(frame->touches, dev->slot); | ||
| 46 | frame->ncreate++; | ||
| 47 | } | ||
| 48 | if (dev->state < 0) { | ||
| 49 | t->active = 0; | ||
| 50 | grail_mask_clear(frame->touches, dev->slot); | ||
| 51 | frame->ndestroy++; | ||
| 52 | } | ||
| 53 | dev->state = 0; | ||
| 54 | } | ||
| 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 | |||
| 85 | static void finish_packet(struct touch_dev *dev, | ||
| 86 | const struct input_event *syn) | ||
| 87 | { | ||
| 88 | static const touch_time_t ms = 1000; | ||
| 89 | struct touch_frame *frame = &dev->frame; | ||
| 90 | int i, nslot = 0; | ||
| 91 | if (dev->mtdev.caps.has_mtdata) | ||
| 92 | finish_touch(dev, frame); | ||
| 93 | else | ||
| 94 | finish_legacy(dev, frame); | ||
| 95 | grail_mask_foreach(i, frame->touches, DIM_TOUCH_BYTES) | ||
| 96 | frame->active[nslot++] = &frame->touch[i]; | ||
| 97 | frame->nactive = nslot; | ||
| 98 | frame->time = syn->time.tv_usec / ms + syn->time.tv_sec * ms; | ||
| 99 | if (dev->sync) | ||
| 100 | dev->sync(dev, syn); | ||
| 101 | frame->ncreate = 0; | ||
| 102 | frame->nmodify = 0; | ||
| 103 | frame->ndestroy = 0; | ||
| 104 | } | ||
| 105 | |||
| 106 | static int handle_abs_event(struct touch_dev *dev, | ||
| 107 | const struct input_event *ev) | ||
| 108 | { | ||
| 109 | struct touch_frame *frame = &dev->frame; | ||
| 110 | struct touch *t = &frame->touch[dev->slot]; | ||
| 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; | ||
| 127 | case ABS_MT_SLOT: | ||
| 128 | if (ev->value >= 0 && ev->value < DIM_TOUCH) { | ||
| 129 | if (dev->slot != ev->value) | ||
| 130 | finish_touch(dev, frame); | ||
| 131 | dev->slot = ev->value; | ||
| 132 | t = &frame->touch[dev->slot]; | ||
| 133 | } | ||
| 134 | return 1; | ||
| 135 | case ABS_MT_POSITION_X: | ||
| 136 | SET_PROP(x, ev->value); | ||
| 137 | return 1; | ||
| 138 | case ABS_MT_POSITION_Y: | ||
| 139 | SET_PROP(y, ev->value); | ||
| 140 | return 1; | ||
| 141 | case ABS_MT_TOUCH_MAJOR: | ||
| 142 | SET_PROP(touch_major, ev->value); | ||
| 143 | return 1; | ||
| 144 | case ABS_MT_TOUCH_MINOR: | ||
| 145 | SET_PROP(touch_minor, ev->value); | ||
| 146 | return 1; | ||
| 147 | case ABS_MT_WIDTH_MAJOR: | ||
| 148 | SET_PROP(width_major, ev->value); | ||
| 149 | return 1; | ||
| 150 | case ABS_MT_WIDTH_MINOR: | ||
| 151 | SET_PROP(width_minor, ev->value); | ||
| 152 | return 1; | ||
| 153 | case ABS_MT_ORIENTATION: | ||
| 154 | SET_PROP(orientation, ev->value); | ||
| 155 | return 1; | ||
| 156 | case ABS_MT_PRESSURE: | ||
| 157 | SET_PROP(pressure, ev->value); | ||
| 158 | return 1; | ||
| 159 | case ABS_MT_TOOL_TYPE: | ||
| 160 | SET_PROP(tool_type, ev->value); | ||
| 161 | return 1; | ||
| 162 | case ABS_MT_TRACKING_ID: | ||
| 163 | if (t->id != ev->value) { | ||
| 164 | if (t->id != MT_ID_NULL) { | ||
| 165 | dev->state = -1; | ||
| 166 | finish_touch(dev, frame); | ||
| 167 | } | ||
| 168 | if (ev->value != MT_ID_NULL) | ||
| 169 | dev->state = 1; | ||
| 170 | t->id = ev->value; | ||
| 171 | } | ||
| 172 | return 1; | ||
| 173 | default: | ||
| 174 | return 0; | ||
| 175 | } | ||
| 176 | } | ||
| 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 | |||
| 212 | int touch_dev_open(struct touch_dev *dev, int fd) | ||
| 213 | { | ||
| 214 | struct touch_frame *frame = &dev->frame; | ||
| 215 | int ret, i; | ||
| 216 | memset(dev, 0, sizeof(*dev)); | ||
| 217 | for (i = 0; i < DIM_TOUCH; i++) { | ||
| 218 | struct touch *t = &frame->touch[i]; | ||
| 219 | t->slot = i; | ||
| 220 | t->id = MT_ID_NULL; | ||
| 221 | } | ||
| 222 | ret = mtdev_open(&dev->mtdev, fd); | ||
| 223 | if (!ret && !touch_caps_is_supported(dev, fd)) | ||
| 224 | ret = -ENODEV; | ||
| 225 | if (ret) | ||
| 226 | goto error; | ||
| 227 | touch_caps_init(dev); | ||
| 228 | return 0; | ||
| 229 | error: | ||
| 230 | return ret; | ||
| 231 | } | ||
| 232 | |||
| 233 | int touch_dev_idle(struct touch_dev *dev, int fd, int ms) | ||
| 234 | { | ||
| 235 | return mtdev_idle(&dev->mtdev, fd, ms); | ||
| 236 | } | ||
| 237 | |||
| 238 | int touch_dev_pull(struct touch_dev *dev, int fd) | ||
| 239 | { | ||
| 240 | struct input_event ev; | ||
| 241 | int ret, count = 0, consumed; | ||
| 242 | while ((ret = mtdev_get(&dev->mtdev, fd, &ev, 1)) > 0) { | ||
| 243 | consumed = 0; | ||
| 244 | if (ev.type == EV_SYN) { | ||
| 245 | if (ev.code == SYN_REPORT) | ||
| 246 | finish_packet(dev, &ev); | ||
| 247 | consumed++; | ||
| 248 | } else if (ev.type == EV_ABS) { | ||
| 249 | consumed += handle_abs_event(dev, &ev); | ||
| 250 | } else if (ev.type == EV_KEY) { | ||
| 251 | consumed += handle_key_event(dev, &ev); | ||
| 252 | } | ||
| 253 | if (!consumed && dev->event) | ||
| 254 | dev->event(dev, &ev); | ||
| 255 | count++; | ||
| 256 | } | ||
| 257 | return count > 0 ? count : ret; | ||
| 258 | } | ||
| 259 | |||
| 260 | void touch_dev_close(struct touch_dev *dev, int fd) | ||
| 261 | { | ||
| 262 | mtdev_close(&dev->mtdev); | ||
| 263 | memset(dev, 0, sizeof(*dev)); | ||
| 264 | } | ||
diff --git a/tools/Makefile.am b/tools/Makefile.am index ae6866c..303f70d 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am | |||
| @@ -4,4 +4,4 @@ INCLUDES=-I$(top_srcdir)/include/ | |||
| 4 | 4 | ||
| 5 | grail_gesture_SOURCES = grail-gesture.c | 5 | grail_gesture_SOURCES = grail-gesture.c |
| 6 | grail_gesture_LDFLAGS = -L$(top_builddir)/src/.libs/ \ | 6 | grail_gesture_LDFLAGS = -L$(top_builddir)/src/.libs/ \ |
| 7 | -lutouch-grail -lmtdev -lm | 7 | -lutouch-grail -lutouch-frame -lutouch-evemu -lmtdev -lm |
