summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mtview.c83
1 files changed, 54 insertions, 29 deletions
diff --git a/src/mtview.c b/src/mtview.c
index a733dde..0ea4688 100644
--- a/src/mtview.c
+++ b/src/mtview.c
@@ -2,18 +2,24 @@
2#include <stdio.h> 2#include <stdio.h>
3#include <fcntl.h> 3#include <fcntl.h>
4#include <grail-touch.h> 4#include <grail-touch.h>
5#include <string.h>
5#include <math.h> 6#include <math.h>
6 7
7#define XMARG 64 8#define XMARG 64
8#define YMARG 64 9#define YMARG 64
9#define WSCALE 0.5 10#define WSCALE 0.5
11#define FLUSH_MS 10
12#define DEF_FRAC 0.15
10 13
11struct windata { 14struct windata {
12 Display *dsp; 15 Display *dsp;
13 Window root, win; 16 Window root, win;
14 GC gc; 17 GC gc;
15 int screen, width, height, lastid; 18 int screen, width, height;
16 unsigned long white, black, color[DIM_TOUCH]; 19 unsigned long white, black;
20 unsigned long color[DIM_TOUCH];
21 int id[DIM_TOUCH];
22 touch_time_t last_flush;
17}; 23};
18 24
19static inline float max(float a, float b) 25static inline float max(float a, float b)
@@ -21,7 +27,7 @@ static inline float max(float a, float b)
21 return b > a ? b : a; 27 return b > a ? b : a;
22} 28}
23 29
24static unsigned long new_color() 30static unsigned long new_color(struct windata *w)
25{ 31{
26 return lrand48(); 32 return lrand48();
27} 33}
@@ -30,32 +36,55 @@ static void clear_screen(struct windata *w)
30{ 36{
31 XSetForeground(w->dsp, w->gc, w->black); 37 XSetForeground(w->dsp, w->gc, w->black);
32 XFillRectangle(w->dsp, w->win, w->gc, 0, 0, w->width, w->height); 38 XFillRectangle(w->dsp, w->win, w->gc, 0, 0, w->width, w->height);
39 XFlush(w->dsp);
33} 40}
34 41
35static void output_touch(struct touch_dev *dev, struct windata *w, 42static void output_touch(struct touch_dev *dev, struct windata *w,
36 const struct touch *t) 43 const struct touch *t)
37{ 44{
38 float a = touch_angle(dev, t->orientation); 45 float x1 = dev->caps.min_x, y1 = dev->caps.min_y;
39 float ac = fabs(cos(a)); 46 float x2 = dev->caps.max_x, y2 = dev->caps.max_y;
40 float as = fabs(sin(a)); 47 float dx = x2 - x1, dy = y2 - y1;
41 float mx = max(t->touch_minor * ac, t->touch_major * as); 48 float major = 0, minor = 0, angle = 0;
42 float my = max(t->touch_major * ac, t->touch_minor * as); 49
50 if (t->pressure > 0) {
51 float p = DEF_FRAC / dev->caps.max_press;
52 major = t->pressure * p * dx;
53 minor = t->pressure * p * dx;
54 angle = 0;
55 }
56 if (t->touch_major > 0 || t->touch_minor > 0) {
57 major = t->touch_major;
58 minor = t->touch_minor;
59 angle = touch_angle(dev, t->orientation);
60 }
61
62 float ac = fabs(cos(angle));
63 float as = fabs(sin(angle));
64 float mx = max(minor * ac, major * as);
65 float my = max(major * ac, minor * as);
43 float ux = t->x - 0.5 * mx; 66 float ux = t->x - 0.5 * mx;
44 float uy = t->y - 0.5 * my; 67 float uy = t->y - 0.5 * my;
45 float vx = t->x + 0.5 * mx; 68 float vx = t->x + 0.5 * mx;
46 float vy = t->y + 0.5 * my; 69 float vy = t->y + 0.5 * my;
47 70
48 float x1 = dev->caps.min_x, y1 = dev->caps.min_y;
49 float x2 = dev->caps.max_x, y2 = dev->caps.max_y;
50 float dx = x2 - x1, dy = y2 - y1;
51 float px = (ux - x1) / dx * w->width; 71 float px = (ux - x1) / dx * w->width;
52 float py = (uy - y1) / dy * w->height; 72 float py = (uy - y1) / dy * w->height;
53 float qx = (vx - x1) / dx * w->width; 73 float qx = (vx - x1) / dx * w->width;
54 float qy = (vy - y1) / dy * w->height; 74 float qy = (vy - y1) / dy * w->height;
55 if (t->id > w->lastid) 75
56 w->color[t->slot] = new_color(); 76 if (w->id[t->slot] != t->id) {
77 w->id[t->slot] = t->id;
78 w->color[t->slot] = new_color(w);
79 }
80
57 XSetForeground(w->dsp, w->gc, w->color[t->slot]); 81 XSetForeground(w->dsp, w->gc, w->color[t->slot]);
58 XFillArc(w->dsp, w->win, w->gc, px, py, qx - px, qy - py, 0, 360 * 64); 82 XFillArc(w->dsp, w->win, w->gc, px, py, qx - px, qy - py, 0, 360 * 64);
83
84 if (dev->frame.time - w->last_flush > FLUSH_MS) {
85 XFlush(w->dsp);
86 w->last_flush = dev->frame.time;
87 }
59} 88}
60 89
61static void tp_event(struct touch_dev *dev, 90static void tp_event(struct touch_dev *dev,
@@ -68,14 +97,9 @@ static void tp_sync(struct touch_dev *dev,
68{ 97{
69 struct windata *w = dev->priv; 98 struct windata *w = dev->priv;
70 struct touch_frame *frame = &dev->frame; 99 struct touch_frame *frame = &dev->frame;
71 int i, lastid = 0; 100 int i;
72 for (i = 0; i < frame->nactive; i++) { 101 for (i = 0; i < frame->nactive; i++)
73 const struct touch *t = frame->active[i]; 102 output_touch(dev, w, frame->active[i]);
74 output_touch(dev, w, t);
75 if (t->id > lastid)
76 lastid = t->id;
77 }
78 w->lastid = lastid;
79} 103}
80 104
81static void event_loop(struct touch_dev *dev, int fd, struct windata *w) 105static void event_loop(struct touch_dev *dev, int fd, struct windata *w)
@@ -85,28 +109,29 @@ static void event_loop(struct touch_dev *dev, int fd, struct windata *w)
85 dev->event = tp_event; 109 dev->event = tp_event;
86 dev->sync = tp_sync; 110 dev->sync = tp_sync;
87 dev->priv = w; 111 dev->priv = w;
88 w->lastid = -1;
89 112
90 XSelectInput(w->dsp, w->win, ButtonPress | ButtonRelease); 113 XSelectInput(w->dsp, w->win,
91 clear_screen(w); 114 ButtonPressMask | ButtonReleaseMask | ExposureMask);
92 XFlush(w->dsp);
93 115
116 clear_screen(w);
94 while (1) { 117 while (1) {
118 while(!touch_dev_idle(dev, fd, 1000))
119 touch_dev_pull(dev, fd);
95 if (XEventsQueued(w->dsp, QueuedAlready)) { 120 if (XEventsQueued(w->dsp, QueuedAlready)) {
96 XNextEvent(w->dsp, &ev); 121 XNextEvent(w->dsp, &ev);
97 if (ev.type == ButtonRelease) 122 if (ev.type == ButtonRelease)
98 break; 123 break;
99 } 124 }
100 if(!touch_dev_idle(dev, fd, 100)) {
101 touch_dev_pull(dev, fd);
102 XFlush(w->dsp);
103 }
104 } 125 }
105} 126}
106 127
107static void run_window(struct touch_dev *dev, int fd) 128static void run_window(struct touch_dev *dev, int fd)
108{ 129{
109 struct windata w; 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;
110 135
111 w.dsp = XOpenDisplay(NULL); 136 w.dsp = XOpenDisplay(NULL);
112 if (!w.dsp) 137 if (!w.dsp)