[Please Cc: me as I'm not subscribed to the list] This should work with xorg-x11-drv-mtev driver included in MeeGo (http://build.meego.com/package/files?package=xorg-x11-drv-mtev&project=devel%3Ax11%3A1.2 ) providing you have a multitouch panel and that the kernel reports multitouch events (mostly handled by hid-multitouch nowadays).
It works pretty well with full screen windows, but has all the known problems of multitouch in a windowed environment. For proper multitouch support, one should wait for Xinput 2.2 : http://cgit.freedesktop.org/~cndougla/inputproto/ But we don't wanna wait, do we ? This patch mimics the adaptation that was done to Qt in MeeGo to support multitouch events hidden in valuators: http://build.meego.com/package/view_file?file=add_xinput2_support.patch&package=qt&project=MeeGo%3A1.2%3Aoss&srcmd5=7f67b59bcb70b759c9667bfa15e9ab3b Known problems: - we register for Xinput and Xinput 2(XIFloatingSlave and XISlavePointer) events, so you'll receive events for the first finger two times. We can mitigate that by not sending track point with id 0, but then the app would need to look at multi_move and mouse_move events to have all the data. - since there's no xinput-level integration events coordinates are converted to match screen coordinates. This doesn't work with more than one screen. - the tracking id for each finger has no correlation with the device id. Right now we use a dirty hack (devid+trackingid) to separate each fingers. - there's no corresponding field for touch major/minor (touch finger size) in ecore events structures. Other concepts are probably left out. - you'll receive the second finger event only if the first finger is in your window. Otherwise it will be grabbed by the window that has the first finger. - it only works with an out-of-tree xorg driver. - it was only tested on a Pegatron Lucid (WeTab, ExoPC, Ordissimo Tablet) --- src/lib/ecore_x/xlib/ecore_x_xi2.c | 189 +++++++++++++++++++++++++----------- 1 files changed, 130 insertions(+), 59 deletions(-) diff --git a/src/lib/ecore_x/xlib/ecore_x_xi2.c b/src/lib/ecore_x/xlib/ecore_x_xi2.c index 8c0611d..c918cfa 100644 --- a/src/lib/ecore_x/xlib/ecore_x_xi2.c +++ b/src/lib/ecore_x/xlib/ecore_x_xi2.c @@ -17,6 +17,27 @@ int _ecore_x_xi2_opcode = -1; #ifdef ECORE_XI2 static XIDeviceInfo *_ecore_x_xi2_devs = NULL; static int _ecore_x_xi2_num = 0; + +enum AbsMTLabels { + AbsMTPositionX = 0, + AbsMTPositionY, + AbsMTTouchMajor, + AbsMTTouchMinor, + AbsMTTrackingID, + + AbsMTNumber +}; + +static const char* const atom_labels_str[] = { + "Abs MT Position X", + "Abs MT Position Y", + "Abs MT Touch Major", + "Abs MT Touch Minor", + "Abs MT Tracking ID", +}; + +static Atom atom_labels[AbsMTNumber]; + #endif /* ifdef ECORE_XI2 */ void @@ -25,6 +46,7 @@ _ecore_x_input_init(void) #ifdef ECORE_XI2 int event, error; int major = 2, minor = 0; + int i; if (!XQueryExtension(_ecore_x_disp, "XInputExtension", &_ecore_x_xi2_opcode, &event, &error)) @@ -41,6 +63,8 @@ _ecore_x_input_init(void) _ecore_x_xi2_devs = XIQueryDevice(_ecore_x_disp, XIAllDevices, &_ecore_x_xi2_num); + for(i = 0; i < AbsMTNumber ; i++) + atom_labels[i] = XInternAtom(_ecore_x_disp, atom_labels_str[i], False); #endif /* ifdef ECORE_XI2 */ } /* _ecore_x_input_init */ @@ -65,65 +89,110 @@ _ecore_x_input_handler(XEvent *xevent) #ifdef ECORE_XI2 XIDeviceEvent *evd = (XIDeviceEvent *)(xevent->xcookie.data); int devid = evd->deviceid; + XIDeviceInfo *dev = NULL; + int i = 0; - //printf("deviceID = %d\n", devid); - switch (xevent->xcookie.evtype) - { - case XI_Motion: - _ecore_mouse_move - (evd->time, - 0, // state - evd->event_x, evd->event_y, - evd->root_x, evd->root_y, - evd->event, - (evd->child ? evd->child : evd->event), - evd->root, - 1, // same_screen - devid, 1, 1, - 1.0, // pressure - 0.0, // angle - evd->event_x, evd->event_y, - evd->root_x, evd->root_y); - break; - - case XI_ButtonPress: - _ecore_mouse_button - (ECORE_EVENT_MOUSE_BUTTON_DOWN, - evd->time, - 0, // state - 0, // button - evd->event_x, evd->event_y, - evd->root_x, evd->root_y, - evd->event, - (evd->child ? evd->child : evd->event), - evd->root, - 1, // same_screen - devid, 1, 1, - 1.0, // pressure - 0.0, // angle - evd->event_x, evd->event_y, - evd->root_x, evd->root_y); - break; - - case XI_ButtonRelease: - _ecore_mouse_button - (ECORE_EVENT_MOUSE_BUTTON_UP, - evd->time, - 0, // state - 0, // button - evd->event_x, evd->event_y, - evd->root_x, evd->root_y, - evd->event, - (evd->child ? evd->child : evd->event), - evd->root, - 1, // same_screen - devid, 1, 1, - 1.0, // pressure - 0.0, // angle - evd->event_x, evd->event_y, - evd->root_x, evd->root_y); - break; - } /* switch */ + /* Get XIDeviceInfo structure */ + for (i = 0; i < _ecore_x_xi2_num; i++) + if (devid == _ecore_x_xi2_devs[i].deviceid) + { + dev = &(_ecore_x_xi2_devs[i]); + break; + } + + for (i = 0; i < dev->num_classes; ++i) { + XIAnyClassInfo *classinfo = dev->classes[i]; + if (classinfo && classinfo->type == XIValuatorClass ) { + XIValuatorClassInfo *valuatorclassinfo = (XIValuatorClassInfo*)classinfo; + int n = valuatorclassinfo->number; + double x, y, winx, winy; + + if (!XIMaskIsSet(evd->valuators.mask, n)) + continue; + /* printf("Valuator %d, class %d, atom = (%d), val = %f\n", n, i, + valuatorclassinfo->label, evd->valuators.values[n]); + */ + if(valuatorclassinfo->label == atom_labels[AbsMTPositionX]) { + /* Convert to screen coordinates. Only works in a one-screen + * setup */ + x = (evd->valuators.values[n] - valuatorclassinfo->min) / (valuatorclassinfo->max - valuatorclassinfo->min)* + WidthOfScreen(DefaultScreenOfDisplay(xevent->xcookie.display)); + winx = x + evd->event_x - evd->root_x; + + } + else if(valuatorclassinfo->label == atom_labels[AbsMTPositionY]) { + y = (evd->valuators.values[n] - valuatorclassinfo->min) / (valuatorclassinfo->max - valuatorclassinfo->min)* + HeightOfScreen(DefaultScreenOfDisplay(xevent->xcookie.display)); + winy = y + evd->event_y - evd->root_y; + } + else if(valuatorclassinfo->label == atom_labels[AbsMTTrackingID]) { + int trackingid = (int)evd->valuators.values[n]; + + if(winx < 0 || winy < 0 ) + continue; + printf("Finger : %d, x = %05.1f, y = %05.1f, rootx = %05.1f, rooty = %05.1f\n", + trackingid, winx, winy, x, y); + + switch (xevent->xcookie.evtype) + { + case XI_Motion: + _ecore_mouse_move + (evd->time, + 0, // state + winx, winy, + x, y, + evd->event, + (evd->child ? evd->child : evd->event), + evd->root, + 1, // same_screen + devid+trackingid, 1, 1, + 1.0, // pressure + 0.0, // angle + winx, winy, + x, y); + break; + + case XI_ButtonPress: + _ecore_mouse_button + (ECORE_EVENT_MOUSE_BUTTON_DOWN, + evd->time, + 0, // state + 0, // button + winx, winy, + x, y, + evd->event, + (evd->child ? evd->child : evd->event), + evd->root, + 1, // same_screen + devid+trackingid, 1, 1, + 1.0, // pressure + 0.0, // angle + winx, winy, + x, y); + break; + + case XI_ButtonRelease: + _ecore_mouse_button + (ECORE_EVENT_MOUSE_BUTTON_UP, + evd->time, + 0, // state + 0, // button + winx, winy, + x, y, + evd->event, + (evd->child ? evd->child : evd->event), + evd->root, + 1, // same_screen + devid+trackingid, 1, 1, + 1.0, // pressure + 0.0, // angle + winx, winy, + x, y); + break; + } /* switch */ + } /* is trackingid*/ + } /* if valuator*/ + } /* for loop on classes */ #endif /* ifdef ECORE_XI2 */ } /* _ecore_x_input_handler */ @@ -142,7 +211,9 @@ ecore_x_input_multi_select(Ecore_X_Window win) { XIDeviceInfo *dev = &(_ecore_x_xi2_devs[i]); - if (dev->use == XIFloatingSlave) + DBG("Now selected on dev %d, deviceid %d, use = %d, float = %d\n", + i, dev->deviceid, dev->use, XIFloatingSlave); + if (dev->use == XIFloatingSlave || dev->use == XISlavePointer) { XIEventMask eventmask; unsigned char mask[1] = { 0 }; -- 1.7.5.3 ------------------------------------------------------------------------------ BlackBerry® DevCon Americas, Oct. 18-20, San Francisco, CA Learn about the latest advances in developing for the BlackBerry® mobile platform with sessions, labs & more. See new tools and technologies. Register for BlackBerry® DevCon today! http://p.sf.net/sfu/rim-devcon-copy1 _______________________________________________ enlightenment-devel mailing list enlightenment-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-devel