diff options
| author | Henrik Rydberg <rydberg@bitmath.org> | 2010-08-27 21:40:09 +0200 |
|---|---|---|
| committer | Henrik Rydberg <rydberg@bitmath.org> | 2010-08-27 21:40:09 +0200 |
| commit | 0732a5df62351a124db35761f8928dc359752e25 (patch) | |
| tree | d1d2518b419f8d211a75573cbf7b607277e18740 | |
Simple MT contact drawing application
Uses grail-touch and mtdev.
Signed-off-by: Henrik Rydberg <rydberg@bitmath.org>
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | Makefile | 35 | ||||
| -rw-r--r-- | src/mtview.c | 146 |
3 files changed, 183 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1746e32 --- /dev/null +++ b/.gitignore | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | bin | ||
| 2 | obj | ||
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9d000ae --- /dev/null +++ b/Makefile | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | SOURCES = mtview | ||
| 2 | TARGETS = mtview | ||
| 3 | |||
| 4 | TARG = $(addprefix bin/,$(TARGETS)) | ||
| 5 | TOBJ = $(addprefix obj/,$(addsuffix .o,$(SOURCES))) | ||
| 6 | |||
| 7 | INCLUDE = | ||
| 8 | LIBS = -lX11 -lutouch-grail -lmtdev | ||
| 9 | |||
| 10 | COMP = gcc -O3 $(INCLUDE) -c $< -o $@ | ||
| 11 | LINK = gcc $< $(LIBS) -o $@ | ||
| 12 | |||
| 13 | .PHONY: all man html clean mkobj | ||
| 14 | .PRECIOUS: obj/%.o | ||
| 15 | |||
| 16 | all: $(TOBJ) $(TARG) | ||
| 17 | |||
| 18 | bin/%: obj/%.o | ||
| 19 | @mkdir -p $(@D) | ||
| 20 | $(LINK) | ||
| 21 | |||
| 22 | obj/%.o: src/%.c | ||
| 23 | @mkdir -p $(@D) | ||
| 24 | $(COMP) | ||
| 25 | |||
| 26 | man: | ||
| 27 | @rm -rf man | ||
| 28 | doxygen etc/doxman | ||
| 29 | |||
| 30 | html: | ||
| 31 | @rm -rf html | ||
| 32 | doxygen etc/doxhtml | ||
| 33 | |||
| 34 | clean: | ||
| 35 | rm -rf man html bin obj auto | ||
diff --git a/src/mtview.c b/src/mtview.c new file mode 100644 index 0000000..b8c3e37 --- /dev/null +++ b/src/mtview.c | |||
| @@ -0,0 +1,146 @@ | |||
| 1 | #include <X11/Xlib.h> | ||
| 2 | #include <stdio.h> | ||
| 3 | #include <fcntl.h> | ||
| 4 | #include <grail-touch.h> | ||
| 5 | |||
| 6 | #define XMARG 64 | ||
| 7 | #define YMARG 64 | ||
| 8 | #define WSCALE 0.5 | ||
| 9 | |||
| 10 | struct windata { | ||
| 11 | Display *dsp; | ||
| 12 | Window root, win; | ||
| 13 | GC gc; | ||
| 14 | int screen, width, height, lastid; | ||
| 15 | unsigned long white, black, color[DIM_TOUCH]; | ||
| 16 | }; | ||
| 17 | |||
| 18 | static unsigned long new_color() | ||
| 19 | { | ||
| 20 | return lrand48(); | ||
| 21 | } | ||
| 22 | |||
| 23 | static void clear_screen(struct windata *w) | ||
| 24 | { | ||
| 25 | XSetForeground(w->dsp, w->gc, w->black); | ||
| 26 | XFillRectangle(w->dsp, w->win, w->gc, 0, 0, w->width, w->height); | ||
| 27 | } | ||
| 28 | |||
| 29 | static void output_touch(struct touch_dev *dev, struct windata *w, | ||
| 30 | const struct touch *t) | ||
| 31 | { | ||
| 32 | float x1 = dev->caps.min_x, y1 = dev->caps.min_y; | ||
| 33 | float x2 = dev->caps.max_x, y2 = dev->caps.max_y; | ||
| 34 | int x = (t->x - x1) / (x2 - x1) * w->width; | ||
| 35 | int y = (t->y - y1) / (y2 - y1) * w->height; | ||
| 36 | int d = t->touch_major / (x2 - x1) * w->width * WSCALE; | ||
| 37 | if (t->id > w->lastid) | ||
| 38 | w->color[t->slot] = new_color(); | ||
| 39 | XSetForeground(w->dsp, w->gc, w->color[t->slot]); | ||
| 40 | XFillArc(w->dsp, w->win, w->gc, x, y, d, d, 0, 360 * 64); | ||
| 41 | } | ||
| 42 | |||
| 43 | static void tp_event(struct touch_dev *dev, | ||
| 44 | const struct input_event *ev) | ||
| 45 | { | ||
| 46 | } | ||
| 47 | |||
| 48 | static void tp_sync(struct touch_dev *dev, | ||
| 49 | const struct input_event *syn) | ||
| 50 | { | ||
| 51 | struct windata *w = dev->priv; | ||
| 52 | struct touch_frame *frame = &dev->frame; | ||
| 53 | int i, lastid = 0; | ||
| 54 | for (i = 0; i < frame->nactive; i++) { | ||
| 55 | const struct touch *t = frame->active[i]; | ||
| 56 | output_touch(dev, w, t); | ||
| 57 | if (t->id > lastid) | ||
| 58 | lastid = t->id; | ||
| 59 | } | ||
| 60 | w->lastid = lastid; | ||
| 61 | } | ||
| 62 | |||
| 63 | static void event_loop(struct touch_dev *dev, int fd, struct windata *w) | ||
| 64 | { | ||
| 65 | XEvent ev; | ||
| 66 | |||
| 67 | dev->event = tp_event; | ||
| 68 | dev->sync = tp_sync; | ||
| 69 | dev->priv = w; | ||
| 70 | w->lastid = -1; | ||
| 71 | |||
| 72 | XSelectInput(w->dsp, w->win, ButtonPressMask | ButtonReleaseMask); | ||
| 73 | while (1) { | ||
| 74 | XNextEvent(w->dsp, &ev); | ||
| 75 | clear_screen(w); | ||
| 76 | XNextEvent(w->dsp, &ev); | ||
| 77 | while (!touch_dev_idle(dev, fd, 1000)) | ||
| 78 | touch_dev_pull(dev, fd); | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | static void run_window(struct touch_dev *dev, int fd) | ||
| 83 | { | ||
| 84 | struct windata w; | ||
| 85 | |||
| 86 | w.dsp = XOpenDisplay(NULL); | ||
| 87 | if (!w.dsp) | ||
| 88 | return; | ||
| 89 | |||
| 90 | w.screen = DefaultScreen(w.dsp); | ||
| 91 | w.white = WhitePixel(w.dsp, w.screen); | ||
| 92 | w.black = BlackPixel(w.dsp, w.screen); | ||
| 93 | w.width = DisplayWidth(w.dsp, w.screen) - XMARG; | ||
| 94 | w.height = DisplayHeight(w.dsp, w.screen) - YMARG; | ||
| 95 | |||
| 96 | w.root = DefaultRootWindow(w.dsp); | ||
| 97 | w.win = XCreateSimpleWindow(w.dsp, w.root, | ||
| 98 | 0, 0, w.width, w.height, | ||
| 99 | 0, w.black, w.white); | ||
| 100 | |||
| 101 | XMapWindow(w.dsp, w.win); | ||
| 102 | |||
| 103 | long eventMask = StructureNotifyMask; | ||
| 104 | XSelectInput(w.dsp, w.win, eventMask); | ||
| 105 | |||
| 106 | XEvent ev; | ||
| 107 | do { | ||
| 108 | XNextEvent(w.dsp, &ev); | ||
| 109 | } while (ev.type != MapNotify); | ||
| 110 | |||
| 111 | |||
| 112 | w.gc = XCreateGC(w.dsp, w.win, 0, NULL); | ||
| 113 | |||
| 114 | event_loop(dev, fd, &w); | ||
| 115 | |||
| 116 | XDestroyWindow(w.dsp, w.win); | ||
| 117 | XCloseDisplay(w.dsp); | ||
| 118 | } | ||
| 119 | |||
| 120 | int main(int argc, char *argv[]) | ||
| 121 | { | ||
| 122 | struct touch_dev dev; | ||
| 123 | int fd; | ||
| 124 | if (argc < 2) { | ||
| 125 | fprintf(stderr, "Usage: %s <device>\n", argv[0]); | ||
| 126 | return -1; | ||
| 127 | } | ||
| 128 | fd = open(argv[1], O_RDONLY | O_NONBLOCK); | ||
| 129 | if (fd < 0) { | ||
| 130 | fprintf(stderr, "error: could not open device\n"); | ||
| 131 | return -1; | ||
| 132 | } | ||
| 133 | if (ioctl(fd, EVIOCGRAB, 1)) { | ||
| 134 | fprintf(stderr, "error: could not grab the device\n"); | ||
| 135 | return -1; | ||
| 136 | } | ||
| 137 | if (touch_dev_open(&dev, fd)) { | ||
| 138 | fprintf(stderr, "error: could not open touch device\n"); | ||
| 139 | return -1; | ||
| 140 | } | ||
| 141 | run_window(&dev, fd); | ||
| 142 | touch_dev_close(&dev, fd); | ||
| 143 | ioctl(fd, EVIOCGRAB, 0); | ||
| 144 | close(fd); | ||
| 145 | return 0; | ||
| 146 | } | ||
