devilhorns pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=2017c8be95c06a905a363838922176931cd2a34f

commit 2017c8be95c06a905a363838922176931cd2a34f
Author: Lukasz Stanislawski <l.stanisl...@samsung.com>
Date:   Thu Jun 4 13:06:27 2015 -0400

    ecore-x: add new grab touch devices functionality.
    
    Summary:
    EFL currently supports pointer grabbing. This patch introduces new API
    allowing to grab all slave touch devices registered in X server
    Grabbing is performed by XIGrabDevice function from XInput 2.0.
    
    By default ecore_x_input_touch_devices_grab grabs all XISlavePointer 
devices,
    having XITouchInfoClass. Function returns EINA_TRUE if at least one touch 
device
    was successfully grabbed. ecore_x_input_touch_devices_ungrab ungrabs all
    previously grabbed devices.
    
    To process events correctly change has been done in x_input_handler to 
emulate
    mouse pointer events. If XITouchEmulatingPointer flag is set on touch 
events and
    device is grabbed framework will generate mouse events. This is required
    due to X Server design in which mouse events are no longer send to client 
when device is
    detached (grabbed) from virtual core pointer.
    
    @feature
    
    Reviewers: cedric, raster, devilhorns
    
    Subscribers: seoz, cedric
    
    Differential Revision: https://phab.enlightenment.org/D2568
---
 src/lib/ecore_x/Ecore_X.h             |   2 +
 src/lib/ecore_x/xcb/ecore_xcb_input.c |  14 ++++
 src/lib/ecore_x/xlib/ecore_x_xi2.c    | 117 +++++++++++++++++++++++++++++++++-
 3 files changed, 132 insertions(+), 1 deletion(-)

diff --git a/src/lib/ecore_x/Ecore_X.h b/src/lib/ecore_x/Ecore_X.h
index 86a33c9..8c3a41f 100644
--- a/src/lib/ecore_x/Ecore_X.h
+++ b/src/lib/ecore_x/Ecore_X.h
@@ -2533,6 +2533,8 @@ EAPI Eina_Bool      ecore_x_image_to_argb_convert(void 
*src, int sbpp, int sbpl,
 
 EAPI Eina_Bool      ecore_x_input_multi_select(Ecore_X_Window win); /**< 
@since 1.13 */
 EAPI Eina_Bool     ecore_x_input_raw_select(Ecore_X_Window win); /**< @since 
1.8 */
+EAPI Eina_Bool      ecore_x_input_touch_devices_grab(Ecore_X_Window win); /**< 
@since 1.15 */
+EAPI Eina_Bool      ecore_x_input_touch_devices_ungrab(void); /**< @since 1.15 
*/
 
 EAPI Eina_Bool      ecore_x_vsync_animator_tick_source_set(Ecore_X_Window win);
 
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_input.c 
b/src/lib/ecore_x/xcb/ecore_xcb_input.c
index e94cc80..cd9e488 100644
--- a/src/lib/ecore_x/xcb/ecore_xcb_input.c
+++ b/src/lib/ecore_x/xcb/ecore_xcb_input.c
@@ -279,3 +279,17 @@ ecore_x_input_raw_select(Ecore_X_Window win EINA_UNUSED)
    /* NB: FIXME: This is just a placeholder. XCB does not have XInput2 yet */
    return EINA_FALSE;
 }
+
+EAPI Eina_Bool
+ecore_x_input_touch_devices_grab(Ecore_X_Window win EINA_UNUSED)
+{
+   /* NB: FIXME: This is just a placeholder. XCB does not have XInput2 yet */
+   return EINA_FALSE;
+}
+
+EAPI Eina_Bool
+ecore_x_input_touch_devices_ungrab(void)
+{
+   /* NB: FIXME: This is just a placeholder. XCB does not have XInput2 yet */
+   return EINA_FALSE;
+}
diff --git a/src/lib/ecore_x/xlib/ecore_x_xi2.c 
b/src/lib/ecore_x/xlib/ecore_x_xi2.c
index 832b424..d18bbab 100644
--- a/src/lib/ecore_x/xlib/ecore_x_xi2.c
+++ b/src/lib/ecore_x/xlib/ecore_x_xi2.c
@@ -41,6 +41,7 @@ static int _ecore_x_xi2_num = 0;
 #ifdef ECORE_XI2_2
 static Eina_Inlist *_ecore_x_xi2_touch_info_list = NULL;
 #endif /* ifdef ECORE_XI2_2 */
+static Eina_List *_ecore_x_xi2_grabbed_devices_list;
 #endif /* ifdef ECORE_XI2 */
 
 void
@@ -140,6 +141,10 @@ _ecore_x_input_shutdown(void)
 
    _ecore_x_xi2_num = 0;
    _ecore_x_xi2_opcode = -1;
+
+   if (_ecore_x_xi2_grabbed_devices_list)
+     eina_list_free(_ecore_x_xi2_grabbed_devices_list);
+   _ecore_x_xi2_grabbed_devices_list = NULL;
 #endif /* ifdef ECORE_XI2 */
 }
 
@@ -271,6 +276,23 @@ _ecore_x_input_raw_handler(XEvent *xevent)
 #endif /* ifdef ECORE_XI2 */
 }
 
+static Eina_Bool
+_ecore_x_input_grabbed_is(int deviceId)
+{
+#ifdef ECORE_XI2
+   void *id;
+   Eina_List *l;
+
+   EINA_LIST_FOREACH(_ecore_x_xi2_grabbed_devices_list, l, id)
+     {
+        if (deviceId == (intptr_t)id)
+          return EINA_TRUE;
+     }
+#endif /* ifdef ECORE_XI2 */
+
+   return EINA_FALSE;
+}
+
 void
 _ecore_x_input_mouse_handler(XEvent *xevent)
 {
@@ -282,6 +304,9 @@ _ecore_x_input_mouse_handler(XEvent *xevent)
 
    switch (xevent->xcookie.evtype)
      {
+      case XI_TouchUpdate:
+         if (!_ecore_x_input_grabbed_is(devid))
+           break;
       case XI_Motion:
         INF("Handling XI_Motion");
         _ecore_mouse_move
@@ -300,6 +325,9 @@ _ecore_x_input_mouse_handler(XEvent *xevent)
           evd->root_x, evd->root_y);
         break;
 
+      case XI_TouchBegin:
+         if (!_ecore_x_input_grabbed_is(devid))
+           break;
       case XI_ButtonPress:
         INF("ButtonEvent:multi press time=%u x=%d y=%d devid=%d", (unsigned 
int)evd->time, (int)evd->event_x, (int)evd->event_y, devid);
         _ecore_mouse_button
@@ -320,6 +348,9 @@ _ecore_x_input_mouse_handler(XEvent *xevent)
           evd->root_x, evd->root_y);
         break;
 
+      case XI_TouchEnd:
+         if (!_ecore_x_input_grabbed_is(devid))
+           break;
       case XI_ButtonRelease:
         INF("ButtonEvent:multi release time=%u x=%d y=%d devid=%d", (unsigned 
int)evd->time, (int)evd->event_x, (int)evd->event_y, devid);
         _ecore_mouse_button
@@ -623,7 +654,12 @@ _ecore_x_input_handler(XEvent *xevent)
 
              if ((dev->use == XISlavePointer) &&
                  !(evd->flags & XIPointerEmulated))
-               _ecore_x_input_multi_handler(xevent);
+               {
+                  if (evd->flags & XITouchEmulatingPointer)
+                    _ecore_x_input_mouse_handler(xevent);
+                  else
+                    _ecore_x_input_multi_handler(xevent);
+               }
              else if (dev->use == XIFloatingSlave)
                _ecore_x_input_mouse_handler(xevent);
 
@@ -738,3 +774,82 @@ ecore_x_input_raw_select(Ecore_X_Window win)
 #endif
 }
 
+EAPI Eina_Bool
+_ecore_x_input_touch_devices_grab(Ecore_X_Window grab_win, Eina_Bool grab)
+{
+#ifdef ECORE_XI2
+   int i;
+
+   if (!_ecore_x_xi2_devs)
+     return EINA_FALSE;
+
+   Eina_Bool status = EINA_FALSE;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+   for (i = 0; i < _ecore_x_xi2_num; i++)
+     {
+        XIDeviceInfo *dev = &(_ecore_x_xi2_devs[i]);
+        int update = 0;
+        XIEventMask eventmask;
+        unsigned char mask[4] = { 0 };
+
+        eventmask.deviceid = XISlavePointer;
+        eventmask.mask_len = sizeof(mask);
+        eventmask.mask = mask;
+
+        if (dev->use == XISlavePointer)
+          {
+#ifdef ECORE_XI2_2
+             Eina_Inlist *l = _ecore_x_xi2_touch_info_list;
+             Ecore_X_Touch_Device_Info *info;
+             info = _ecore_x_input_touch_info_get(dev);
+
+             if (info)
+               {
+                  XISetMask(mask, XI_TouchUpdate);
+                  XISetMask(mask, XI_TouchBegin);
+                  XISetMask(mask, XI_TouchEnd);
+                  update = 1;
+                  free(info);
+               }
+#endif /* #ifdef ECORE_XI2_2 */
+
+#if !defined (ECORE_XI2_2) && defined (XI_TouchUpdate) && defined 
(XI_TouchBegin) && defined (XI_TouchEnd)
+             XISetMask(mask, XI_TouchUpdate);
+             XISetMask(mask, XI_TouchBegin);
+             XISetMask(mask, XI_TouchEnd);
+             update = 1;
+#endif
+          }
+
+        if (update)
+          {
+             if (grab) {
+                status |= (XIGrabDevice(_ecore_x_disp, dev->deviceid, 
grab_win, CurrentTime,
+                           None, GrabModeAsync, GrabModeAsync, False, 
&eventmask) == GrabSuccess);
+                _ecore_x_xi2_grabbed_devices_list = 
eina_list_append(_ecore_x_xi2_grabbed_devices_list, 
(void*)(intptr_t)dev->deviceid);
+             }
+             else {
+                status |= (XIUngrabDevice(_ecore_x_disp, dev->deviceid, 
CurrentTime) == Success);
+                _ecore_x_xi2_grabbed_devices_list = 
eina_list_remove(_ecore_x_xi2_grabbed_devices_list, 
(void*)(intptr_t)dev->deviceid);
+             }
+             if (_ecore_xlib_sync) ecore_x_sync();
+          }
+     }
+
+   return status;
+#endif
+   return EINA_FALSE;
+}
+
+EAPI Eina_Bool
+ecore_x_input_touch_devices_grab(Ecore_X_Window grab_win)
+{
+   return _ecore_x_input_touch_devices_grab(grab_win, EINA_TRUE);
+}
+
+EAPI Eina_Bool
+ecore_x_input_touch_devices_ungrab(void)
+{
+   return _ecore_x_input_touch_devices_grab(0, EINA_FALSE);
+}

-- 


Reply via email to