[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&reg; DevCon Americas, Oct. 18-20, San Francisco, CA
Learn about the latest advances in developing for the 
BlackBerry&reg; mobile platform with sessions, labs & more.
See new tools and technologies. Register for BlackBerry&reg; 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

Reply via email to