diff options
| author | Henrik Rydberg <rydberg@euromail.se> | 2011-02-15 16:39:58 +0100 |
|---|---|---|
| committer | Henrik Rydberg <rydberg@euromail.se> | 2011-02-15 18:49:56 +0100 |
| commit | 0129cd863ad87b8090f150611be58ac9e6e9bfda (patch) | |
| tree | e21b7779c38ea2df5428229d3a760e1f6f9f5c92 /tools/mtview.c | |
| parent | 9607b34bf384cd341f2ac2a7a06f1021eff14363 (diff) | |
Prepare for additional backends
Rework the code slightly to make room for additional backends. Some
fixes due to Chase Douglas have been incorporated as well. The device
is mapped onto the whole screen, and the paint area is a window into
it, regardless of where the window is on screen.
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'tools/mtview.c')
| -rw-r--r-- | tools/mtview.c | 194 |
1 files changed, 112 insertions, 82 deletions
diff --git a/tools/mtview.c b/tools/mtview.c index ea6730c..7d6fdc6 100644 --- a/tools/mtview.c +++ b/tools/mtview.c | |||
| @@ -2,21 +2,24 @@ | |||
| 2 | #include <stdio.h> | 2 | #include <stdio.h> |
| 3 | #include <fcntl.h> | 3 | #include <fcntl.h> |
| 4 | #include <utouch/frame-mtdev.h> | 4 | #include <utouch/frame-mtdev.h> |
| 5 | #include <stdlib.h> | ||
| 6 | #include <unistd.h> | ||
| 5 | #include <string.h> | 7 | #include <string.h> |
| 6 | #include <math.h> | 8 | #include <math.h> |
| 7 | 9 | ||
| 8 | #define XMARG 16 | ||
| 9 | #define YMARG 16 | ||
| 10 | #define DEF_FRAC 0.15 | 10 | #define DEF_FRAC 0.15 |
| 11 | #define DEF_WIDTH 0.05 | 11 | #define DEF_WIDTH 0.05 |
| 12 | 12 | ||
| 13 | #define DIM_TOUCH 32 | 13 | #define DIM_TOUCH 32 |
| 14 | 14 | ||
| 15 | static int opcode; | ||
| 16 | |||
| 15 | struct windata { | 17 | struct windata { |
| 16 | Display *dsp; | 18 | Display *dsp; |
| 17 | Window root, win; | 19 | Window win; |
| 18 | GC gc; | 20 | GC gc; |
| 19 | int screen, width, height; | 21 | int screen; |
| 22 | float off_x, off_y; | ||
| 20 | unsigned long white, black; | 23 | unsigned long white, black; |
| 21 | unsigned long color[DIM_TOUCH]; | 24 | unsigned long color[DIM_TOUCH]; |
| 22 | int id[DIM_TOUCH]; | 25 | int id[DIM_TOUCH]; |
| @@ -32,26 +35,28 @@ static unsigned long new_color(struct windata *w) | |||
| 32 | return lrand48() & 0xffffff; | 35 | return lrand48() & 0xffffff; |
| 33 | } | 36 | } |
| 34 | 37 | ||
| 35 | static void clear_screen(struct windata *w) | 38 | static void clear_screen(utouch_frame_handle fh, struct windata *w) |
| 36 | { | 39 | { |
| 40 | const struct utouch_surface *s = utouch_frame_get_surface(fh); | ||
| 41 | int width = s->mapped_max_x - s->mapped_min_x; | ||
| 42 | int height = s->mapped_max_y - s->mapped_min_y; | ||
| 43 | |||
| 37 | XSetForeground(w->dsp, w->gc, w->black); | 44 | XSetForeground(w->dsp, w->gc, w->black); |
| 38 | XFillRectangle(w->dsp, w->win, w->gc, 0, 0, w->width, w->height); | 45 | XFillRectangle(w->dsp, w->win, w->gc, 0, 0, width, height); |
| 39 | } | 46 | } |
| 40 | 47 | ||
| 41 | static void output_touch(utouch_frame_handle fh, struct windata *w, | 48 | static void output_touch(utouch_frame_handle fh, struct windata *w, |
| 42 | const struct utouch_contact *t) | 49 | const struct utouch_contact *t) |
| 43 | { | 50 | { |
| 44 | const struct utouch_surface *s = utouch_frame_get_surface(fh); | 51 | const struct utouch_surface *s = utouch_frame_get_surface(fh); |
| 45 | 52 | float dx = s->mapped_max_x - s->mapped_min_x; | |
| 46 | float x1 = s->min_x, y1 = s->min_y; | 53 | float dy = s->mapped_max_y - s->mapped_min_y; |
| 47 | float x2 = s->max_x, y2 = s->max_y; | 54 | float x = t->x - w->off_x, y = t->y - w->off_y; |
| 48 | float dx = x2 - x1, dy = y2 - y1; | ||
| 49 | float major = 0, minor = 0, angle = 0; | 55 | float major = 0, minor = 0, angle = 0; |
| 50 | 56 | ||
| 51 | if (s->use_pressure) { | 57 | if (s->use_pressure) { |
| 52 | float p = DEF_FRAC / s->max_pressure; | 58 | major = DEF_FRAC * t->pressure * dy; |
| 53 | major = t->pressure * p * dx; | 59 | minor = DEF_FRAC * t->pressure * dx; |
| 54 | minor = t->pressure * p * dx; | ||
| 55 | angle = 0; | 60 | angle = 0; |
| 56 | } | 61 | } |
| 57 | if (s->use_touch_major) { | 62 | if (s->use_touch_major) { |
| @@ -68,15 +73,6 @@ static void output_touch(utouch_frame_handle fh, struct windata *w, | |||
| 68 | float as = fabs(sin(angle)); | 73 | float as = fabs(sin(angle)); |
| 69 | float mx = max(minor * ac, major * as); | 74 | float mx = max(minor * ac, major * as); |
| 70 | float my = max(major * ac, minor * as); | 75 | float my = max(major * ac, minor * as); |
| 71 | float ux = t->x - 0.5 * mx; | ||
| 72 | float uy = t->y - 0.5 * my; | ||
| 73 | float vx = t->x + 0.5 * mx; | ||
| 74 | float vy = t->y + 0.5 * my; | ||
| 75 | |||
| 76 | float px = (ux - x1) / dx * w->width; | ||
| 77 | float py = (uy - y1) / dy * w->height; | ||
| 78 | float qx = (vx - x1) / dx * w->width; | ||
| 79 | float qy = (vy - y1) / dy * w->height; | ||
| 80 | 76 | ||
| 81 | if (w->id[t->slot] != t->id) { | 77 | if (w->id[t->slot] != t->id) { |
| 82 | w->id[t->slot] = t->id; | 78 | w->id[t->slot] = t->id; |
| @@ -84,7 +80,9 @@ static void output_touch(utouch_frame_handle fh, struct windata *w, | |||
| 84 | } | 80 | } |
| 85 | 81 | ||
| 86 | XSetForeground(w->dsp, w->gc, w->color[t->slot]); | 82 | XSetForeground(w->dsp, w->gc, w->color[t->slot]); |
| 87 | XFillArc(w->dsp, w->win, w->gc, px, py, qx - px, qy - py, 0, 360 * 64); | 83 | |
| 84 | XFillArc(w->dsp, w->win, w->gc, x - mx / 2, y - my / 2, | ||
| 85 | mx, my, 0, 360 * 64); | ||
| 88 | XFlush(w->dsp); | 86 | XFlush(w->dsp); |
| 89 | } | 87 | } |
| 90 | 88 | ||
| @@ -98,88 +96,105 @@ static void report_frame(utouch_frame_handle fh, | |||
| 98 | output_touch(fh, w, frame->active[i]); | 96 | output_touch(fh, w, frame->active[i]); |
| 99 | } | 97 | } |
| 100 | 98 | ||
| 101 | static void event_loop(utouch_frame_handle fh, | 99 | static int init_window(struct windata *w) |
| 102 | struct mtdev *dev, int fd, | 100 | { |
| 103 | struct windata *w) | 101 | int event, err; |
| 102 | int i; | ||
| 103 | |||
| 104 | memset(w, 0, sizeof(w)); | ||
| 105 | for (i = 0; i < DIM_TOUCH; i++) | ||
| 106 | w->id[i] = -1; | ||
| 107 | |||
| 108 | w->dsp = XOpenDisplay(NULL); | ||
| 109 | if (!w->dsp) | ||
| 110 | return -1; | ||
| 111 | if (!XQueryExtension(w->dsp, "XInputExtension", &opcode, &event, &err)) | ||
| 112 | return -1; | ||
| 113 | |||
| 114 | w->screen = DefaultScreen(w->dsp); | ||
| 115 | w->white = WhitePixel(w->dsp, w->screen); | ||
| 116 | w->black = BlackPixel(w->dsp, w->screen); | ||
| 117 | |||
| 118 | w->win = XCreateSimpleWindow(w->dsp, XDefaultRootWindow(w->dsp), | ||
| 119 | 0, 0, 200, 200, 0, w->black, w->white); | ||
| 120 | w->gc = DefaultGC(w->dsp, w->screen); | ||
| 121 | |||
| 122 | XMapWindow(w->dsp, w->win); | ||
| 123 | XFlush(w->dsp); | ||
| 124 | |||
| 125 | return 0; | ||
| 126 | } | ||
| 127 | |||
| 128 | static void term_window(struct windata *w) | ||
| 129 | { | ||
| 130 | XDestroyWindow(w->dsp, w->win); | ||
| 131 | XCloseDisplay(w->dsp); | ||
| 132 | } | ||
| 133 | |||
| 134 | static void set_screen_size_mtdev(utouch_frame_handle fh, | ||
| 135 | struct windata *w, | ||
| 136 | XEvent *xev) | ||
| 137 | { | ||
| 138 | struct utouch_surface *s = utouch_frame_get_surface(fh); | ||
| 139 | XConfigureEvent *cev = (XConfigureEvent *)xev; | ||
| 140 | |||
| 141 | s->mapped_min_x = 0; | ||
| 142 | s->mapped_min_y = 0; | ||
| 143 | s->mapped_max_x = DisplayWidth(w->dsp, w->screen); | ||
| 144 | s->mapped_max_y = DisplayHeight(w->dsp, w->screen); | ||
| 145 | s->mapped_max_pressure = 1; | ||
| 146 | |||
| 147 | if (cev) { | ||
| 148 | w->off_x = cev->x; | ||
| 149 | w->off_y = cev->y; | ||
| 150 | } | ||
| 151 | |||
| 152 | fprintf(stderr, "map: %f %f %f %f %f %f\n", | ||
| 153 | w->off_x, w->off_y, | ||
| 154 | s->mapped_min_x, s->mapped_min_y, | ||
| 155 | s->mapped_max_x, s->mapped_max_y); | ||
| 156 | } | ||
| 157 | |||
| 158 | static void run_window_mtdev(utouch_frame_handle fh, struct mtdev *dev, int fd) | ||
| 104 | { | 159 | { |
| 105 | const struct utouch_frame *frame; | 160 | const struct utouch_frame *frame; |
| 106 | struct input_event iev; | 161 | struct input_event iev; |
| 162 | struct windata w; | ||
| 107 | XEvent xev; | 163 | XEvent xev; |
| 108 | 164 | ||
| 109 | XSelectInput(w->dsp, w->win, | 165 | if (init_window(&w)) |
| 110 | ButtonPressMask | ButtonReleaseMask | | 166 | return; |
| 111 | ExposureMask | StructureNotifyMask); | 167 | |
| 168 | clear_screen(fh, &w); | ||
| 169 | |||
| 170 | set_screen_size_mtdev(fh, &w, 0); | ||
| 171 | XSelectInput(w.dsp, w.win, StructureNotifyMask); | ||
| 112 | 172 | ||
| 113 | clear_screen(w); | ||
| 114 | while (1) { | 173 | while (1) { |
| 115 | while (!mtdev_idle(dev, fd, 100)) { | 174 | while (!mtdev_idle(dev, fd, 100)) { |
| 116 | while (mtdev_get(dev, fd, &iev, 1) > 0) { | 175 | while (mtdev_get(dev, fd, &iev, 1) > 0) { |
| 117 | frame = utouch_frame_pump_mtdev(fh, &iev); | 176 | frame = utouch_frame_pump_mtdev(fh, &iev); |
| 118 | if (frame) | 177 | if (frame) |
| 119 | report_frame(fh, frame, w); | 178 | report_frame(fh, frame, &w); |
| 120 | } | 179 | } |
| 121 | } | 180 | } |
| 122 | while (XPending(w->dsp)) { | 181 | while (XPending(w.dsp)) { |
| 123 | XNextEvent(w->dsp, &xev); | 182 | XNextEvent(w.dsp, &xev); |
| 183 | set_screen_size_mtdev(fh, &w, &xev); | ||
| 124 | } | 184 | } |
| 125 | } | 185 | } |
| 126 | } | ||
| 127 | |||
| 128 | static void run_window(utouch_frame_handle fh, struct mtdev *dev, int fd) | ||
| 129 | { | ||
| 130 | struct windata w; | ||
| 131 | int i; | ||
| 132 | memset(&w, 0, sizeof(w)); | ||
| 133 | for (i = 0; i < DIM_TOUCH; i++) | ||
| 134 | w.id[i] = -1; | ||
| 135 | |||
| 136 | w.dsp = XOpenDisplay(NULL); | ||
| 137 | if (!w.dsp) | ||
| 138 | return; | ||
| 139 | |||
| 140 | w.screen = DefaultScreen(w.dsp); | ||
| 141 | w.white = WhitePixel(w.dsp, w.screen); | ||
| 142 | w.black = BlackPixel(w.dsp, w.screen); | ||
| 143 | w.width = DisplayWidth(w.dsp, w.screen) - XMARG; | ||
| 144 | w.height = DisplayHeight(w.dsp, w.screen) - YMARG; | ||
| 145 | 186 | ||
| 146 | w.root = DefaultRootWindow(w.dsp); | 187 | term_window(&w); |
| 147 | w.win = XCreateSimpleWindow(w.dsp, w.root, | ||
| 148 | 0, 0, w.width, w.height, | ||
| 149 | 0, w.black, w.white); | ||
| 150 | |||
| 151 | XMapWindow(w.dsp, w.win); | ||
| 152 | |||
| 153 | long eventMask = StructureNotifyMask; | ||
| 154 | XSelectInput(w.dsp, w.win, eventMask); | ||
| 155 | |||
| 156 | XEvent ev; | ||
| 157 | do { | ||
| 158 | XNextEvent(w.dsp, &ev); | ||
| 159 | } while (ev.type != MapNotify); | ||
| 160 | |||
| 161 | |||
| 162 | w.gc = XCreateGC(w.dsp, w.win, 0, NULL); | ||
| 163 | |||
| 164 | event_loop(fh, dev, fd, &w); | ||
| 165 | |||
| 166 | XDestroyWindow(w.dsp, w.win); | ||
| 167 | XCloseDisplay(w.dsp); | ||
| 168 | } | 188 | } |
| 169 | 189 | ||
| 170 | int main(int argc, char *argv[]) | 190 | static int run_mtdev(const char *name) |
| 171 | { | 191 | { |
| 172 | struct evemu_device *evemu; | 192 | struct evemu_device *evemu; |
| 173 | struct mtdev *mtdev; | 193 | struct mtdev *mtdev; |
| 174 | utouch_frame_handle fh; | 194 | utouch_frame_handle fh; |
| 175 | int fd; | 195 | int fd; |
| 176 | 196 | ||
| 177 | if (argc < 2) { | 197 | fd = open(name, O_RDONLY | O_NONBLOCK); |
| 178 | fprintf(stderr, "Usage: %s <device>\n", argv[0]); | ||
| 179 | return -1; | ||
| 180 | } | ||
| 181 | |||
| 182 | fd = open(argv[1], O_RDONLY | O_NONBLOCK); | ||
| 183 | if (fd < 0) { | 198 | if (fd < 0) { |
| 184 | fprintf(stderr, "error: could not open device\n"); | 199 | fprintf(stderr, "error: could not open device\n"); |
| 185 | return -1; | 200 | return -1; |
| @@ -209,7 +224,7 @@ int main(int argc, char *argv[]) | |||
| 209 | return -1; | 224 | return -1; |
| 210 | } | 225 | } |
| 211 | 226 | ||
| 212 | run_window(fh, mtdev, fd); | 227 | run_window_mtdev(fh, mtdev, fd); |
| 213 | 228 | ||
| 214 | utouch_frame_delete_engine(fh); | 229 | utouch_frame_delete_engine(fh); |
| 215 | mtdev_close_delete(mtdev); | 230 | mtdev_close_delete(mtdev); |
| @@ -220,3 +235,18 @@ int main(int argc, char *argv[]) | |||
| 220 | 235 | ||
| 221 | return 0; | 236 | return 0; |
| 222 | } | 237 | } |
| 238 | |||
| 239 | int main(int argc, char *argv[]) | ||
| 240 | { | ||
| 241 | int id, ret; | ||
| 242 | |||
| 243 | if (argc < 2) { | ||
| 244 | fprintf(stderr, "Usage: %s <device>\n", argv[0]); | ||
| 245 | return -1; | ||
| 246 | } | ||
| 247 | |||
| 248 | id = atoi(argv[1]); | ||
| 249 | ret = run_mtdev(argv[1]); | ||
| 250 | |||
| 251 | return ret; | ||
| 252 | } | ||
