summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mtview.c146
1 files changed, 146 insertions, 0 deletions
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
10struct 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
18static unsigned long new_color()
19{
20 return lrand48();
21}
22
23static 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
29static 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
43static void tp_event(struct touch_dev *dev,
44 const struct input_event *ev)
45{
46}
47
48static 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
63static 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
82static 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
120int 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}