2 #include "e_input_private.h"
4 /* e_input_device private variable */
5 static Eina_List *einput_devices;
6 static E_Input_Device *e_input_device_default = NULL;
9 _device_open_no_pending(const char *device, int flags)
14 fd = open(device, flags | O_CLOEXEC);
16 if (fd < 0) return fd;
17 if (fstat(fd, &s) == -1)
27 _device_close(const char *device, int fd)
35 _e_input_device_cb_open_restricted(const char *path, int flags, void *data)
37 E_Input_Backend *input;
40 if (!(input = data)) return -1;
42 /* try to open the device */
43 fd = _device_open_no_pending(path, flags);
47 ERR("Could not open device");
51 if (input->dev->fd_hash)
52 eina_hash_add(input->dev->fd_hash, path, (void *)(intptr_t)fd);
58 _e_input_device_cb_close_restricted(int fd, void *data)
60 if (fd >= 0) close(fd);
63 const struct libinput_interface _input_interface =
65 _e_input_device_cb_open_restricted,
66 _e_input_device_cb_close_restricted,
69 static E_Input_Device *
70 _e_input_device_default_get(void)
72 return e_input_device_default;
76 _e_input_device_cached_context_get(enum xkb_context_flags flags)
79 return xkb_context_new(flags);
81 return xkb_context_ref(cached_context);
85 _e_input_device_cached_keymap_get(struct xkb_context *ctx,
86 const struct xkb_rule_names *names,
87 enum xkb_keymap_compile_flags flags)
89 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
92 return xkb_map_new_from_names(ctx, names, flags);
94 return xkb_map_ref(cached_keymap);
98 _e_input_device_cached_context_update(struct xkb_context *ctx)
103 EINA_LIST_FOREACH(einput_devices, l, dev)
105 xkb_context_unref(dev->xkb_ctx);
106 dev->xkb_ctx = xkb_context_ref(ctx);
111 _e_input_device_cached_keymap_update(struct xkb_keymap *map)
113 Eina_List *l, *l2, *l3;
118 EINA_LIST_FOREACH(einput_devices, l, dev)
119 EINA_LIST_FOREACH(dev->seats, l2, seat)
120 EINA_LIST_FOREACH(e_input_seat_evdev_list_get(seat), l3, edev)
122 xkb_keymap_unref(edev->xkb.keymap);
123 edev->xkb.keymap = xkb_keymap_ref(map);
124 xkb_state_unref(edev->xkb.state);
125 edev->xkb.state = xkb_state_new(map);
130 e_input_device_keyboard_cached_context_set(struct xkb_context *ctx)
132 EINA_SAFETY_ON_NULL_RETURN(ctx);
134 if (cached_context == ctx) return;
137 _e_input_device_cached_context_update(ctx);
139 cached_context = ctx;
143 e_input_device_keyboard_cached_keymap_set(struct xkb_keymap *map)
145 EINA_SAFETY_ON_NULL_RETURN(map);
147 if (cached_keymap == map) return;
150 _e_input_device_cached_keymap_update(map);
156 e_input_device_destroy(E_Input_Device *dev)
158 E_Input_Backend *input;
162 EINA_SAFETY_ON_NULL_RETURN(dev);
164 EINA_LIST_FREE(dev->seats, seat)
166 EINA_LIST_FREE(seat->devices, edev)
170 _e_input_evdev_device_destroy(edev);
174 eina_stringshare_del(seat->name);
178 EINA_LIST_FREE(dev->inputs, input)
181 ecore_main_fd_handler_del(input->hdlr);
183 libinput_unref(input->libinput);
187 eina_stringshare_del(dev->seat);
188 xkb_context_unref(dev->xkb_ctx);
189 eina_hash_free(dev->fd_hash);
192 if (dev == e_input_device_default)
193 e_input_device_default = NULL;
199 _e_input_device_add_list(E_Input_Device *dev)
202 E_Input_Device *dev_data;
204 EINA_LIST_FOREACH(einput_devices, l, dev_data)
206 if (dev_data == dev) return;
209 einput_devices = eina_list_append(einput_devices, dev);
213 _e_input_device_remove_list(E_Input_Device *dev)
215 Eina_List *l, *l_next;
216 E_Input_Device *dev_data;
218 EINA_LIST_FOREACH_SAFE(einput_devices, l, l_next, dev_data)
221 einput_devices = eina_list_remove_list(einput_devices, l);
225 EINTERN E_Input_Device *
226 e_input_device_open(void)
228 E_Input_Device *dev = NULL;
230 dev = (E_Input_Device *)calloc(1, sizeof(E_Input_Device));
234 EINA_LOG_ERR("Failed to alloc memory for E_Input_Device\n");
238 dev->seat = eina_stringshare_add("seat0");
239 dev->fd_hash = eina_hash_string_superfast_new(NULL);
241 /* try to create xkb context */
242 if (!(dev->xkb_ctx = _e_input_device_cached_context_get(0)))
244 ERR("Failed to create xkb context: %m");
248 if (!e_input_device_default)
249 e_input_device_default = dev;
251 _e_input_device_add_list(dev);
258 eina_stringshare_del(dev->seat);
259 xkb_context_unref(dev->xkb_ctx);
267 e_input_device_close(E_Input_Device *dev)
269 /* check for valid device */
270 EINA_SAFETY_ON_NULL_RETURN_VAL(dev, EINA_FALSE);
272 _e_input_device_remove_list(dev);
273 e_input_device_destroy(dev);
279 e_input_device_window_set(E_Input_Device *dev, unsigned int window)
281 /* check for valid device */
282 EINA_SAFETY_ON_TRUE_RETURN(!dev);
284 /* TODO : Must update window of ecore/evas device when the given window */
285 /* is not equal to the existing window. */
287 dev->window = window;
291 e_input_device_pointer_xy_get(E_Input_Device *dev, int *x, int *y)
301 dev = _e_input_device_default_get();
303 /* check for valid device */
304 EINA_SAFETY_ON_TRUE_RETURN(!dev);
305 EINA_LIST_FOREACH(dev->seats, l, seat)
307 EINA_LIST_FOREACH(seat->devices, ll, edev)
309 if (!libinput_device_has_capability(edev->device,
310 LIBINPUT_DEVICE_CAP_POINTER))
313 if (x) *x = seat->ptr.dx;
314 if (y) *y = seat->ptr.dy;
322 e_input_device_pointer_warp(E_Input_Device *dev, int x, int y)
329 dev = _e_input_device_default_get();
331 /* check for valid device */
332 EINA_SAFETY_ON_TRUE_RETURN(!dev);
333 EINA_LIST_FOREACH(dev->seats, l, seat)
335 EINA_LIST_FOREACH(seat->devices, ll, edev)
337 if (!libinput_device_has_capability(edev->device,
338 LIBINPUT_DEVICE_CAP_POINTER))
341 seat->ptr.dx = seat->ptr.ix = x;
342 seat->ptr.dy = seat->ptr.iy = y;
343 _e_input_pointer_motion_post(edev);
349 e_input_device_pointer_left_handed_set(E_Input_Device *dev, Eina_Bool left_handed)
351 E_Input_Seat *seat = NULL;
352 E_Input_Evdev *edev = NULL;
353 Eina_List *l = NULL, *l2 = NULL;
355 EINA_SAFETY_ON_NULL_RETURN_VAL(dev, EINA_FALSE);
356 EINA_SAFETY_ON_NULL_RETURN_VAL(dev->seats, EINA_FALSE);
358 if (dev->left_handed == left_handed)
360 dev->left_handed = left_handed;
362 EINA_LIST_FOREACH(dev->seats, l, seat)
364 EINA_LIST_FOREACH(e_input_seat_evdev_list_get(seat), l2, edev)
366 if (libinput_device_has_capability(edev->device,
367 LIBINPUT_DEVICE_CAP_POINTER))
369 if (libinput_device_config_left_handed_set(edev->device, (int)left_handed) !=
370 LIBINPUT_CONFIG_STATUS_SUCCESS)
372 WRN("Failed to set left hand mode about device: %s\n",
373 libinput_device_get_name(edev->device));
384 e_input_device_pointer_rotation_set(E_Input_Device *dev, int rotation)
386 E_Input_Seat *seat = NULL;
389 EINA_SAFETY_ON_NULL_RETURN_VAL(dev, EINA_FALSE);
390 EINA_SAFETY_ON_NULL_RETURN_VAL(dev->seats, EINA_FALSE);
392 if ((rotation % 90 != 0) || (rotation / 90 > 3) || (rotation < 0)) return EINA_FALSE;
394 EINA_LIST_FOREACH(dev->seats, l, seat)
399 seat->ptr.swap = EINA_TRUE;
400 seat->ptr.invert_x = EINA_FALSE;
401 seat->ptr.invert_y = EINA_TRUE;
404 seat->ptr.swap = EINA_FALSE;
405 seat->ptr.invert_x = EINA_TRUE;
406 seat->ptr.invert_y = EINA_TRUE;
409 seat->ptr.swap = EINA_TRUE;
410 seat->ptr.invert_x = EINA_TRUE;
411 seat->ptr.invert_y = EINA_FALSE;
414 seat->ptr.swap = EINA_FALSE;
415 seat->ptr.invert_x = EINA_FALSE;
416 seat->ptr.invert_y = EINA_FALSE;
426 e_input_device_rotation_set(E_Input_Device *dev, unsigned int rotation)
428 E_Input_Seat *seat = NULL;
429 E_Input_Evdev *edev = NULL;
430 Eina_List *l = NULL, *l2 = NULL;
433 EINA_SAFETY_ON_NULL_RETURN(dev);
434 EINA_SAFETY_ON_NULL_RETURN(dev->seats);
436 EINA_LIST_FOREACH(dev->seats, l, seat)
438 EINA_LIST_FOREACH(e_input_seat_evdev_list_get(seat), l2, edev)
440 if (libinput_device_has_capability(edev->device,
441 LIBINPUT_DEVICE_CAP_POINTER))
443 edev->mouse.minx = edev->mouse.miny = 0;
444 e_output_size_get(e_comp_screen_primary_output_get(e_comp->e_comp_screen),
445 &edev->mouse.maxw, &edev->mouse.maxh);
447 if (rotation == 90 || rotation == 270)
449 temp = edev->mouse.minx;
450 edev->mouse.minx = edev->mouse.miny;
451 edev->mouse.miny = temp;
453 temp = edev->mouse.maxw;
454 edev->mouse.maxw = edev->mouse.maxh;
455 edev->mouse.maxh = temp;
463 _e_input_device_touch_matrix_identify(float result[6])
474 _e_input_device_touch_matrix_mulifly(float result[6], float m1[6], float m2[6])
476 result[0] = m1[0] * m2 [0] + m1[1] * m2[3];
477 result[1] = m1[0] * m2 [1] + m1[1] * m2[4];
478 result[2] = m1[0] * m2 [2] + m1[1] * m2[5] + m1[2];
479 result[3] = m1[3] * m2 [0] + m1[4] * m2[3];
480 result[4] = m1[3] * m2 [1] + m1[4] * m2[4];
481 result[5] = m1[3] * m2 [2] + m1[4] * m2[5] + m1[5];
485 _e_input_device_touch_matrix_rotation_get(float result[6], int degree, float w, float h)
487 if (w == 0.0) w = 1.0;
488 if (h == 0.0) h = 1.0;
517 _e_input_device_touch_matrix_identify(result);
520 WRN("Please input valid angle(%d)\n", degree);
525 _e_input_device_touch_matrix_translate_get(float result[6], float x, float y, float w, float h, float default_w, float default_h)
527 if (default_w == 0.0) default_w = 1.0;
528 if (default_h == 0.0) default_h = 1.0;
530 result[0] = w / default_w;
531 result[4] = h / default_h;
532 result[2] = x / default_w;
533 result[5] = y / default_h;
537 e_input_device_touch_rotation_set(E_Input_Device *dev, unsigned int rotation)
539 E_Input_Seat *seat = NULL;
540 E_Input_Evdev *edev = NULL;
541 Eina_List *l = NULL, *l2 = NULL;
542 float mat_translate[6] = {0.0, }, mat_rotation[6] = {0.0, }, result[6] = {0.0, };
543 float default_w = 0.0, default_h = 0.0;
544 Eina_Bool res = EINA_TRUE;
545 int output_w = 0, output_h = 0;
547 EINA_SAFETY_ON_NULL_RETURN_VAL(dev, EINA_FALSE);
548 EINA_SAFETY_ON_NULL_RETURN_VAL(dev->seats, EINA_FALSE);
550 e_output_size_get(e_comp_screen_primary_output_get(e_comp->e_comp_screen), &output_w, &output_h);
551 default_w = (float)output_w;
552 default_h = (float)output_h;
554 EINA_LIST_FOREACH(dev->seats, l, seat)
556 EINA_LIST_FOREACH(e_input_seat_evdev_list_get(seat), l2, edev)
558 if (edev->caps & E_INPUT_SEAT_TOUCH)
560 _e_input_device_touch_matrix_identify(mat_translate);
561 _e_input_device_touch_matrix_identify(mat_rotation);
562 _e_input_device_touch_matrix_identify(result);
564 if (edev->touch.transform.x || edev->touch.transform.y ||
565 edev->touch.transform.w || edev->touch.transform.h)
567 _e_input_device_touch_matrix_translate_get(mat_translate,
568 (float)edev->touch.transform.x,
569 (float)edev->touch.transform.y,
570 (float)edev->touch.transform.w,
571 (float)edev->touch.transform.h,
572 default_w, default_h);
576 _e_input_device_touch_matrix_rotation_get(mat_rotation, rotation, default_w, default_h);
578 _e_input_device_touch_matrix_mulifly(result, mat_translate, mat_rotation);
580 if (!e_input_evdev_touch_calibration_set(edev, result))
587 edev->touch.transform.rotation = rotation;
597 e_input_device_touch_transformation_set(E_Input_Device *dev, int offset_x, int offset_y, int w, int h)
599 E_Input_Seat *seat = NULL;
600 E_Input_Evdev *edev = NULL;
601 Eina_List *l = NULL, *l2 = NULL;
602 float mat_translate[6] = {0.0, }, mat_rotation[6] = {0.0 }, result[6] = {0.0, };
603 float default_w = 0.0, default_h = 0.0;
604 Eina_Bool res = EINA_TRUE;
605 int output_w = 0, output_h = 0;
607 EINA_SAFETY_ON_NULL_RETURN_VAL(dev, EINA_FALSE);
608 EINA_SAFETY_ON_NULL_RETURN_VAL(dev->seats, EINA_FALSE);
609 EINA_SAFETY_ON_TRUE_RETURN_VAL((w == 0) || (h == 0), EINA_FALSE);
611 e_output_size_get(e_comp_screen_primary_output_get(e_comp->e_comp_screen), &output_w, &output_h);
612 default_w = (float)output_w;
613 default_h = (float)output_h;
615 EINA_LIST_FOREACH(dev->seats, l, seat)
617 EINA_LIST_FOREACH(e_input_seat_evdev_list_get(seat), l2, edev)
619 if (edev->caps & E_INPUT_SEAT_TOUCH)
621 _e_input_device_touch_matrix_identify(mat_translate);
622 _e_input_device_touch_matrix_identify(mat_rotation);
623 _e_input_device_touch_matrix_identify(result);
625 _e_input_device_touch_matrix_translate_get(mat_translate,
626 (float)offset_x, (float)offset_y,
627 (float)w, (float)h, default_w, default_h);
629 if (edev->touch.transform.rotation)
631 _e_input_device_touch_matrix_rotation_get(mat_rotation,
632 edev->touch.transform.rotation,
633 default_w, default_h);
636 _e_input_device_touch_matrix_mulifly(result, mat_translate, mat_rotation);
638 if (!e_input_evdev_touch_calibration_set(edev, result))
645 edev->touch.transform.x = offset_x;
646 edev->touch.transform.y = offset_y;
647 edev->touch.transform.w = w;
648 edev->touch.transform.h = h;
657 e_input_device_libinput_log_handler(struct libinput *libinput EINA_UNUSED,
658 enum libinput_log_priority priority,
659 const char *format, va_list args)
661 char buf[1024] = {0,};
663 vsnprintf(buf, 1024, format, args);
666 case LIBINPUT_LOG_PRIORITY_DEBUG:
669 case LIBINPUT_LOG_PRIORITY_INFO:
672 case LIBINPUT_LOG_PRIORITY_ERROR:
681 e_input_device_input_backend_create(E_Input_Device *dev, E_Input_Libinput_Backend backend)
683 Eina_Bool res = EINA_FALSE;
685 EINA_SAFETY_ON_NULL_RETURN_VAL(dev, EINA_FALSE);
687 if (backend == E_INPUT_LIBINPUT_BACKEND_UDEV)
689 TRACE_INPUT_BEGIN(e_input_device_input_create_libinput_udev);
690 res = e_input_device_input_create_libinput_udev(dev);
693 else if (backend == E_INPUT_LIBINPUT_BACKEND_PATH)
695 TRACE_INPUT_BEGIN(e_input_device_input_create_libinput_path);
696 res = e_input_device_input_create_libinput_path(dev);
703 /* public functions */
705 e_input_device_input_create_libinput_udev(E_Input_Device *dev)
707 E_Input_Backend *input;
710 /* check for valid device */
711 EINA_SAFETY_ON_NULL_RETURN_VAL(dev, EINA_FALSE);
713 /* try to allocate space for new input structure */
714 if (!(input = calloc(1, sizeof(E_Input_Backend))))
719 /* set reference for parent device */
722 /* try to create libinput context */
724 libinput_udev_create_context(&_input_interface, input, eeze_udev_get());
725 if (!input->libinput)
727 ERR("Could not create libinput context: %m");
731 /* set libinput log priority */
732 if ((env = getenv(E_INPUT_ENV_LIBINPUT_LOG_DISABLE)) && (atoi(env) == 1))
733 libinput_log_set_handler(input->libinput, NULL);
734 else if ((env = getenv(E_INPUT_ENV_LIBINPUT_LOG_EINA_LOG)) && (atoi(env) == 1))
735 libinput_log_set_handler(input->libinput, e_input_device_libinput_log_handler);
737 libinput_log_set_priority(input->libinput, LIBINPUT_LOG_PRIORITY_INFO);
739 /* assign udev seat */
740 TRACE_INPUT_BEGIN(libinput_udev_assign_seat);
741 if (libinput_udev_assign_seat(input->libinput, dev->seat) != 0)
743 ERR("Failed to assign seat: %m");
749 /* process pending events */
750 _input_events_process(input);
752 /* enable this input */
753 if (!e_input_enable_input(input))
755 ERR("Failed to enable input");
759 /* append this input */
760 dev->inputs = eina_list_append(dev->inputs, input);
765 if (input->libinput) libinput_unref(input->libinput);
772 e_input_device_input_create_libinput_path(E_Input_Device *dev)
774 E_Input_Backend *input;
775 struct libinput_device *device;
778 Eina_Stringshare *path;
780 /* check for valid device */
781 EINA_SAFETY_ON_NULL_RETURN_VAL(dev, EINA_FALSE);
783 if ((env = getenv("PATH_DEVICES_NUM")))
784 devices_num = atoi(env);
785 if (devices_num <= 0 || devices_num >= INT_MAX)
790 INF("PATH_DEVICES_NUM : %d", devices_num);
792 /* try to allocate space for new input structure */
793 if (!(input = calloc(1, sizeof(E_Input_Backend))))
798 /* set reference for parent device */
801 /* try to create libinput context */
803 libinput_path_create_context(&_input_interface, input);
804 if (!input->libinput)
806 ERR("Could not create libinput path context: %m");
810 /* set libinput log priority */
811 if ((env = getenv(E_INPUT_ENV_LIBINPUT_LOG_DISABLE)) && (atoi(env) == 1))
812 libinput_log_set_handler(input->libinput, NULL);
813 else if ((env = getenv(E_INPUT_ENV_LIBINPUT_LOG_EINA_LOG)) && (atoi(env) == 1))
814 libinput_log_set_handler(input->libinput, e_input_device_libinput_log_handler);
816 libinput_log_set_priority(input->libinput, LIBINPUT_LOG_PRIORITY_INFO);
818 for (int i = 0; i < devices_num; i++)
820 char buf[1024] = "PATH_DEVICE_";
821 eina_convert_itoa(i + 1, buf + 12);
825 path = eina_stringshare_add(env);
826 device = libinput_path_add_device(input->libinput, path);
828 ERR("Failed to initialized device %s", path);
830 INF("libinput_path created input device %s", path);
834 /* process pending events */
835 _input_events_process(input);
837 /* enable this input */
838 if (!e_input_enable_input(input))
840 ERR("Failed to enable input");
844 /* append this input */
845 dev->inputs = eina_list_append(dev->inputs, input);
850 if (input->libinput) libinput_unref(input->libinput);
857 E_API const Eina_List *
858 e_input_devices_get(void)
860 return einput_devices;