#include "e.h"
#include "e_input_private.h"
+#include "e_comp_wl_input.h"
#include <Ecore_Input_Evas.h>
int _e_input_init_count;
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)
// 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();
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();
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();
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);
if (!input->libinput)
{
+ free(input);
+
ERR("Could not create libinput context: %m");
return;
}
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 */
/* 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;
}
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;
}
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 */
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))))
/* 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;
}
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);
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);
E_FREE(env);
}
}
+ TRACE_INPUT_END();
/* enable this input */
if (!e_input_enable_input(input))