1 #include "e_input_intern.h"
2 #include "e_input_log.h"
3 #include "e_comp_screen_intern.h"
4 #include "e_comp_wl_input_intern.h"
5 #include "e_comp_wl_intern.h"
6 #include "e_utils_intern.h"
8 #include <Ecore_Input_Evas.h>
9 #include <cpu-boosting.h>
12 static int _e_input_hooks_delete = 0;
13 static int _e_input_hooks_walking = 0;
15 static pid_t _e_input_thread_id = 0;
16 static pid_t _e_input_main_thread_id = 0;
17 static pthread_key_t thread_id_key = 0;
18 static pthread_once_t once_init = PTHREAD_ONCE_INIT;
19 static int _e_input_thread_error = 0;
21 static Eina_Inlist *_e_input_hooks[] =
23 [E_INPUT_HOOK_POINTER_WARP] = NULL,
24 [E_INPUT_HOOK_INPUT_THREAD_START] = NULL,
27 int _e_input_init_count;
28 int _e_input_log_dom = -1;
30 EINTERN int E_INPUT_EVENT_SEAT_ADD = -1;
31 EINTERN int E_EVENT_INPUT_ENABLED = -1;
32 EINTERN int E_EVENT_INPUT_DISABLED = -1;
34 E_API E_Input *e_input = NULL;
37 e_input_hook_add(E_Input_Hook_Point hookpoint, E_Input_Hook_Cb func, const void *data)
41 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_INPUT_HOOK_LAST, NULL);
42 EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
43 hook = E_NEW(E_Input_Hook, 1);
44 if (!hook) return NULL;
45 hook->hookpoint = hookpoint;
47 hook->data = (void*)data;
48 _e_input_hooks[hookpoint] = eina_inlist_append(_e_input_hooks[hookpoint], EINA_INLIST_GET(hook));
53 e_input_hook_del(E_Input_Hook *hook)
55 EINA_SAFETY_ON_NULL_RETURN(hook);
58 if (_e_input_hooks_walking == 0)
60 _e_input_hooks[hook->hookpoint] = eina_inlist_remove(_e_input_hooks[hook->hookpoint], EINA_INLIST_GET(hook));
64 _e_input_hooks_delete++;
68 _e_input_hooks_clean(void)
73 for (x = 0; x < E_INPUT_HOOK_LAST; x++)
74 EINA_INLIST_FOREACH_SAFE(_e_input_hooks[x], l, hook)
76 if (!hook->delete_me) continue;
77 _e_input_hooks[x] = eina_inlist_remove(_e_input_hooks[x], EINA_INLIST_GET(hook));
81 _e_input_hooks_delete = 0;
85 _e_input_hook_call(E_Input_Hook_Point hookpoint, const char *device_name)
89 _e_input_hooks_walking++;
90 EINA_INLIST_FOREACH(_e_input_hooks[hookpoint], hook)
92 if (hook->delete_me) continue;
93 hook->func(hook->data, device_name);
95 _e_input_hooks_walking--;
96 if ((_e_input_hooks_walking == 0) && (_e_input_hooks_delete > 0))
97 _e_input_hooks_clean();
101 _e_input_cb_screen_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
105 E_Input_Device *dev_data;
107 devices = (Eina_List *)e_input_devices_get();
109 EINA_LIST_FOREACH(devices, l, dev_data)
111 e_input_device_output_changed(dev_data);
113 return ECORE_CALLBACK_PASS_ON;
117 e_input_base_dir_get(void)
119 return e_input->input_base_dir;
123 e_input_thread_enabled_get(void)
125 return e_input->use_thread;
129 e_input_init(Ecore_Evas *ee)
132 unsigned int seat_caps = 0;
136 Eina_Bool use_udev_backend = EINA_FALSE;
137 Eina_Bool use_path_backend = EINA_FALSE;
138 Eina_Bool skip_udev_enumeration = EINA_FALSE;
140 EINA_SAFETY_ON_NULL_RETURN_VAL(ee, _e_input_init_count);
142 TRACE_INPUT_BEGIN(e_input_init);
144 if (++_e_input_init_count != 1) return _e_input_init_count;
145 if (!ecore_event_evas_init()) goto ecore_event_evas_err;
147 _e_input_log_dom = eina_log_domain_register("e_input", EINA_COLOR_GREEN);
148 if (!_e_input_log_dom)
150 EINA_LOG_ERR("Could not create logging domain for E_Input");
153 eina_log_domain_level_set("e_input", EINA_LOG_LEVEL_INFO);
155 E_INPUT_EVENT_SEAT_ADD = ecore_event_type_new();
156 E_EVENT_INPUT_ENABLED = ecore_event_type_new();
157 E_EVENT_INPUT_DISABLED = ecore_event_type_new();
159 ecore_event_add(E_EVENT_INPUT_ENABLED, NULL, NULL, NULL);
161 ecore_evas_input_event_register_with_multi2(ee);
165 e_input = (E_Input *)calloc(1, sizeof(E_Input));
170 EINA_LOG_ERR("Failed to alloc memory for e_input\n");
174 // TODO : make this variable configurable e.g. e.cfg
175 e_input->input_base_dir = eina_stringshare_add("/dev/input");
176 e_input->use_thread = EINA_FALSE;
178 e_input->touch_device_count = 0;
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 _keyboard_share_key_event_flush_cb(void *data)
388 INF("flush keyboard share key events");
389 e_comp_wl_display_flush();
393 e_input_flush_keyboard_share_events(void)
395 ecore_main_loop_thread_safe_call_async(_keyboard_share_key_event_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_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_main_thread_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_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_boost_unlock(GMutex *mutex)
504 g_mutex_unlock(mutex);