e_input: modify to enable libinput path backend threading and udev/path backend combi... 78/164878/5
authorSung-Jin Park <sj76.park@samsung.com>
Thu, 21 Dec 2017 10:03:03 +0000 (19:03 +0900)
committerSung-Jin Park <sj76.park@samsung.com>
Tue, 26 Dec 2017 05:18:21 +0000 (05:18 +0000)
Change-Id: I79a20aeebbe363f403661dd7cb41ba00c3f544c4
Signed-off-by: Sung-Jin Park <sj76.park@samsung.com>
src/bin/e_comp_wl_input.c
src/bin/e_comp_wl_input.h
src/bin/e_input.c
src/bin/e_input.h
src/bin/e_input_device.c
src/bin/e_input_private.h

index 0d9bed5..017a385 100644 (file)
@@ -975,6 +975,29 @@ e_comp_wl_input_touch_enabled_set(Eina_Bool enabled)
    _e_comp_wl_input_update_seat_caps(NULL);
 }
 
+E_API void
+e_comp_wl_input_seat_caps_set(unsigned int caps)
+{
+   Eina_Bool need_update = EINA_FALSE;
+
+   /* check for valid compositor data */
+   if (!e_comp->wl_comp_data)
+     {
+        ERR("No compositor data");
+        return;
+     }
+
+   if (caps & E_INPUT_SEAT_POINTER)
+     e_comp_wl->ptr.enabled = need_update = EINA_TRUE;
+   if (caps & E_INPUT_SEAT_KEYBOARD)
+     e_comp_wl->kbd.enabled = need_update = EINA_TRUE;
+   if (caps & E_INPUT_SEAT_TOUCH)
+     e_comp_wl->touch.enabled = need_update = EINA_TRUE;
+
+   if (need_update)
+     _e_comp_wl_input_update_seat_caps(NULL);
+}
+
 EINTERN Eina_Bool
 e_comp_wl_input_touch_check(struct wl_resource *res)
 {
index f7658f0..55c00bc 100644 (file)
@@ -26,6 +26,7 @@ EINTERN void e_comp_wl_input_keyboard_enter_send(E_Client *client);
 E_API void e_comp_wl_input_pointer_enabled_set(Eina_Bool enabled);
 E_API void e_comp_wl_input_keyboard_enabled_set(Eina_Bool enabled);
 E_API void e_comp_wl_input_touch_enabled_set(Eina_Bool enabled);
+E_API void e_comp_wl_input_seat_caps_set(unsigned int caps);
 
 E_API Eina_Bool e_comp_wl_input_keymap_cache_file_use_get(void);
 E_API Eina_Stringshare *e_comp_wl_input_keymap_path_get(struct xkb_rule_names names);
index 93288ec..3a4cdfe 100644 (file)
@@ -1,5 +1,6 @@
 #include "e.h"
 #include "e_input_private.h"
+#include "e_comp_wl_input.h"
 #include <Ecore_Input_Evas.h>
 
 int _e_input_init_count;
@@ -19,22 +20,29 @@ e_input_base_dir_get(void)
    return e_input->input_base_dir;
 }
 
+EINTERN Eina_Bool
+e_input_thread_enabled_get(void)
+{
+   return e_input->use_thread;
+}
+
 EINTERN int
 e_input_init(Ecore_Evas *ee)
 {
    char *env = NULL;
+   unsigned int seat_caps = 0;
+
    E_Input_Device *dev;
-   E_Input_Libinput_Backend backend = E_INPUT_LIBINPUT_BACKEND_UDEV;
+
+   Eina_Bool use_udev_backend = EINA_FALSE;
+   Eina_Bool use_path_backend = EINA_FALSE;
+   Eina_Bool skip_udev_enumeration = EINA_FALSE;
 
    TRACE_INPUT_BEGIN(e_input_init);
 
    if (++_e_input_init_count != 1) return _e_input_init_count;
-
-   if (!eina_init()) goto eina_err;
-   if (!ecore_init()) goto ecore_err;
-   if (!ecore_event_init()) goto ecore_event_err;
-   if (!eeze_init()) goto eeze_err;
    if (!ecore_event_evas_init()) goto ecore_event_evas_err;
+   if (!eeze_init()) goto eeze_err;
 
    _e_input_log_dom = eina_log_domain_register("e_input", EINA_COLOR_GREEN);
    if (!_e_input_log_dom)
@@ -66,6 +74,7 @@ e_input_init(Ecore_Evas *ee)
 
    // TODO : make this variable configurable e.g. e.cfg
    e_input->input_base_dir = eina_stringshare_add("/dev/input");
+   e_input->use_thread = EINA_FALSE;
 
    dev = e_input_device_open();
 
@@ -78,23 +87,63 @@ e_input_init(Ecore_Evas *ee)
    e_input->window = ecore_evas_window_get(ee);
    e_input_device_window_set(dev, e_input->window);
 
-   TRACE_INPUT_BEGIN(e_input_device_input_backend_create);
+   env = e_util_env_get("E_INPUT_USE_THREAD_INIT");
+
+   if (env)
+     {
+        e_input->use_thread = EINA_TRUE;
+        E_FREE(env);
+     }
+
+   env = e_util_env_get("LIBINPUT_UDEV_SKIP_INITIAL_ENUMERATION");
+   if (env)
+     {
+        skip_udev_enumeration = EINA_TRUE;
+        E_FREE(env);
+     }
+
+   env = e_util_env_get("E_INPUT_USE_LIBINPUT_UDEV_BACKEND");
+   if (env)
+     {
+        use_udev_backend = EINA_TRUE;
+        E_FREE(env);
+     }
 
    env = e_util_env_get("E_INPUT_USE_LIBINPUT_PATH_BACKEND");
    if (env)
      {
-        backend = E_INPUT_LIBINPUT_BACKEND_PATH;
+        use_path_backend = EINA_TRUE;
         E_FREE(env);
      }
 
-   if (!e_input_device_input_backend_create(dev, backend))
+   TRACE_INPUT_BEGIN(e_input_device_input_backend_create);
+
+   if ((use_udev_backend) &&
+       (!e_input_device_input_backend_create(dev, E_INPUT_LIBINPUT_BACKEND_UDEV)))
      {
-        EINA_LOG_ERR("Failed to create device\n");
+        EINA_LOG_ERR("Failed to create e_input_device\n");
         TRACE_INPUT_END();
         goto device_create_err;
      }
+
+   if ((use_path_backend) && (!use_udev_backend || skip_udev_enumeration) &&
+       (!e_input_device_input_backend_create(dev, E_INPUT_LIBINPUT_BACKEND_PATH)))
+     {
+        EINA_LOG_ERR("Failed to create e_input_device\n");
+        TRACE_INPUT_END();
+        goto device_create_err;
+     }
+
    TRACE_INPUT_END();
 
+   if (use_udev_backend && skip_udev_enumeration && !use_path_backend)
+     {
+        /* Enable some of keyboard, touch devices temporarily */
+        /* FIXME : get seat caps from e_input configuration or env */
+        seat_caps = E_INPUT_SEAT_KEYBOARD | E_INPUT_SEAT_TOUCH;
+        e_comp_wl_input_seat_caps_set(seat_caps);
+     }
+
    e_input->dev = dev;
 
    TRACE_INPUT_END();
@@ -110,21 +159,13 @@ log_err:
         eina_stringshare_del(e_input->input_base_dir);
         e_input->input_base_dir = NULL;
      }
-   ecore_event_evas_shutdown();
 
-ecore_event_evas_err:
    eeze_shutdown();
 
 eeze_err:
-   ecore_event_shutdown();
-
-ecore_event_err:
-   ecore_shutdown();
-
-ecore_err:
-   eina_shutdown();
+   ecore_event_evas_shutdown();
 
-eina_err:
+ecore_event_evas_err:
 
    TRACE_INPUT_END();
 
index 145d458..c3c57b1 100644 (file)
@@ -59,6 +59,8 @@ struct _E_Input
    Ecore_Window window;
    E_Input_Device *dev;
    const char *input_base_dir;
+
+   Eina_Bool use_thread : 1;
 };
 
 struct _E_Input_Device
@@ -77,6 +79,7 @@ struct _E_Input_Device
 EINTERN int e_input_init(Ecore_Evas *ee);
 EINTERN int e_input_shutdown(void);
 EINTERN const char *e_input_base_dir_get(void);
+EINTERN Eina_Bool e_input_thread_enabled_get(void);
 
 EINTERN E_Input_Device *e_input_device_open(void);
 EINTERN Eina_Bool e_input_device_close(E_Input_Device *dev);
index 006b9f8..974e999 100644 (file)
@@ -696,7 +696,6 @@ e_input_device_input_backend_create(E_Input_Device *dev, E_Input_Libinput_Backen
 static void
 _einput_device_input_thread_udev_backend_heavy(void *data, Ecore_Thread *th, void *msg_data)
 {
-   char *env = NULL;
    E_Input_Backend *input = (E_Input_Backend *)data;
 
    EINA_SAFETY_ON_NULL_RETURN(input);
@@ -709,6 +708,8 @@ _einput_device_input_thread_udev_backend_heavy(void *data, Ecore_Thread *th, voi
 
    if (!input->libinput)
      {
+        free(input);
+
         ERR("Could not create libinput context: %m");
         return;
      }
@@ -790,13 +791,11 @@ _e_input_device_input_thread_init_udev_backend(E_Input_Backend *input)
    return !!(input->thread);
 }
 
-
 /* public functions */
 EINTERN Eina_Bool
 e_input_device_input_create_libinput_udev(E_Input_Device *dev)
 {
    E_Input_Backend *input;
-   Eina_Bool use_thread = EINA_FALSE;
    char *env = NULL;
 
    /* check for valid device */
@@ -811,6 +810,7 @@ e_input_device_input_create_libinput_udev(E_Input_Device *dev)
    /* set reference for parent device */
    input->dev = dev;
 
+   input->backend = E_INPUT_LIBINPUT_BACKEND_UDEV;
    input->log_disable = EINA_FALSE;
    input->log_use_eina = EINA_FALSE;
 
@@ -827,21 +827,12 @@ e_input_device_input_create_libinput_udev(E_Input_Device *dev)
      }
    E_FREE(env);
 
-   env = e_util_env_get("E_INPUT_USE_THREAD_INIT");
-   if (env)
-     {
-        use_thread = EINA_TRUE;
-        E_FREE(env);
-     }
-
-   input->use_thread = use_thread;
-
-   if (input->use_thread)
+   if (e_input_thread_enabled_get())
      {
         /* intialize libinput udev backend within an ecore thread */
         if (!_e_input_device_input_thread_init_udev_backend(input))
           {
-             ERR("Failed to initialize e_input backend !");
+             ERR("Failed to initialize e_input backend (libinput udev backend) !");
              goto err;
         }
 
@@ -898,12 +889,119 @@ err:
    return EINA_FALSE;
 }
 
+static void
+_einput_device_input_thread_path_backend_heavy(void *data, Ecore_Thread *th, void *msg_data)
+{
+   char *env = NULL;
+   struct libinput_device *device;
+   E_Input_Backend *input = (E_Input_Backend *)data;
+
+   EINA_SAFETY_ON_NULL_RETURN(input);
+   EINA_SAFETY_ON_NULL_RETURN(input->dev);
+   EINA_SAFETY_ON_NULL_RETURN(input->dev->seat);
+
+   /* try to create libinput context */
+   input->libinput =
+     libinput_path_create_context(&_input_interface, input);
+   if (!input->libinput)
+     {
+        free(input);
+
+        ERR("Could not create libinput path context: %m");
+        return;
+     }
+
+   if (input->log_disable)
+     libinput_log_set_handler(input->libinput, NULL);
+   else
+     {
+        if (input->log_use_eina)
+          libinput_log_set_handler(input->libinput, e_input_device_libinput_log_handler);
+        libinput_log_set_priority(input->libinput, LIBINPUT_LOG_PRIORITY_INFO);
+     }
+
+   TRACE_INPUT_BEGIN(libinput_path_add_device_loop);
+   for (int i = 0; i < input->path_ndevices; i++)
+     {
+        char buf[1024] = "PATH_DEVICE_";
+        eina_convert_itoa(i + 1, buf + 12);
+        env = e_util_env_get(buf);
+
+        if (env)
+          {
+             device = libinput_path_add_device(input->libinput, env);
+             if (!device)
+               ERR("Failed to initialized device %s", env);
+             else
+               INF("libinput_path created input device %s", env);
+             E_FREE(env);
+          }
+     }
+   TRACE_INPUT_END();
+
+   return;
+}
+
+static void
+_einput_device_input_thread_path_backend_notify(void *data, Ecore_Thread *th, void *msg_data)
+{
+   //TODO : do if there is something to do in main thread
+}
+
+static void
+_einput_device_input_thread_path_backend_end(void *data, Ecore_Thread *th, void *msg_data)
+{
+   E_Input_Backend *input = (E_Input_Backend *)data;
+   E_Input_Device *dev = NULL;
+
+   EINA_SAFETY_ON_NULL_RETURN(input);
+   EINA_SAFETY_ON_NULL_RETURN(input->dev);
+
+   input->thread = NULL;
+
+   /* enable this input */
+   if (!e_input_enable_input(input))
+     {
+        ERR("Failed to enable input");
+        return;
+     }
+
+   /* append this input */
+   dev = input->dev;
+   dev->inputs = eina_list_append(dev->inputs, input);
+
+   /* process pending events */
+   _input_events_process(input);
+}
+
+static void
+_einput_device_input_thread_path_backend_cancel(void *data, Ecore_Thread *th, void *msg_data)
+{
+   E_Input_Backend *input = (E_Input_Backend *)data;
+
+   EINA_SAFETY_ON_NULL_RETURN(input);
+
+   input->thread = NULL;
+}
+
+static Eina_Bool
+_e_input_device_input_thread_init_path_backend(E_Input_Backend *input)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
+
+   input->thread = ecore_thread_feedback_run((Ecore_Thread_Cb)_einput_device_input_thread_path_backend_heavy,
+                                             (Ecore_Thread_Notify_Cb)_einput_device_input_thread_path_backend_notify,
+                                             (Ecore_Thread_Cb)_einput_device_input_thread_path_backend_end,
+                                             (Ecore_Thread_Cb)_einput_device_input_thread_path_backend_cancel, input, 1);
+   return !!(input->thread);
+}
+
 EINTERN Eina_Bool
 e_input_device_input_create_libinput_path(E_Input_Device *dev)
 {
    E_Input_Backend *input;
    struct libinput_device *device;
-   int devices_num = 0;
+   int ndevices = 0;
    char *env;
 
    /* check for valid device */
@@ -912,16 +1010,16 @@ e_input_device_input_create_libinput_path(E_Input_Device *dev)
    env = e_util_env_get("PATH_DEVICES_NUM");
    if (env)
      {
-        devices_num = atoi(env);
+        ndevices = atoi(env);
         E_FREE(env);
      }
 
-   if (devices_num <= 0 || devices_num >= INT_MAX)
+   if (ndevices <= 0 || ndevices >= INT_MAX)
      {
         return EINA_TRUE;
      }
 
-   INF("PATH_DEVICES_NUM : %d", devices_num);
+   INF("PATH_DEVICES_NUM : %d", ndevices);
 
    /* try to allocate space for new input structure */
    if (!(input = calloc(1, sizeof(E_Input_Backend))))
@@ -932,6 +1030,8 @@ e_input_device_input_create_libinput_path(E_Input_Device *dev)
    /* set reference for parent device */
    input->dev = dev;
 
+   input->backend = E_INPUT_LIBINPUT_BACKEND_PATH;
+   input->path_ndevices = ndevices;
    input->log_disable = EINA_FALSE;
    input->log_use_eina = EINA_FALSE;
 
@@ -948,6 +1048,18 @@ e_input_device_input_create_libinput_path(E_Input_Device *dev)
      }
    E_FREE(env);
 
+   if (e_input_thread_enabled_get())
+     {
+        /* intialize libinput path backend within an ecore thread */
+        if (!_e_input_device_input_thread_init_path_backend(input))
+          {
+             ERR("Failed to initialize e_input backend (libinput path backend) !");
+             goto err;
+        }
+
+        return EINA_TRUE;
+     }
+
    /* try to create libinput context */
    input->libinput =
      libinput_path_create_context(&_input_interface, input);
@@ -966,7 +1078,8 @@ e_input_device_input_create_libinput_path(E_Input_Device *dev)
         libinput_log_set_priority(input->libinput, LIBINPUT_LOG_PRIORITY_INFO);
      }
 
-   for (int i = 0; i < devices_num; i++)
+   TRACE_INPUT_BEGIN(libinput_path_add_device_loop);
+   for (int i = 0; i < ndevices; i++)
      {
         char buf[1024] = "PATH_DEVICE_";
         eina_convert_itoa(i + 1, buf + 12);
@@ -981,6 +1094,7 @@ e_input_device_input_create_libinput_path(E_Input_Device *dev)
              E_FREE(env);
           }
      }
+   TRACE_INPUT_END();
 
    /* enable this input */
    if (!e_input_enable_input(input))
index e0d7976..46dd82b 100644 (file)
@@ -46,10 +46,12 @@ struct _E_Input_Backend
    Eina_Bool left_handed : 1;
 
    Ecore_Thread *thread;
-   Eina_Bool use_thread : 1;
+   E_Input_Libinput_Backend backend;
 
    Eina_Bool log_disable : 1;
    Eina_Bool log_use_eina : 1;
+
+   unsigned int path_ndevices;
 };
 
 struct _E_Input_Evdev