From a9cf916966ce0359dd5a896c8ab71774cd85f1d4 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Tue, 19 Apr 2011 14:02:25 +0200 Subject: Test utouch-frame through utouch-compiz This patch implements a simple test of the touch frame mechanism, via XI2.1 and the compiz plugin. Run compiz in the foreground to see the printouts for touches. Signed-off-by: Henrik Rydberg --- src/utouch.cpp | 197 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 188 insertions(+), 9 deletions(-) (limited to 'src/utouch.cpp') diff --git a/src/utouch.cpp b/src/utouch.cpp index e55346c..09a4c53 100644 --- a/src/utouch.cpp +++ b/src/utouch.cpp @@ -23,23 +23,202 @@ COMPIZ_PLUGIN_20090315(utouch, UtouchVTable); -bool -UtouchVTable::init() +bool UtouchVTable::init() { - return true; + compLogMessage ("utouch", CompLogLevelInfo, "init"); + + return true; +} + + +UtouchScreen::UtouchScreen(CompScreen* s) + : PluginClassHandler(s) + , screen(s) +{ + int ret, event, error; + XIEventMask mask; + + ret = XQueryExtension(screen->dpy(), "XInputExtension", + &opcode, &event, &error); + + compLogMessage ("utouch", CompLogLevelInfo, "ctor %d", ret); + + mask.deviceid = XIAllMasterDevices; + mask.mask_len = XIMaskLen(XI_LASTEVENT); + mask.mask = (unsigned char *)calloc(mask.mask_len, sizeof(char)); + + XISetMask(mask.mask, XI_TouchBegin); + XISetMask(mask.mask, XI_TouchUpdate); + XISetMask(mask.mask, XI_TouchEnd); + XISetMask(mask.mask, XI_TouchOwnership); + XISetMask(mask.mask, XI_TouchUpdateUnowned); + XISetMask(mask.mask, XI_DeviceChanged); + XISetMask(mask.mask, XI_PropertyEvent); + + //XISelectEvents(screen->dpy(), screen->root(), &mask, 1); + XIGrabModifiers mods = { XIAnyModifier, 0 }; + XIGrabTouchBegin(screen->dpy(), XIAllMasterDevices, screen->root(), + False, &mask, 1, &mods); + + ScreenInterface::setHandler(screen); } -UtouchScreen:: -UtouchScreen(CompScreen* s) -: PluginClassHandler(s) -, screen(s) +UtouchScreen::~UtouchScreen() { + for (dev_map::iterator p = devices.begin(); p != devices.end(); ++p) + utouch_frame_delete_engine(p->second); + devices.clear(); } +utouch_frame_handle UtouchScreen::createDevice(int devid) const +{ + utouch_frame_handle fh; + XIDeviceInfo *info; + int ndevices; + + info = XIQueryDevice(screen->dpy(), devid, &ndevices); + if (!info) { + compLogMessage ("utouch", CompLogLevelError, + "no info for device: %d", devid); + return 0; + } + + fh = utouch_frame_new_engine(100, 32, 100); + if (fh && utouch_frame_init_xi2(fh, screen->dpy(), info)) { + compLogMessage ("utouch", CompLogLevelError, + "bad device: %d", devid); + utouch_frame_delete_engine(fh); + fh = 0; + } -UtouchScreen:: -~UtouchScreen() + XIFreeDeviceInfo(info); + return fh; +} + +static void report_device_caps(const struct utouch_surface *s) { + fprintf(stderr, "device props:\n"); + if (s->needs_pointer) + fprintf(stderr, "\tpointer\n"); + if (s->is_direct) + fprintf(stderr, "\tdirect\n"); + if (s->is_buttonpad) + fprintf(stderr, "\tbuttonpad\n"); + if (s->is_semi_mt) + fprintf(stderr, "\tsemi_mt\n"); + fprintf(stderr, "device mt events:\n"); + if (s->use_touch_major) + fprintf(stderr, "\ttouch_major\n"); + if (s->use_touch_minor) + fprintf(stderr, "\ttouch_minor\n"); + if (s->use_width_major) + fprintf(stderr, "\twidth_major\n"); + if (s->use_width_minor) + fprintf(stderr, "\twidth_minor\n"); + if (s->use_orientation) + fprintf(stderr, "\torientation\n"); + if (s->use_pressure) + fprintf(stderr, "\tpressure\n"); + if (s->use_distance) + fprintf(stderr, "\tdistance\n"); +} + +static void report_frame(const struct utouch_frame *frame) +{ + int i; + + for (i = 0; i < (int)frame->num_active; i++) { + const struct utouch_contact *t = frame->active[i]; + + fprintf(stderr, "touch %d\n", i); + fprintf(stderr, " slot: %d\n", t->slot); + fprintf(stderr, " id: %d\n", t->id); + fprintf(stderr, " tool_type: %d\n", t->tool_type); + fprintf(stderr, " x: %f\n", t->x); + fprintf(stderr, " y: %f\n", t->y); + fprintf(stderr, " touch_major: %f\n", t->touch_major); + fprintf(stderr, " touch_minor: %f\n", t->touch_minor); + fprintf(stderr, " width_major: %f\n", t->width_major); + fprintf(stderr, " width_minor: %f\n", t->width_minor); + fprintf(stderr, " angle: %f\n", t->orientation); + fprintf(stderr, " pressure: %f\n", t->pressure); + fprintf(stderr, " distance: %f\n", t->distance); + } + + fprintf(stderr, "sync %d %ld %d %d %d\n", + frame->num_active, + frame->time, + frame->sequence_id, + frame->revision, + frame->slot_revision); +} + +void UtouchScreen::handleDeviceEvent(const XIDeviceEvent *ev) +{ + utouch_frame_handle fh; + const struct utouch_frame *frame; + + switch(ev->evtype) { + case XI_TouchOwnership: + compLogMessage ("utouch", CompLogLevelInfo, + "touch owner %d", ev->detail); + XIAllowTouchEvents(ev->display, ev->sourceid, ev->detail, + XITouchOwnerRejectContinue); + compLogMessage ("utouch", CompLogLevelInfo, + "rejected: %d %d %d %d", + ev->evtype, ev->deviceid, + ev->sourceid, ev->detail); + break; + case XI_TouchUpdateUnowned: + compLogMessage ("utouch", CompLogLevelInfo, "touch motion unowned"); + break; + case XI_DeviceChanged: + compLogMessage ("utouch", CompLogLevelInfo, "touch device changed"); + break; + case XI_PropertyEvent: + compLogMessage ("utouch", CompLogLevelInfo, "touch property changed"); + break; + case XI_TouchBegin: + case XI_TouchUpdate: + case XI_TouchEnd: + + compLogMessage ("utouch", CompLogLevelInfo, + "touch: %d %d %d %d", + ev->evtype, ev->deviceid, + ev->sourceid, ev->detail); + + fh = devices[ev->sourceid]; + if (!fh) { + fh = createDevice(ev->sourceid); + if (!fh) + return; + compLogMessage ("utouch", CompLogLevelInfo, + "new device: %d", ev->sourceid); + report_device_caps(utouch_frame_get_surface(fh)); + devices[ev->sourceid] = fh; + } + + // update on property changes here? + // update on device going away here? + + frame = utouch_frame_pump_xi2(fh, ev); + if (frame) + report_frame(frame); + break; + } +} + +void UtouchScreen::handleEvent(XEvent *ev) +{ + XGenericEventCookie *gev = &ev->xcookie; + + if (XGetEventData(screen->dpy(), gev)) { + if (gev->type == GenericEvent && gev->extension == opcode) + handleDeviceEvent((XIDeviceEvent *)gev->data); + XFreeEventData(screen->dpy(), gev); + } + + screen->handleEvent(ev); } -- cgit v1.2.3