Enable default single finger gesture 55/65055/3 submit/tizen/20160418.063128
authorJengHyun Kang <jhyuni.kang@samsung.com>
Thu, 7 Apr 2016 05:29:02 +0000 (14:29 +0900)
committerJengHyun Kang <jhyuni.kang@samsung.com>
Fri, 15 Apr 2016 03:54:29 +0000 (12:54 +0900)
 - Convert single finger gesture to Back Key
 - This will be changed to configuration

Change-Id: I779d50c9fac6293704f88f81d79b6dd47c2b3d34

src/Makefile.am
src/e_mod_gesture_device.c [new file with mode: 0644]
src/e_mod_gesture_events.c
src/e_mod_main.c
src/e_mod_main.h

index 59ac035..563afca 100644 (file)
@@ -7,7 +7,8 @@ pkgdir                 = $(libdir)/enlightenment/modules/$(MODULE)/$(MODULE_ARCH
 pkg_LTLIBRARIES        = module.la
 module_la_SOURCES      = e_mod_main.c \
                          e_mod_main.h \
-                                                e_mod_gesture_events.c
+                         e_mod_gesture_events.c \
+                         e_mod_gesture_device.c
 module_la_CFLAGS       = @ENLIGHTENMENT_CFLAGS@ @WAYLAND_CFLAGS@ -DHAVE_WAYLAND_ONLY
 module_la_LDFLAGS      = -module -avoid-version @WAYLAND_LIBS@ @ENLIGHTENMENT_LIBS@
 
diff --git a/src/e_mod_gesture_device.c b/src/e_mod_gesture_device.c
new file mode 100644 (file)
index 0000000..38aa14b
--- /dev/null
@@ -0,0 +1,164 @@
+#define E_COMP_WL
+#include "e_mod_main.h"
+#include <string.h>
+#include <linux/uinput.h>
+
+static void
+_e_gesture_device_keydev_create(void)
+{
+   int uinp_fd = -1;
+   struct uinput_user_dev uinp;
+   int ret = 0;
+
+   uinp_fd = open("/dev/uinput", O_WRONLY | O_NDELAY);
+   if ( uinp_fd < 0)
+     {
+        GTWRN("Failed to open /dev/uinput: (%d)\n", uinp_fd);
+        return;
+     }
+
+   memset(&uinp, 0, sizeof(struct uinput_user_dev));
+   strncpy(uinp.name, E_GESTURE_KEYBOARD_NAME, UINPUT_MAX_NAME_SIZE);
+   uinp.id.version = 4;
+   uinp.id.bustype = BUS_USB;
+
+   ioctl(uinp_fd, UI_SET_EVBIT, EV_KEY);
+   ioctl(uinp_fd, UI_SET_EVBIT, EV_SYN);
+   ioctl(uinp_fd, UI_SET_EVBIT, EV_MSC);
+
+   ioctl(uinp_fd, UI_SET_KEYBIT, KEY_BACK);
+
+   ret = write(uinp_fd, &uinp, sizeof(struct uinput_user_dev));
+   if (ret < 0)
+     {
+        GTWRN("Failed to write UINPUT device\n");
+        close(uinp_fd);
+        return;
+     }
+   if (ioctl(uinp_fd, UI_DEV_CREATE))
+     {
+        GTWRN("Unable to create UINPUT device\n");
+        close(uinp_fd);
+        return;
+     }
+
+   gesture->device.uinp_fd = uinp_fd;
+}
+
+void
+e_gesture_device_keydev_set(char *option)
+{
+   if (!option)
+     {
+        _e_gesture_device_keydev_create();
+        gesture->device.kbd_name = strdup(E_GESTURE_KEYBOARD_NAME);
+     }
+   else if (strncmp(option, "Any", sizeof("Any")))
+     {
+        gesture->device.kbd_name = strdup(option);
+     }
+}
+
+Ecore_Device *
+_e_gesture_device_ecore_device_get(char *path, unsigned int clas)
+{
+   const Eina_List *dev_list = NULL;
+   const Eina_List *l;
+   Ecore_Device *dev = NULL;
+   const char *identifier;
+
+   if (!path) return NULL;
+
+   dev_list = ecore_device_list();
+   if (!dev_list) return NULL;
+   EINA_LIST_FOREACH(dev_list, l, dev)
+     {
+        if (!dev) continue;
+        GTINF("dev: %s\n", ecore_device_name_get(dev));
+        identifier = ecore_device_identifier_get(dev);
+        if (!identifier) continue;
+        if ((ecore_device_class_get(dev) == clas) && !(strcmp(identifier, path)))
+          return dev;
+     }
+
+   return NULL;
+}
+
+Eina_Bool
+e_gesture_device_add(Ecore_Event_Device_Info *ev)
+{
+   if (ev->clas == ECORE_DEVICE_CLASS_TOUCH)
+     {
+        gesture->device.touch_devices = eina_list_append(gesture->device.touch_devices, ev->identifier);
+        GTINF("%s(%s) device is touch device: add list\n", ev->name, ev->identifier);
+     }
+   if ((!gesture->device.kbd_identifier) &&
+       (ev->clas == ECORE_DEVICE_CLASS_KEYBOARD))
+     {
+        if (gesture->device.kbd_name)
+          {
+             if (!strncmp(ev->name, gesture->device.kbd_name, strlen(gesture->device.kbd_name)))
+               {
+                  GTINF("%s(%s) device is key generated device in gesture\n", ev->name, ev->identifier);
+                  gesture->device.kbd_identifier = strdup(ev->identifier);
+                  gesture->device.kbd_device = _e_gesture_device_ecore_device_get(gesture->device.kbd_identifier, ECORE_DEVICE_CLASS_KEYBOARD);
+               }
+          }
+        else
+          {
+             GTINF("%s(%s) device is key generated device in gesture\n", ev->name, ev->identifier);
+             gesture->device.kbd_name = strdup(ev->name);
+             gesture->device.kbd_identifier = strdup(ev->identifier);
+             gesture->device.kbd_device = _e_gesture_device_ecore_device_get(gesture->device.kbd_identifier, ECORE_DEVICE_CLASS_KEYBOARD);
+          }
+     }
+   return EINA_TRUE;
+}
+
+Eina_Bool
+e_gesture_device_del(Ecore_Event_Device_Info *ev)
+{
+   Eina_List *l, *l_next;
+   char *data;
+
+   if (ev->clas == ECORE_DEVICE_CLASS_TOUCH)
+     {
+        EINA_LIST_FOREACH_SAFE(gesture->device.touch_devices, l, l_next, data)
+          {
+             if (!strncmp(data, ev->identifier, strlen(ev->identifier)))
+               {
+                  GTINF("%s(%s) device is touch device: remove list\n", ev->name, ev->identifier);
+                  gesture->device.touch_devices = eina_list_remove(gesture->device.touch_devices, data);
+                  E_FREE(data);
+               }
+          }
+     }
+   if ((gesture->device.kbd_identifier) &&
+       (ev->clas == ECORE_DEVICE_CLASS_KEYBOARD))
+     {
+        if (!strncmp(ev->name, gesture->device.kbd_name, strlen(gesture->device.kbd_name)))
+          {
+             GTWRN("Gesture keyboard device(%s) is disconnected. Gesture cannot create key events\n", gesture->device.kbd_name);
+             E_FREE(gesture->device.kbd_identifier);
+             E_FREE(gesture->device.kbd_name);
+          }
+     }
+   return EINA_TRUE;
+}
+
+Eina_Bool
+e_gesture_is_touch_device(const Ecore_Device *dev)
+{
+   if (ecore_device_class_get(dev) == ECORE_DEVICE_CLASS_TOUCH)
+     return EINA_TRUE;
+
+   return EINA_FALSE;
+}
+
+void
+e_gesture_device_shutdown(void)
+{
+   E_FREE(gesture->device.kbd_identifier);
+   E_FREE(gesture->device.kbd_name);
+   gesture->device.touch_devices = eina_list_free(gesture->device.touch_devices);
+}
index 72231e5..5492964 100644 (file)
@@ -24,26 +24,44 @@ _e_gesture_swipe_cancel(void)
    gesture->gesture_filter |= TIZEN_GESTURE_TYPE_SWIPE;
 }
 
-static Eina_Bool
-_e_gesture_is_touch_device(Ecore_Device *dev)
+static void
+_e_gesture_keyevent_free(void *data EINA_UNUSED, void *ev)
 {
-   Eina_List *l;
-   char *data;
-   const char *identifier;
+   Ecore_Event_Key *e = ev;
 
-   EINA_SAFETY_ON_NULL_RETURN_VAL(dev, EINA_FALSE);
+   eina_stringshare_del(e->keyname);
+   eina_stringshare_del(e->key);
+   eina_stringshare_del(e->compose);
 
-   identifier = ecore_device_identifier_get(dev);
-   if (!identifier) return EINA_FALSE;
+   E_FREE(e);
+}
 
-   EINA_LIST_FOREACH(gesture->touch_devices, l, data)
-     {
-        if (!strncmp(data, identifier, strlen(identifier)))
-          {
-             return EINA_TRUE;
-          }
-     }
-   return EINA_FALSE;
+/* Optional: This function is currently used to generate back key.
+ *           But how about change this function to generate every key?
+ *           _e_gesture_send_key(char *keyname, Eina_Bool pressed)
+ */
+static void
+_e_gesture_send_back_key(Eina_Bool pressed)
+{
+   Ecore_Event_Key *ev;
+
+   EINA_SAFETY_ON_NULL_RETURN(e_comp_wl->xkb.keymap);
+
+   ev = E_NEW(Ecore_Event_Key, 1);
+   EINA_SAFETY_ON_NULL_RETURN(ev);
+
+   ev->key = (char *)eina_stringshare_add("XF86Back");
+   ev->keyname = (char *)eina_stringshare_add(ev->key);
+   ev->compose = (char *)eina_stringshare_add(ev->key);
+   ev->timestamp = (int)(ecore_time_get()*1000);
+   ev->same_screen = 1;
+   ev->keycode = E_GESTURE_SWIPE_BACK_KEY;
+   ev->dev = gesture->device.kbd_device;
+
+   if (pressed)
+     ecore_event_add(ECORE_EVENT_KEY_DOWN, ev, _e_gesture_keyevent_free, NULL);
+   else
+     ecore_event_add(ECORE_EVENT_KEY_UP, ev, _e_gesture_keyevent_free, NULL);
 }
 
 static void
@@ -51,6 +69,7 @@ _e_gesture_send_swipe(int fingers, int x, int y, int direction, struct wl_client
 {
    enum tizen_gesture_direction dir = 0;
    Ecore_Event_Mouse_Button *ev_cancel;
+
    switch (direction)
      {
         case E_GESTURE_DIRECTION_DOWN:
@@ -76,46 +95,33 @@ _e_gesture_send_swipe(int fingers, int x, int y, int direction, struct wl_client
    ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_CANCEL, ev_cancel, NULL, NULL);
 
    GTINF("Send swipe gesture (direction: %d) to client: %p\n", dir, client);
+
+   if (E_GESTURE_SWIPE_BACK_DEFAULT_ENABLE &&
+       direction == E_GESTURE_DIRECTION_DOWN)
+     {
+        _e_gesture_send_back_key(EINA_TRUE);
+        _e_gesture_send_back_key(EINA_FALSE);
+        goto finish;
+     }
    
    tizen_gesture_send_swipe(res, fingers, TIZEN_GESTURE_MODE_DONE, x, y, dir);
    _e_gesture_swipe_cancel();
 
+finish:
+   _e_gesture_swipe_cancel();
    gesture->gesture_events.recognized_gesture |= TIZEN_GESTURE_TYPE_SWIPE;
 }
 
 static Eina_Bool
 _e_gesture_process_device_add(void *event)
 {
-   Ecore_Event_Device_Info *ev = event;
-
-   if (ev->clas == ECORE_DEVICE_CLASS_TOUCH)
-     {
-        gesture->touch_devices = eina_list_append(gesture->touch_devices, ev->identifier);
-        GTINF("%s(%s) device is touch device: add list\n", ev->name, ev->identifier);
-     }
-   return EINA_TRUE;
+   return e_gesture_device_add(event);
 }
 
 static Eina_Bool
 _e_gesture_process_device_del(void *event)
 {
-   Ecore_Event_Device_Info *ev = event;
-   Eina_List *l, *l_next;
-   char *data;
-
-   if (ev->clas == ECORE_DEVICE_CLASS_TOUCH)
-     {
-        EINA_LIST_FOREACH_SAFE(gesture->touch_devices, l, l_next, data)
-          {
-             if (!strncmp(data, ev->identifier, strlen(ev->identifier)))
-               {
-                  GTINF("%s(%s) device is touch device: remove list\n", ev->name, ev->identifier);
-                  gesture->touch_devices = eina_list_remove(gesture->touch_devices, data);
-                  E_FREE(data);
-               }
-          }
-     }
-   return EINA_TRUE;
+   return e_gesture_device_del(event);
 }
 
 static Eina_Bool
@@ -284,7 +290,7 @@ _e_gesture_process_mouse_button_down(void *event)
      {
         return EINA_TRUE;
      }
-   if (_e_gesture_is_touch_device(ev->dev) == EINA_FALSE)
+   if (e_gesture_is_touch_device(ev->dev) == EINA_FALSE)
      {
         return EINA_TRUE;
      }
@@ -327,7 +333,7 @@ _e_gesture_process_mouse_button_up(void *event)
      {
         return EINA_TRUE;
      }
-   if (_e_gesture_is_touch_device(ev->dev) == EINA_FALSE)
+   if (e_gesture_is_touch_device(ev->dev) == EINA_FALSE)
      {
         return EINA_TRUE;
      }
@@ -355,7 +361,7 @@ _e_gesture_process_mouse_move(void *event)
      {
         return EINA_TRUE;
      }
-   if (_e_gesture_is_touch_device(ev->dev) == EINA_FALSE)
+   if (e_gesture_is_touch_device(ev->dev) == EINA_FALSE)
      {
         return EINA_TRUE;
      }
index 949c45e..529a02f 100644 (file)
@@ -352,6 +352,16 @@ _e_gesture_init(E_Module *m)
 
    gesture->gesture_filter = E_GESTURE_TYPE_MAX;
 
+   if (E_GESTURE_SWIPE_BACK_DEFAULT_ENABLE)
+     {
+        gesture->grabbed_gesture |= TIZEN_GESTURE_TYPE_SWIPE;
+        gesture->gesture_events.swipes.fingers[1].enabled = EINA_TRUE;
+        gesture->gesture_events.swipes.fingers[1].direction[E_GESTURE_DIRECTION_DOWN].client = (void *)0x1;
+        gesture->gesture_events.swipes.fingers[1].direction[E_GESTURE_DIRECTION_DOWN].res = (void *)0x1;
+     }
+
+   e_gesture_device_keydev_set(E_GESTURE_KEYBOARD_DEVICE);
+
    return m;
 
 err:
@@ -370,6 +380,7 @@ e_modapi_init(E_Module *m)
 E_API int
 e_modapi_shutdown(E_Module *m)
 {
+   e_gesture_device_shutdown();
    return 1;
 }
 
index fddbf43..6fca7ef 100644 (file)
@@ -1,8 +1,8 @@
 #ifndef E_MOD_MAIN_H
 #define E_MOD_MAIN_H
 
-#include <tizen-extension-server-protocol.h>
 #include <e.h>
+#include <tizen-extension-server-protocol.h>
 #include <Ecore_Drm.h>
 
 #define GTERR(msg, ARG...) ERR("[tizen_gesture][%s:%d] "msg, __FUNCTION__, __LINE__, ##ARG)
 #define E_GESTURE_FINGER_MAX 3
 #define E_GESTURE_TYPE_MAX TIZEN_GESTURE_TYPE_SWIPE+1
 #define E_GESTURE_TYPE_ALL TIZEN_GESTURE_TYPE_SWIPE
+#define E_GESTURE_KEYBOARD_NAME "Gesture Keyboard"
 
 /* FIX ME: Set values in contiguration file, do not use definition */
+#define E_GESTURE_KEYBOARD_DEVICE "Any"
+
 #define E_GESTURE_SWIPE_DONE_TIME 0.5
 #define E_GESTURE_SWIPE_START_TIME 0.01
 #define E_GESTURE_SWIPE_START_AREA 50
 #define E_GESTURE_SWIPE_DIFF_FAIL 100
 #define E_GESTURE_SWIPE_DIFF_SUCCESS 300
+/* FIX ME: Key code will be get from keymap */
 #define E_GESTURE_SWIPE_COMBINE_KEY 124
+#define E_GESTURE_SWIPE_BACK_KEY 166
+#define E_GESTURE_SWIPE_BACK_DEFAULT_ENABLE EINA_TRUE
 
 #define ABS(x) ((x)>0)?(x):-(x)
 
@@ -82,6 +88,7 @@ struct _E_Gesture_Event_Swipe
    E_Gesture_Direction direction;
 
    unsigned int combined_keycode;
+   unsigned int back_keycode;
 
    unsigned int enabled_finger;
    Ecore_Timer *start_timer;
@@ -104,7 +111,14 @@ struct _E_Gesture
    Eina_List *handlers;
    Eina_List *grab_client_list;
 
-   Eina_List *touch_devices;
+   struct
+   {
+      Eina_List *touch_devices;
+      int uinp_fd;
+      char *kbd_identifier;
+      char *kbd_name;
+      Ecore_Device *kbd_device;
+   }device;
 
    unsigned int grabbed_gesture;
    E_Gesture_Event gesture_events;
@@ -121,4 +135,12 @@ E_API int   e_modapi_save(E_Module *m);
 
 Eina_Bool e_gesture_process_events(void *event, int type);
 int e_gesture_type_convert(uint32_t type);
+
+/* Device control */
+void e_gesture_device_shutdown(void);
+Eina_Bool e_gesture_device_add(Ecore_Event_Device_Info *ev);
+Eina_Bool e_gesture_device_del(Ecore_Event_Device_Info *ev);
+Eina_Bool e_gesture_is_touch_device(const Ecore_Device *dev);
+void e_gesture_device_keydev_set(char *option);
+
 #endif