1 #include "e_input_intern.h"
2 #include "e_input_log.h"
3 #include "e_input_device_intern.h"
4 #include "e_comp_screen_intern.h"
5 #include "e_comp_wl_input_intern.h"
6 #include "e_comp_wl_intern.h"
7 #include "e_utils_intern.h"
9 #include <Ecore_Input_Evas.h>
10 #include <cpu-boosting.h>
13 static int _e_input_hooks_delete = 0;
14 static int _e_input_hooks_walking = 0;
16 static pid_t _e_input_thread_id = 0;
17 static pid_t _e_input_main_thread_id = 0;
18 static pthread_key_t thread_id_key = 0;
19 static pthread_once_t once_init = PTHREAD_ONCE_INIT;
20 static int _e_input_thread_error = 0;
22 static Eina_Inlist *_e_input_hooks[] =
24 [E_INPUT_HOOK_POINTER_WARP] = NULL,
25 [E_INPUT_HOOK_INPUT_THREAD_START] = NULL,
28 int _e_input_init_count;
29 int _e_input_log_dom = -1;
31 EINTERN int E_INPUT_EVENT_SEAT_ADD = -1;
32 EINTERN int E_EVENT_INPUT_ENABLED = -1;
33 EINTERN int E_EVENT_INPUT_DISABLED = -1;
35 E_API E_Input *e_input = NULL;
38 e_input_hook_add(E_Input_Hook_Point hookpoint, E_Input_Hook_Cb func, const void *data)
42 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_INPUT_HOOK_LAST, NULL);
43 EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
44 hook = E_NEW(E_Input_Hook, 1);
45 if (!hook) return NULL;
46 hook->hookpoint = hookpoint;
48 hook->data = (void*)data;
49 _e_input_hooks[hookpoint] = eina_inlist_append(_e_input_hooks[hookpoint], EINA_INLIST_GET(hook));
54 e_input_hook_del(E_Input_Hook *hook)
56 EINA_SAFETY_ON_NULL_RETURN(hook);
59 if (_e_input_hooks_walking == 0)
61 _e_input_hooks[hook->hookpoint] = eina_inlist_remove(_e_input_hooks[hook->hookpoint], EINA_INLIST_GET(hook));
65 _e_input_hooks_delete++;
69 _e_input_hooks_clean(void)
74 for (x = 0; x < E_INPUT_HOOK_LAST; x++)
75 EINA_INLIST_FOREACH_SAFE(_e_input_hooks[x], l, hook)
77 if (!hook->delete_me) continue;
78 _e_input_hooks[x] = eina_inlist_remove(_e_input_hooks[x], EINA_INLIST_GET(hook));
82 _e_input_hooks_delete = 0;
86 e_input_hook_call(E_Input_Hook_Point hookpoint, const char *device_name)
90 _e_input_hooks_walking++;
91 EINA_INLIST_FOREACH(_e_input_hooks[hookpoint], hook)
93 if (hook->delete_me) continue;
94 hook->func(hook->data, device_name);
96 _e_input_hooks_walking--;
97 if ((_e_input_hooks_walking == 0) && (_e_input_hooks_delete > 0))
98 _e_input_hooks_clean();
102 _e_input_cb_screen_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
106 E_Input_Device *dev_data;
108 devices = (Eina_List *)e_input_devices_get();
110 EINA_LIST_FOREACH(devices, l, dev_data)
112 e_input_device_output_changed(dev_data);
114 return ECORE_CALLBACK_PASS_ON;
118 e_input_base_dir_get(void)
120 return e_input->input_base_dir;
124 e_input_thread_enabled_get(void)
126 return e_input->use_thread;
130 e_input_init(Ecore_Evas *ee)
133 unsigned int seat_caps = 0;
137 Eina_Bool use_udev_backend = EINA_FALSE;
138 Eina_Bool use_path_backend = EINA_FALSE;
139 Eina_Bool skip_udev_enumeration = EINA_FALSE;
141 EINA_SAFETY_ON_NULL_RETURN_VAL(ee, _e_input_init_count);
143 TRACE_INPUT_BEGIN(e_input_init);
145 if (++_e_input_init_count != 1) return _e_input_init_count;
146 if (!ecore_event_evas_init()) goto ecore_event_evas_err;
148 _e_input_log_dom = eina_log_domain_register("e_input", EINA_COLOR_GREEN);
149 if (!_e_input_log_dom)
151 EINA_LOG_ERR("Could not create logging domain for E_Input");
154 eina_log_domain_level_set("e_input", EINA_LOG_LEVEL_INFO);
156 E_INPUT_EVENT_SEAT_ADD = ecore_event_type_new();
157 E_EVENT_INPUT_ENABLED = ecore_event_type_new();
158 E_EVENT_INPUT_DISABLED = ecore_event_type_new();
160 ecore_event_add(E_EVENT_INPUT_ENABLED, NULL, NULL, NULL);
162 ecore_evas_input_event_register_with_multi2(ee);
166 e_input = (E_Input *)calloc(1, sizeof(E_Input));
171 EINA_LOG_ERR("Failed to alloc memory for e_input\n");
175 // TODO : make this variable configurable e.g. e.cfg
176 e_input->input_base_dir = eina_stringshare_add("/dev/input");
177 e_input->use_thread = EINA_FALSE;
179 e_input->touch_max_count = 1;//This is going to updated when a touch device is attached.
181 dev = e_input_device_open();
188 EINA_LOG_ERR("Failed to open device\n");
192 e_input->window = ecore_evas_window_get(ee);
193 e_input_device_window_set(dev, e_input->window);
195 env = e_util_env_get("E_INPUT_USE_THREAD_INIT");
199 e_input->use_thread = EINA_TRUE;
203 env = e_util_env_get("LIBINPUT_UDEV_SKIP_INITIAL_ENUMERATION");
206 skip_udev_enumeration = EINA_TRUE;
210 env = e_util_env_get("E_INPUT_USE_LIBINPUT_UDEV_BACKEND");
213 use_udev_backend = EINA_TRUE;
217 env = e_util_env_get("E_INPUT_USE_LIBINPUT_PATH_BACKEND");
220 use_path_backend = EINA_TRUE;
224 TRACE_INPUT_BEGIN(e_input_device_input_backend_create);
226 /* FIXME: we need to select default backend udev or path.
227 * Input system will not be initialized, if there are no environment is set.
229 if ((!use_udev_backend) && (!use_path_backend))
231 EINA_LOG_INFO("This system doesn't select input backend. We use udev backend defaultly\n");
232 use_udev_backend = EINA_TRUE;
235 if ((use_udev_backend) &&
236 (!e_input_device_input_backend_create(dev, E_INPUT_LIBINPUT_BACKEND_UDEV)))
238 EINA_LOG_ERR("Failed to create e_input_device\n");
240 goto device_create_err;
243 if ((use_path_backend) && (!use_udev_backend || skip_udev_enumeration) &&
244 (!e_input_device_input_backend_create(dev, E_INPUT_LIBINPUT_BACKEND_PATH)))
246 EINA_LOG_ERR("Failed to create e_input_device\n");
248 goto device_create_err;
253 if (use_udev_backend && skip_udev_enumeration && !use_path_backend)
255 /* Enable some of keyboard, touch devices temporarily */
256 /* FIXME : get seat caps from e_input configuration or env */
257 seat_caps = E_INPUT_SEAT_KEYBOARD | E_INPUT_SEAT_TOUCH;
258 e_comp_wl_input_seat_caps_set(seat_caps);
261 E_LIST_HANDLER_APPEND(e_input->handlers, E_EVENT_SCREEN_CHANGE, _e_input_cb_screen_change, NULL);
265 return _e_input_init_count;
268 e_input_device_close(dev);
271 if (e_input && e_input->input_base_dir)
273 eina_stringshare_del(e_input->input_base_dir);
274 e_input->input_base_dir = NULL;
277 ecore_event_evas_shutdown();
279 ecore_event_evas_err:
283 return --_e_input_init_count;
287 e_input_shutdown(void)
289 Ecore_Event_Handler *h = NULL;
291 if (_e_input_init_count < 1) return 0;
292 if (--_e_input_init_count != 0) return _e_input_init_count;
294 ecore_event_add(E_EVENT_INPUT_DISABLED, NULL, NULL, NULL);
296 E_INPUT_EVENT_SEAT_ADD = -1;
297 E_EVENT_INPUT_ENABLED = -1;
298 E_EVENT_INPUT_DISABLED = -1;
300 EINA_LIST_FREE(e_input->handlers, h)
301 ecore_event_handler_del(h);
303 if (e_input->input_base_dir)
304 eina_stringshare_del(e_input->input_base_dir);
305 e_input_device_close(e_input->dev);
309 ecore_event_evas_shutdown();
310 ecore_event_shutdown();
314 return _e_input_init_count;
320 if (e_input) return e_input;
325 e_input_ecore_evas_get(E_Input *ei)
327 if (ei) return ei->ee;
332 e_input_touch_max_count_get()
335 return e_input->touch_max_count;
341 e_input_touch_max_count_set(unsigned int max_count)
344 e_input->touch_max_count = max_count;
348 e_input_relative_motion_handler_set(e_input_relative_motion_cb handler)
353 e_input->relative_motion_handler = handler;
357 EINTERN e_input_relative_motion_cb
358 e_input_relative_motion_handler_get(void)
361 return e_input->relative_motion_handler;
367 e_input_keyboard_grab_key_handler_set(e_input_keyboard_grab_key_cb handler)
372 e_input->keyboard_grab_key_handler = handler;
376 EINTERN e_input_keyboard_grab_key_cb
377 e_input_keyboard_grab_key_handler_get(void)
380 return e_input->keyboard_grab_key_handler;
386 _wl_events_flush_cb(void *data)
388 INF("flush events in main thread");
389 e_comp_wl_display_flush();
393 e_input_wl_events_flush(void)
395 ecore_main_loop_thread_safe_call_async(_wl_events_flush_cb, NULL);
398 E_API pid_t e_input_thread_id_get()
400 return _e_input_thread_id;
404 e_input_init_thread()
406 int ret = pthread_key_create(&thread_id_key, NULL);
409 ERR("failed to create pthread_key");
412 _e_input_thread_error = ret;
415 EINTERN void e_input_thread_input_id_set(pid_t tid)
417 _e_input_thread_id = tid;
419 pthread_once(&once_init, e_input_init_thread);
420 int ret = pthread_setspecific(thread_id_key, &_e_input_thread_id);
423 ERR("failed to set thread specific");
426 _e_input_thread_error = ret;
429 E_API pid_t e_input_main_thread_id_get()
431 return _e_input_main_thread_id;
434 EINTERN void e_input_thread_main_id_set(pid_t tid)
436 _e_input_main_thread_id = tid;
440 _e_input_main_thread_set_boosting()
442 if (!pthread_getspecific(thread_id_key))
445 pid_t main_thread_id = e_input_main_thread_id_get();
446 if (main_thread_id <= 0)
448 ERR("Failed to get main thread id");
452 TRACE_INPUT_BEGIN(_e_input_main_thread_set_boosting);
453 resource_pid_t resource;
455 resource.tid = &main_thread_id;
456 resource.tid_count = 1;
458 int ret = resource_set_cpu_boosting(resource, CPU_BOOSTING_LEVEL_STRONG, CPU_BOOSTING_RESET_ON_FORK, -1);
462 ERR("set_cpu_boosting failed. error %d", ret);
466 _e_input_main_thread_clear_boosting()
468 if (!pthread_getspecific(thread_id_key))
471 pid_t main_thread_id = e_input_main_thread_id_get();
472 if (main_thread_id <= 0)
474 ERR("Failed to get main thread id");
478 TRACE_INPUT_BEGIN(_e_input_main_thread_clear_boosting);
479 resource_pid_t resource;
481 resource.tid = &main_thread_id;
482 resource.tid_count = 1;
484 int ret = resource_clear_cpu_boosting(resource);
488 ERR("clear_cpu_boosting failed. error %d", ret);
492 EINTERN void e_input_thread_boost_lock(GMutex *mutex)
494 if (!g_mutex_trylock(mutex))
496 _e_input_main_thread_set_boosting();
498 _e_input_main_thread_clear_boosting();
502 EINTERN void e_input_thread_boost_unlock(GMutex *mutex)
504 g_mutex_unlock(mutex);