summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukasz Stanislawski <l.stanislaws@samsung.com>2015-06-04 13:06:27 -0400
committerChris Michael <cp.michael@samsung.com>2015-06-04 13:06:27 -0400
commit2017c8be95c06a905a363838922176931cd2a34f (patch)
tree7832b641ca729a95fdc6f117da106c6461f72e66
parentaf2bcfa9d1f46fc7ef99b0f5f4dc9851dcf52612 (diff)
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
-rw-r--r--src/lib/ecore_x/Ecore_X.h2
-rw-r--r--src/lib/ecore_x/xcb/ecore_xcb_input.c14
-rw-r--r--src/lib/ecore_x/xlib/ecore_x_xi2.c117
3 files changed, 132 insertions, 1 deletions
diff --git a/src/lib/ecore_x/Ecore_X.h b/src/lib/ecore_x/Ecore_X.h
index 86a33c9448..8c3a41f4dc 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,
2533 2533
2534EAPI Eina_Bool ecore_x_input_multi_select(Ecore_X_Window win); /**< @since 1.13 */ 2534EAPI Eina_Bool ecore_x_input_multi_select(Ecore_X_Window win); /**< @since 1.13 */
2535EAPI Eina_Bool ecore_x_input_raw_select(Ecore_X_Window win); /**< @since 1.8 */ 2535EAPI Eina_Bool ecore_x_input_raw_select(Ecore_X_Window win); /**< @since 1.8 */
2536EAPI Eina_Bool ecore_x_input_touch_devices_grab(Ecore_X_Window win); /**< @since 1.15 */
2537EAPI Eina_Bool ecore_x_input_touch_devices_ungrab(void); /**< @since 1.15 */
2536 2538
2537EAPI Eina_Bool ecore_x_vsync_animator_tick_source_set(Ecore_X_Window win); 2539EAPI Eina_Bool ecore_x_vsync_animator_tick_source_set(Ecore_X_Window win);
2538 2540
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_input.c b/src/lib/ecore_x/xcb/ecore_xcb_input.c
index e94cc80263..cd9e488986 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)
279 /* NB: FIXME: This is just a placeholder. XCB does not have XInput2 yet */ 279 /* NB: FIXME: This is just a placeholder. XCB does not have XInput2 yet */
280 return EINA_FALSE; 280 return EINA_FALSE;
281} 281}
282
283EAPI Eina_Bool
284ecore_x_input_touch_devices_grab(Ecore_X_Window win EINA_UNUSED)
285{
286 /* NB: FIXME: This is just a placeholder. XCB does not have XInput2 yet */
287 return EINA_FALSE;
288}
289
290EAPI Eina_Bool
291ecore_x_input_touch_devices_ungrab(void)
292{
293 /* NB: FIXME: This is just a placeholder. XCB does not have XInput2 yet */
294 return EINA_FALSE;
295}
diff --git a/src/lib/ecore_x/xlib/ecore_x_xi2.c b/src/lib/ecore_x/xlib/ecore_x_xi2.c
index 832b424f28..d18bbabe78 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;
41#ifdef ECORE_XI2_2 41#ifdef ECORE_XI2_2
42static Eina_Inlist *_ecore_x_xi2_touch_info_list = NULL; 42static Eina_Inlist *_ecore_x_xi2_touch_info_list = NULL;
43#endif /* ifdef ECORE_XI2_2 */ 43#endif /* ifdef ECORE_XI2_2 */
44static Eina_List *_ecore_x_xi2_grabbed_devices_list;
44#endif /* ifdef ECORE_XI2 */ 45#endif /* ifdef ECORE_XI2 */
45 46
46void 47void
@@ -140,6 +141,10 @@ _ecore_x_input_shutdown(void)
140 141
141 _ecore_x_xi2_num = 0; 142 _ecore_x_xi2_num = 0;
142 _ecore_x_xi2_opcode = -1; 143 _ecore_x_xi2_opcode = -1;
144
145 if (_ecore_x_xi2_grabbed_devices_list)
146 eina_list_free(_ecore_x_xi2_grabbed_devices_list);
147 _ecore_x_xi2_grabbed_devices_list = NULL;
143#endif /* ifdef ECORE_XI2 */ 148#endif /* ifdef ECORE_XI2 */
144} 149}
145 150
@@ -271,6 +276,23 @@ _ecore_x_input_raw_handler(XEvent *xevent)
271#endif /* ifdef ECORE_XI2 */ 276#endif /* ifdef ECORE_XI2 */
272} 277}
273 278
279static Eina_Bool
280_ecore_x_input_grabbed_is(int deviceId)
281{
282#ifdef ECORE_XI2
283 void *id;
284 Eina_List *l;
285
286 EINA_LIST_FOREACH(_ecore_x_xi2_grabbed_devices_list, l, id)
287 {
288 if (deviceId == (intptr_t)id)
289 return EINA_TRUE;
290 }
291#endif /* ifdef ECORE_XI2 */
292
293 return EINA_FALSE;
294}
295
274void 296void
275_ecore_x_input_mouse_handler(XEvent *xevent) 297_ecore_x_input_mouse_handler(XEvent *xevent)
276{ 298{
@@ -282,6 +304,9 @@ _ecore_x_input_mouse_handler(XEvent *xevent)
282 304
283 switch (xevent->xcookie.evtype) 305 switch (xevent->xcookie.evtype)
284 { 306 {
307 case XI_TouchUpdate:
308 if (!_ecore_x_input_grabbed_is(devid))
309 break;
285 case XI_Motion: 310 case XI_Motion:
286 INF("Handling XI_Motion"); 311 INF("Handling XI_Motion");
287 _ecore_mouse_move 312 _ecore_mouse_move
@@ -300,6 +325,9 @@ _ecore_x_input_mouse_handler(XEvent *xevent)
300 evd->root_x, evd->root_y); 325 evd->root_x, evd->root_y);
301 break; 326 break;
302 327
328 case XI_TouchBegin:
329 if (!_ecore_x_input_grabbed_is(devid))
330 break;
303 case XI_ButtonPress: 331 case XI_ButtonPress:
304 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); 332 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);
305 _ecore_mouse_button 333 _ecore_mouse_button
@@ -320,6 +348,9 @@ _ecore_x_input_mouse_handler(XEvent *xevent)
320 evd->root_x, evd->root_y); 348 evd->root_x, evd->root_y);
321 break; 349 break;
322 350
351 case XI_TouchEnd:
352 if (!_ecore_x_input_grabbed_is(devid))
353 break;
323 case XI_ButtonRelease: 354 case XI_ButtonRelease:
324 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); 355 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);
325 _ecore_mouse_button 356 _ecore_mouse_button
@@ -623,7 +654,12 @@ _ecore_x_input_handler(XEvent *xevent)
623 654
624 if ((dev->use == XISlavePointer) && 655 if ((dev->use == XISlavePointer) &&
625 !(evd->flags & XIPointerEmulated)) 656 !(evd->flags & XIPointerEmulated))
626 _ecore_x_input_multi_handler(xevent); 657 {
658 if (evd->flags & XITouchEmulatingPointer)
659 _ecore_x_input_mouse_handler(xevent);
660 else
661 _ecore_x_input_multi_handler(xevent);
662 }
627 else if (dev->use == XIFloatingSlave) 663 else if (dev->use == XIFloatingSlave)
628 _ecore_x_input_mouse_handler(xevent); 664 _ecore_x_input_mouse_handler(xevent);
629 665
@@ -738,3 +774,82 @@ ecore_x_input_raw_select(Ecore_X_Window win)
738#endif 774#endif
739} 775}
740 776
777EAPI Eina_Bool
778_ecore_x_input_touch_devices_grab(Ecore_X_Window grab_win, Eina_Bool grab)
779{
780#ifdef ECORE_XI2
781 int i;
782
783 if (!_ecore_x_xi2_devs)
784 return EINA_FALSE;
785
786 Eina_Bool status = EINA_FALSE;
787
788 LOGFN(__FILE__, __LINE__, __FUNCTION__);
789 for (i = 0; i < _ecore_x_xi2_num; i++)
790 {
791 XIDeviceInfo *dev = &(_ecore_x_xi2_devs[i]);
792 int update = 0;
793 XIEventMask eventmask;
794 unsigned char mask[4] = { 0 };
795
796 eventmask.deviceid = XISlavePointer;
797 eventmask.mask_len = sizeof(mask);
798 eventmask.mask = mask;
799
800 if (dev->use == XISlavePointer)
801 {
802#ifdef ECORE_XI2_2
803 Eina_Inlist *l = _ecore_x_xi2_touch_info_list;
804 Ecore_X_Touch_Device_Info *info;
805 info = _ecore_x_input_touch_info_get(dev);
806
807 if (info)
808 {
809 XISetMask(mask, XI_TouchUpdate);
810 XISetMask(mask, XI_TouchBegin);
811 XISetMask(mask, XI_TouchEnd);
812 update = 1;
813 free(info);
814 }
815#endif /* #ifdef ECORE_XI2_2 */
816
817#if !defined (ECORE_XI2_2) && defined (XI_TouchUpdate) && defined (XI_TouchBegin) && defined (XI_TouchEnd)
818 XISetMask(mask, XI_TouchUpdate);
819 XISetMask(mask, XI_TouchBegin);
820 XISetMask(mask, XI_TouchEnd);
821 update = 1;
822#endif
823 }
824
825 if (update)
826 {
827 if (grab) {
828 status |= (XIGrabDevice(_ecore_x_disp, dev->deviceid, grab_win, CurrentTime,
829 None, GrabModeAsync, GrabModeAsync, False, &eventmask) == GrabSuccess);
830 _ecore_x_xi2_grabbed_devices_list = eina_list_append(_ecore_x_xi2_grabbed_devices_list, (void*)(intptr_t)dev->deviceid);
831 }
832 else {
833 status |= (XIUngrabDevice(_ecore_x_disp, dev->deviceid, CurrentTime) == Success);
834 _ecore_x_xi2_grabbed_devices_list = eina_list_remove(_ecore_x_xi2_grabbed_devices_list, (void*)(intptr_t)dev->deviceid);
835 }
836 if (_ecore_xlib_sync) ecore_x_sync();
837 }
838 }
839
840 return status;
841#endif
842 return EINA_FALSE;
843}
844
845EAPI Eina_Bool
846ecore_x_input_touch_devices_grab(Ecore_X_Window grab_win)
847{
848 return _ecore_x_input_touch_devices_grab(grab_win, EINA_TRUE);
849}
850
851EAPI Eina_Bool
852ecore_x_input_touch_devices_ungrab(void)
853{
854 return _ecore_x_input_touch_devices_grab(0, EINA_FALSE);
855}