summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@bitmath.org>2010-08-30 02:39:57 +0200
committerHenrik Rydberg <rydberg@bitmath.org>2010-08-30 02:39:57 +0200
commitb54a969c469bb41ae82de343b1e85f376f48f9ec (patch)
treeb5c06b8e50cc7d633fba27e3245219475d76f9bb
parentdb8c04052596ca0271d11f3516b56288f51854a1 (diff)
reasonable behavior
-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 @@
#include <stdio.h>
#include <fcntl.h>
#include <grail-touch.h>
+#include <string.h>
#include <math.h>
#define XMARG 64
#define YMARG 64
#define WSCALE 0.5
+#define FLUSH_MS 10
+#define DEF_FRAC 0.15
struct windata {
Display *dsp;
Window root, win;
GC gc;
- int screen, width, height, lastid;
- unsigned long white, black, color[DIM_TOUCH];
+ int screen, width, height;
+ unsigned long white, black;
+ unsigned long color[DIM_TOUCH];
+ int id[DIM_TOUCH];
+ touch_time_t last_flush;
};
static inline float max(float a, float b)
@@ -21,7 +27,7 @@ static inline float max(float a, float b)
return b > a ? b : a;
}
-static unsigned long new_color()
+static unsigned long new_color(struct windata *w)
{
return lrand48();
}
@@ -30,32 +36,55 @@ static void clear_screen(struct windata *w)
{
XSetForeground(w->dsp, w->gc, w->black);
XFillRectangle(w->dsp, w->win, w->gc, 0, 0, w->width, w->height);
+ XFlush(w->dsp);
}
static void output_touch(struct touch_dev *dev, struct windata *w,
const struct touch *t)
{
- float a = touch_angle(dev, t->orientation);
- float ac = fabs(cos(a));
- float as = fabs(sin(a));
- float mx = max(t->touch_minor * ac, t->touch_major * as);
- float my = max(t->touch_major * ac, t->touch_minor * as);
+ float x1 = dev->caps.min_x, y1 = dev->caps.min_y;
+ float x2 = dev->caps.max_x, y2 = dev->caps.max_y;
+ float dx = x2 - x1, dy = y2 - y1;
+ float major = 0, minor = 0, angle = 0;
+
+ if (t->pressure > 0) {
+ float p = DEF_FRAC / dev->caps.max_press;
+ major = t->pressure * p * dx;
+ minor = t->pressure * p * dx;
+ angle = 0;
+ }
+ if (t->touch_major > 0 || t->touch_minor > 0) {
+ major = t->touch_major;
+ minor = t->touch_minor;
+ angle = touch_angle(dev, t->orientation);
+ }
+
+ float ac = fabs(cos(angle));
+ float as = fabs(sin(angle));
+ float mx = max(minor * ac, major * as);
+ float my = max(major * ac, minor * as);
float ux = t->x - 0.5 * mx;
float uy = t->y - 0.5 * my;
float vx = t->x + 0.5 * mx;
float vy = t->y + 0.5 * my;
- float x1 = dev->caps.min_x, y1 = dev->caps.min_y;
- float x2 = dev->caps.max_x, y2 = dev->caps.max_y;
- float dx = x2 - x1, dy = y2 - y1;
float px = (ux - x1) / dx * w->width;
float py = (uy - y1) / dy * w->height;
float qx = (vx - x1) / dx * w->width;
float qy = (vy - y1) / dy * w->height;
- if (t->id > w->lastid)
- w->color[t->slot] = new_color();
+
+ if (w->id[t->slot] != t->id) {
+ w->id[t->slot] = t->id;
+ w->color[t->slot] = new_color(w);
+ }
+
XSetForeground(w->dsp, w->gc, w->color[t->slot]);
XFillArc(w->dsp, w->win, w->gc, px, py, qx - px, qy - py, 0, 360 * 64);
+
+ if (dev->frame.time - w->last_flush > FLUSH_MS) {
+ XFlush(w->dsp);
+ w->last_flush = dev->frame.time;
+ }
}
static void tp_event(struct touch_dev *dev,
@@ -68,14 +97,9 @@ static void tp_sync(struct touch_dev *dev,
{
struct windata *w = dev->priv;
struct touch_frame *frame = &dev->frame;
- int i, lastid = 0;
- for (i = 0; i < frame->nactive; i++) {
- const struct touch *t = frame->active[i];
- output_touch(dev, w, t);
- if (t->id > lastid)
- lastid = t->id;
- }
- w->lastid = lastid;
+ int i;
+ for (i = 0; i < frame->nactive; i++)
+ output_touch(dev, w, frame->active[i]);
}
static 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)
dev->event = tp_event;
dev->sync = tp_sync;
dev->priv = w;
- w->lastid = -1;
- XSelectInput(w->dsp, w->win, ButtonPress | ButtonRelease);
- clear_screen(w);
- XFlush(w->dsp);
+ XSelectInput(w->dsp, w->win,
+ ButtonPressMask | ButtonReleaseMask | ExposureMask);
+ clear_screen(w);
while (1) {
+ while(!touch_dev_idle(dev, fd, 1000))
+ touch_dev_pull(dev, fd);
if (XEventsQueued(w->dsp, QueuedAlready)) {
XNextEvent(w->dsp, &ev);
if (ev.type == ButtonRelease)
break;
}
- if(!touch_dev_idle(dev, fd, 100)) {
- touch_dev_pull(dev, fd);
- XFlush(w->dsp);
- }
}
}
static void run_window(struct touch_dev *dev, int fd)
{
struct windata w;
+ int i;
+ memset(&w, 0, sizeof(w));
+ for (i = 0; i < DIM_TOUCH; i++)
+ w.id[i] = -1;
w.dsp = XOpenDisplay(NULL);
if (!w.dsp)