summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@bitmath.org>2010-08-27 21:40:09 +0200
committerHenrik Rydberg <rydberg@bitmath.org>2010-08-27 21:40:09 +0200
commit0732a5df62351a124db35761f8928dc359752e25 (patch)
treed1d2518b419f8d211a75573cbf7b607277e18740
Simple MT contact drawing application
Uses grail-touch and mtdev. Signed-off-by: Henrik Rydberg <rydberg@bitmath.org>
-rw-r--r--.gitignore2
-rw-r--r--Makefile35
-rw-r--r--src/mtview.c146
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 @@
+bin
+obj
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..9d000ae
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,35 @@
+SOURCES = mtview
+TARGETS = mtview
+
+TARG = $(addprefix bin/,$(TARGETS))
+TOBJ = $(addprefix obj/,$(addsuffix .o,$(SOURCES)))
+
+INCLUDE =
+LIBS = -lX11 -lutouch-grail -lmtdev
+
+COMP = gcc -O3 $(INCLUDE) -c $< -o $@
+LINK = gcc $< $(LIBS) -o $@
+
+.PHONY: all man html clean mkobj
+.PRECIOUS: obj/%.o
+
+all: $(TOBJ) $(TARG)
+
+bin/%: obj/%.o
+ @mkdir -p $(@D)
+ $(LINK)
+
+obj/%.o: src/%.c
+ @mkdir -p $(@D)
+ $(COMP)
+
+man:
+ @rm -rf man
+ doxygen etc/doxman
+
+html:
+ @rm -rf html
+ doxygen etc/doxhtml
+
+clean:
+ 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 @@
+#include <X11/Xlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <grail-touch.h>
+
+#define XMARG 64
+#define YMARG 64
+#define WSCALE 0.5
+
+struct windata {
+ Display *dsp;
+ Window root, win;
+ GC gc;
+ int screen, width, height, lastid;
+ unsigned long white, black, color[DIM_TOUCH];
+};
+
+static unsigned long new_color()
+{
+ return lrand48();
+}
+
+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);
+}
+
+static void output_touch(struct touch_dev *dev, struct windata *w,
+ const struct touch *t)
+{
+ float x1 = dev->caps.min_x, y1 = dev->caps.min_y;
+ float x2 = dev->caps.max_x, y2 = dev->caps.max_y;
+ int x = (t->x - x1) / (x2 - x1) * w->width;
+ int y = (t->y - y1) / (y2 - y1) * w->height;
+ int d = t->touch_major / (x2 - x1) * w->width * WSCALE;
+ if (t->id > w->lastid)
+ w->color[t->slot] = new_color();
+ XSetForeground(w->dsp, w->gc, w->color[t->slot]);
+ XFillArc(w->dsp, w->win, w->gc, x, y, d, d, 0, 360 * 64);
+}
+
+static void tp_event(struct touch_dev *dev,
+ const struct input_event *ev)
+{
+}
+
+static void tp_sync(struct touch_dev *dev,
+ const struct input_event *syn)
+{
+ 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;
+}
+
+static void event_loop(struct touch_dev *dev, int fd, struct windata *w)
+{
+ XEvent ev;
+
+ dev->event = tp_event;
+ dev->sync = tp_sync;
+ dev->priv = w;
+ w->lastid = -1;
+
+ XSelectInput(w->dsp, w->win, ButtonPressMask | ButtonReleaseMask);
+ while (1) {
+ XNextEvent(w->dsp, &ev);
+ clear_screen(w);
+ XNextEvent(w->dsp, &ev);
+ while (!touch_dev_idle(dev, fd, 1000))
+ touch_dev_pull(dev, fd);
+ }
+}
+
+static void run_window(struct touch_dev *dev, int fd)
+{
+ struct windata w;
+
+ w.dsp = XOpenDisplay(NULL);
+ if (!w.dsp)
+ return;
+
+ w.screen = DefaultScreen(w.dsp);
+ w.white = WhitePixel(w.dsp, w.screen);
+ w.black = BlackPixel(w.dsp, w.screen);
+ w.width = DisplayWidth(w.dsp, w.screen) - XMARG;
+ w.height = DisplayHeight(w.dsp, w.screen) - YMARG;
+
+ w.root = DefaultRootWindow(w.dsp);
+ w.win = XCreateSimpleWindow(w.dsp, w.root,
+ 0, 0, w.width, w.height,
+ 0, w.black, w.white);
+
+ XMapWindow(w.dsp, w.win);
+
+ long eventMask = StructureNotifyMask;
+ XSelectInput(w.dsp, w.win, eventMask);
+
+ XEvent ev;
+ do {
+ XNextEvent(w.dsp, &ev);
+ } while (ev.type != MapNotify);
+
+
+ w.gc = XCreateGC(w.dsp, w.win, 0, NULL);
+
+ event_loop(dev, fd, &w);
+
+ XDestroyWindow(w.dsp, w.win);
+ XCloseDisplay(w.dsp);
+}
+
+int main(int argc, char *argv[])
+{
+ struct touch_dev dev;
+ int fd;
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s <device>\n", argv[0]);
+ return -1;
+ }
+ fd = open(argv[1], O_RDONLY | O_NONBLOCK);
+ if (fd < 0) {
+ fprintf(stderr, "error: could not open device\n");
+ return -1;
+ }
+ if (ioctl(fd, EVIOCGRAB, 1)) {
+ fprintf(stderr, "error: could not grab the device\n");
+ return -1;
+ }
+ if (touch_dev_open(&dev, fd)) {
+ fprintf(stderr, "error: could not open touch device\n");
+ return -1;
+ }
+ run_window(&dev, fd);
+ touch_dev_close(&dev, fd);
+ ioctl(fd, EVIOCGRAB, 0);
+ close(fd);
+ return 0;
+}