From 41197333c6779832bd718fa55ed1b17d97e02304 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Thu, 30 Dec 2010 20:51:35 +0100 Subject: Switch to autotools To simplify the creation of packages for mtview, swtich to using the autoconf make tools. Signed-off-by: Henrik Rydberg --- tools/mtview.c | 222 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 tools/mtview.c (limited to 'tools/mtview.c') diff --git a/tools/mtview.c b/tools/mtview.c new file mode 100644 index 0000000..ea6730c --- /dev/null +++ b/tools/mtview.c @@ -0,0 +1,222 @@ +#include +#include +#include +#include +#include +#include + +#define XMARG 16 +#define YMARG 16 +#define DEF_FRAC 0.15 +#define DEF_WIDTH 0.05 + +#define DIM_TOUCH 32 + +struct windata { + Display *dsp; + Window root, win; + GC gc; + int screen, width, height; + unsigned long white, black; + unsigned long color[DIM_TOUCH]; + int id[DIM_TOUCH]; +}; + +static inline float max(float a, float b) +{ + return b > a ? b : a; +} + +static unsigned long new_color(struct windata *w) +{ + return lrand48() & 0xffffff; +} + +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(utouch_frame_handle fh, struct windata *w, + const struct utouch_contact *t) +{ + const struct utouch_surface *s = utouch_frame_get_surface(fh); + + float x1 = s->min_x, y1 = s->min_y; + float x2 = s->max_x, y2 = s->max_y; + float dx = x2 - x1, dy = y2 - y1; + float major = 0, minor = 0, angle = 0; + + if (s->use_pressure) { + float p = DEF_FRAC / s->max_pressure; + major = t->pressure * p * dx; + minor = t->pressure * p * dx; + angle = 0; + } + if (s->use_touch_major) { + major = t->touch_major; + minor = t->touch_minor; + angle = t->orientation; + } + if (major == 0 && minor == 0) { + major = DEF_WIDTH * dy; + minor = DEF_WIDTH * dx; + } + + 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 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 (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); + XFlush(w->dsp); +} + +static void report_frame(utouch_frame_handle fh, + const struct utouch_frame *frame, + struct windata *w) +{ + int i; + + for (i = 0; i < frame->num_active; i++) + output_touch(fh, w, frame->active[i]); +} + +static void event_loop(utouch_frame_handle fh, + struct mtdev *dev, int fd, + struct windata *w) +{ + const struct utouch_frame *frame; + struct input_event iev; + XEvent xev; + + XSelectInput(w->dsp, w->win, + ButtonPressMask | ButtonReleaseMask | + ExposureMask | StructureNotifyMask); + + clear_screen(w); + while (1) { + while (!mtdev_idle(dev, fd, 100)) { + while (mtdev_get(dev, fd, &iev, 1) > 0) { + frame = utouch_frame_pump_mtdev(fh, &iev); + if (frame) + report_frame(fh, frame, w); + } + } + while (XPending(w->dsp)) { + XNextEvent(w->dsp, &xev); + } + } +} + +static void run_window(utouch_frame_handle fh, struct mtdev *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) + 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(fh, dev, fd, &w); + + XDestroyWindow(w.dsp, w.win); + XCloseDisplay(w.dsp); +} + +int main(int argc, char *argv[]) +{ + struct evemu_device *evemu; + struct mtdev *mtdev; + utouch_frame_handle fh; + int fd; + + if (argc < 2) { + fprintf(stderr, "Usage: %s \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; + } + + evemu = evemu_new(0); + if (!evemu || evemu_extract(evemu, fd)) { + fprintf(stderr, "error: could not describe device\n"); + return -1; + } + if (!utouch_frame_is_supported_mtdev(evemu)) { + fprintf(stderr, "error: unsupported device\n"); + return -1; + } + mtdev = mtdev_new_open(fd); + if (!mtdev) { + fprintf(stderr, "error: could not open mtdev\n"); + return -1; + } + fh = utouch_frame_new_engine(100, 32, 100); + if (!fh || utouch_frame_init_mtdev(fh, evemu)) { + fprintf(stderr, "error: could not init frame\n"); + return -1; + } + + run_window(fh, mtdev, fd); + + utouch_frame_delete_engine(fh); + mtdev_close_delete(mtdev); + evemu_delete(evemu); + + ioctl(fd, EVIOCGRAB, 0); + close(fd); + + return 0; +} -- cgit v1.2.3