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"
8 #include "e_comp_input_intern.h"
10 #include <Ecore_Input_Evas.h>
11 #include <cpu-boosting.h>
14 static int _e_input_hooks_delete = 0;
15 static int _e_input_hooks_walking = 0;
17 static pid_t _e_input_thread_id = 0;
18 static pid_t _e_input_main_thread_id = 0;
19 static pthread_key_t thread_id_key = 0;
20 static pthread_once_t once_init = PTHREAD_ONCE_INIT;
21 static int _e_input_thread_error = 0;
23 static Eina_Inlist *_e_input_hooks[] =
25 [E_INPUT_HOOK_POINTER_WARP] = NULL,
26 [E_INPUT_HOOK_INPUT_THREAD_START] = NULL,
29 int _e_input_init_count;
30 int _e_input_log_dom = -1;
32 EINTERN int E_INPUT_EVENT_SEAT_ADD = -1;
33 EINTERN int E_EVENT_INPUT_ENABLED = -1;
34 EINTERN int E_EVENT_INPUT_DISABLED = -1;
36 E_API E_Input *e_input = NULL;
39 e_input_hook_add(E_Input_Hook_Point hookpoint, E_Input_Hook_Cb func, const void *data)
43 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_INPUT_HOOK_LAST, NULL);
44 EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
45 hook = E_NEW(E_Input_Hook, 1);
46 if (!hook) return NULL;
47 hook->hookpoint = hookpoint;
49 hook->data = (void*)data;
50 _e_input_hooks[hookpoint] = eina_inlist_append(_e_input_hooks[hookpoint], EINA_INLIST_GET(hook));
55 e_input_hook_del(E_Input_Hook *hook)
57 EINA_SAFETY_ON_NULL_RETURN(hook);
60 if (_e_input_hooks_walking == 0)
62 _e_input_hooks[hook->hookpoint] = eina_inlist_remove(_e_input_hooks[hook->hookpoint], EINA_INLIST_GET(hook));
66 _e_input_hooks_delete++;
70 _e_input_hooks_clean(void)
75 for (x = 0; x < E_INPUT_HOOK_LAST; x++)
76 EINA_INLIST_FOREACH_SAFE(_e_input_hooks[x], l, hook)
78 if (!hook->delete_me) continue;
79 _e_input_hooks[x] = eina_inlist_remove(_e_input_hooks[x], EINA_INLIST_GET(hook));
83 _e_input_hooks_delete = 0;
87 e_input_hook_call(E_Input_Hook_Point hookpoint, const char *device_name)
91 _e_input_hooks_walking++;
92 EINA_INLIST_FOREACH(_e_input_hooks[hookpoint], hook)
94 if (hook->delete_me) continue;
95 hook->func(hook->data, device_name);
97 _e_input_hooks_walking--;
98 if ((_e_input_hooks_walking == 0) && (_e_input_hooks_delete > 0))
99 _e_input_hooks_clean();
103 _e_input_cb_screen_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
107 E_Input_Device *dev_data;
109 devices = (Eina_List *)e_input_devices_get();
111 EINA_LIST_FOREACH(devices, l, dev_data)
113 e_input_device_output_changed(dev_data);
115 return ECORE_CALLBACK_PASS_ON;
119 e_input_base_dir_get(void)
121 return e_input->input_base_dir;
125 e_input_thread_enabled_get(void)
127 return e_input->use_thread;
131 e_input_init(Ecore_Evas *ee)
134 unsigned int seat_caps = 0;
138 Eina_Bool use_udev_backend = EINA_FALSE;
139 Eina_Bool use_path_backend = EINA_FALSE;
140 Eina_Bool skip_udev_enumeration = EINA_FALSE;
142 EINA_SAFETY_ON_NULL_RETURN_VAL(ee, _e_input_init_count);
144 TRACE_INPUT_BEGIN(e_input_init);
146 if (++_e_input_init_count != 1) return _e_input_init_count;
147 if (!ecore_event_evas_init()) goto ecore_event_evas_err;
149 _e_input_log_dom = eina_log_domain_register("e_input", EINA_COLOR_GREEN);
150 if (!_e_input_log_dom)
152 EINA_LOG_ERR("Could not create logging domain for E_Input");
155 eina_log_domain_level_set("e_input", EINA_LOG_LEVEL_INFO);
159 E_INPUT_EVENT_SEAT_ADD = ecore_event_type_new();
160 E_EVENT_INPUT_ENABLED = ecore_event_type_new();
161 E_EVENT_INPUT_DISABLED = ecore_event_type_new();
163 ecore_event_add(E_EVENT_INPUT_ENABLED, NULL, NULL, NULL);
165 ecore_evas_input_event_register_with_multi2(ee);
169 e_input = (E_Input *)calloc(1, sizeof(E_Input));
174 EINA_LOG_ERR("Failed to alloc memory for e_input\n");
178 // TODO : make this variable configurable e.g. e.cfg
179 e_input->input_base_dir = eina_stringshare_add("/dev/input");
180 e_input->use_thread = EINA_FALSE;
182 e_input->touch_max_count = 1;//This is going to updated when a touch device is attached.
184 dev = e_input_device_open();
191 EINA_LOG_ERR("Failed to open device\n");
195 e_input->window = ecore_evas_window_get(ee);
196 e_input_device_window_set(dev, e_input->window);
198 env = e_util_env_get("E_INPUT_USE_THREAD_INIT");
202 e_input->use_thread = EINA_TRUE;
206 env = e_util_env_get("LIBINPUT_UDEV_SKIP_INITIAL_ENUMERATION");
209 skip_udev_enumeration = EINA_TRUE;
213 env = e_util_env_get("E_INPUT_USE_LIBINPUT_UDEV_BACKEND");
216 use_udev_backend = EINA_TRUE;
220 env = e_util_env_get("E_INPUT_USE_LIBINPUT_PATH_BACKEND");
223 use_path_backend = EINA_TRUE;
227 TRACE_INPUT_BEGIN(e_input_device_input_backend_create);
229 /* FIXME: we need to select default backend udev or path.
230 * Input system will not be initialized, if there are no environment is set.
232 if ((!use_udev_backend) && (!use_path_backend))
234 EINA_LOG_INFO("This system doesn't select input backend. We use udev backend defaultly\n");
235 use_udev_backend = EINA_TRUE;
238 if ((use_udev_backend) &&
239 (!e_input_device_input_backend_create(dev, E_INPUT_LIBINPUT_BACKEND_UDEV)))
241 EINA_LOG_ERR("Failed to create e_input_device\n");
243 goto device_create_err;
246 if ((use_path_backend) && (!use_udev_backend || skip_udev_enumeration) &&
247 (!e_input_device_input_backend_create(dev, E_INPUT_LIBINPUT_BACKEND_PATH)))
249 EINA_LOG_ERR("Failed to create e_input_device\n");
251 goto device_create_err;
256 if (use_udev_backend && skip_udev_enumeration && !use_path_backend)
258 /* Enable some of keyboard, touch devices temporarily */
259 /* FIXME : get seat caps from e_input configuration or env */
260 seat_caps = E_INPUT_SEAT_KEYBOARD | E_INPUT_SEAT_TOUCH;
261 e_comp_wl_input_seat_caps_set(seat_caps);
264 E_LIST_HANDLER_APPEND(e_input->handlers, E_EVENT_SCREEN_CHANGE, _e_input_cb_screen_change, NULL);
268 return _e_input_init_count;
271 e_input_device_close(dev);
274 if (e_input && e_input->input_base_dir)
276 eina_stringshare_del(e_input->input_base_dir);
277 e_input->input_base_dir = NULL;
280 ecore_event_evas_shutdown();
282 ecore_event_evas_err:
286 return --_e_input_init_count;
290 e_input_shutdown(void)
292 Ecore_Event_Handler *h = NULL;
294 if (_e_input_init_count < 1) return 0;
295 if (--_e_input_init_count != 0) return _e_input_init_count;
297 ecore_event_add(E_EVENT_INPUT_DISABLED, NULL, NULL, NULL);
299 E_INPUT_EVENT_SEAT_ADD = -1;
300 E_EVENT_INPUT_ENABLED = -1;
301 E_EVENT_INPUT_DISABLED = -1;
303 EINA_LIST_FREE(e_input->handlers, h)
304 ecore_event_handler_del(h);
306 if (e_input->input_base_dir)
307 eina_stringshare_del(e_input->input_base_dir);
308 e_input_device_close(e_input->dev);
310 e_comp_input_shutdown();
314 ecore_event_evas_shutdown();
315 ecore_event_shutdown();
319 return _e_input_init_count;
325 if (e_input) return e_input;
330 e_input_ecore_evas_get(E_Input *ei)
332 if (ei) return ei->ee;
337 e_input_touch_max_count_get()
340 return e_input->touch_max_count;
346 e_input_touch_max_count_set(unsigned int max_count)
349 e_input->touch_max_count = max_count;
353 e_input_relative_motion_handler_set(e_input_relative_motion_cb handler)
358 e_input->relative_motion_handler = handler;
362 EINTERN e_input_relative_motion_cb
363 e_input_relative_motion_handler_get(void)
366 return e_input->relative_motion_handler;
372 e_input_keyboard_grab_key_handler_set(e_input_keyboard_grab_key_cb handler)
377 e_input->keyboard_grab_key_handler = handler;
381 EINTERN e_input_keyboard_grab_key_cb
382 e_input_keyboard_grab_key_handler_get(void)
385 return e_input->keyboard_grab_key_handler;
391 _wl_events_flush_cb(void *data)
393 INF("flush events in main thread");
394 e_comp_wl_display_flush();
398 e_input_wl_events_flush(void)
400 ecore_main_loop_thread_safe_call_async(_wl_events_flush_cb, NULL);
403 E_API pid_t e_input_thread_id_get()
405 return _e_input_thread_id;
409 e_input_init_thread()
411 int ret = pthread_key_create(&thread_id_key, NULL);
414 ERR("failed to create pthread_key");
417 _e_input_thread_error = ret;
420 EINTERN void e_input_thread_input_id_set(pid_t tid)
422 _e_input_thread_id = tid;
424 pthread_once(&once_init, e_input_init_thread);
425 int ret = pthread_setspecific(thread_id_key, &_e_input_thread_id);
428 ERR("failed to set thread specific");
431 _e_input_thread_error = ret;
434 E_API pid_t e_input_main_thread_id_get()
436 return _e_input_main_thread_id;
439 EINTERN void e_input_thread_main_id_set(pid_t tid)
441 _e_input_main_thread_id = tid;
445 _e_input_main_thread_set_boosting()
447 if (!pthread_getspecific(thread_id_key))
450 pid_t main_thread_id = e_input_main_thread_id_get();
451 if (main_thread_id <= 0)
453 ERR("Failed to get main thread id");
457 TRACE_INPUT_BEGIN(_e_input_main_thread_set_boosting);
458 resource_pid_t resource;
460 resource.tid = &main_thread_id;
461 resource.tid_count = 1;
463 int ret = resource_set_cpu_boosting(resource, CPU_BOOSTING_LEVEL_STRONG, CPU_BOOSTING_RESET_ON_FORK, -1);
467 ERR("set_cpu_boosting failed. error %d", ret);
471 _e_input_main_thread_clear_boosting()
473 if (!pthread_getspecific(thread_id_key))
476 pid_t main_thread_id = e_input_main_thread_id_get();
477 if (main_thread_id <= 0)
479 ERR("Failed to get main thread id");
483 TRACE_INPUT_BEGIN(_e_input_main_thread_clear_boosting);
484 resource_pid_t resource;
486 resource.tid = &main_thread_id;
487 resource.tid_count = 1;
489 int ret = resource_clear_cpu_boosting(resource);
493 ERR("clear_cpu_boosting failed. error %d", ret);
497 EINTERN void e_input_thread_boost_lock(GMutex *mutex)
499 if (!g_mutex_trylock(mutex))
501 _e_input_main_thread_set_boosting();
503 _e_input_main_thread_clear_boosting();
507 EINTERN void e_input_thread_boost_unlock(GMutex *mutex)
509 g_mutex_unlock(mutex);