-#include "e.h"
-#include "e_input_private.h"
+#include "e_input_intern.h"
+#include "e_input_log.h"
+#include "e_input_event.h"
+#include "e_keyrouter_intern.h"
+#include "e_devicemgr_intern.h"
+#include "e_device_intern.h"
+#include "e_comp_screen_intern.h"
+#include "e_output_intern.h"
+
+#include <glib.h>
+#include <ctype.h>
+
+#define G_LIST_GET_DATA(list) ((list) ? (((GList *)(list))->data) : NULL)
static void _device_modifiers_update(E_Input_Evdev *edev);
+static void _device_configured_size_get(E_Input_Evdev *edev, int *x, int *y, int *w, int *h);
+static void _device_output_assign(E_Input_Evdev *edev, E_Input_Seat_Capabilities cap);
void
_device_calibration_set(E_Input_Evdev *edev)
E_Output *output;
int w = 0, h = 0;
int temp;
+ E_Comp_Config *comp_conf;
+
+ if (e_comp->e_comp_screen->num_outputs > 1) //multiple outputs
+ {
+ comp_conf = e_comp_config_get();
+ if (comp_conf && (comp_conf->input_output_assign_policy == 1)) //use output-assignment policy
+ {
+ _device_output_assign(edev, E_INPUT_SEAT_POINTER);
+ _device_output_assign(edev, E_INPUT_SEAT_TOUCH);
+ }
+ }
output = e_comp_screen_primary_output_get(e_comp->e_comp_screen);
e_output_size_get(output, &w, &h);
edev->mouse.maxw = w;
edev->mouse.maxh = h;
- if (libinput_device_has_capability(edev->device, LIBINPUT_DEVICE_CAP_POINTER))
+ if (edev->caps & E_INPUT_SEAT_POINTER)
{
edev->seat->ptr.dx = (double)(w / 2);
edev->seat->ptr.dy = (double)(h / 2);
//LCOV_EXCL_START
#ifdef _F_E_INPUT_ENABLE_DEVICE_CALIBRATION_
- const char *sysname;
float cal[6];
- const char *device;
- Eina_List *devices;
if ((!libinput_device_config_calibration_has_matrix(edev->device)) ||
(libinput_device_config_calibration_get_default_matrix(edev->device, cal) != 0))
return;
- sysname = libinput_device_get_sysname(edev->device);
-
- devices = eeze_udev_find_by_subsystem_sysname("input", sysname);
- if (eina_list_count(devices) < 1) return;
-
#ifdef _F_E_INPUT_USE_WL_CALIBRATION_
const char *vals;
enum libinput_config_status status;
+ struct udev_device *udev_device = NULL;
- EINA_LIST_FREE(devices, device)
+ udev_device = libinput_device_get_udev_device(edev->device);
+ if (!udev_device)
{
- vals = eeze_udev_syspath_get_property(device, "WL_CALIBRATION");
- if ((!vals) ||
- (sscanf(vals, "%f %f %f %f %f %f",
- &cal[0], &cal[1], &cal[2], &cal[3], &cal[4], &cal[5]) != 6))
- goto cont;
+ ERR("no udev_device");
+ return;
+ }
- cal[2] /= w;
- cal[5] /= h;
+ vals = udev_device_get_property_value(udev_device, "WL_CALIBRATION");
+ if ((!vals) ||
+ (sscanf(vals, "%f %f %f %f %f %f",
+ &cal[0], &cal[1], &cal[2], &cal[3], &cal[4], &cal[5]) != 6))
+ {
+ udev_device_unref(udev_device);
+ return;
+ }
+ udev_device_unref(udev_device);
- status =
- libinput_device_config_calibration_set_matrix(edev->device, cal);
+ ELOGF("E_INPUT_EVDEV", "calibration_set cal[%lf %lf %lf %lf %lf %lf] (%d x %d)",
+ NULL, cal[0], cal[1], cal[2], cal[3], cal[4], cal[5], w, h);
- if (status != LIBINPUT_CONFIG_STATUS_SUCCESS)
- ERR("Failed to apply calibration");
+ status =
+ libinput_device_config_calibration_set_matrix(edev->device, cal);
-cont:
- eina_stringshare_del(device);
- continue;
- }
+ if (status != LIBINPUT_CONFIG_STATUS_SUCCESS)
+ ERR("Failed to apply calibration");
#endif//_F_E_INPUT_USE_WL_CALIBRATION_
#endif//_F_E_INPUT_ENABLE_DEVICE_CALIBRATION_
//LCOV_EXCL_STOP
}
static void
+_device_output_assign(E_Input_Evdev *edev, E_Input_Seat_Capabilities cap)
+{
+ int last_output_idx;
+ E_Input_Evdev *ed;
+ Eina_List *l;
+ Eina_Bool need_assign_output = EINA_FALSE;
+ const char *output_name;
+ E_Output *output;
+
+ if (!(edev->caps & cap)) return;
+ if (edev->output_name) return; //already assigned
+ if (e_comp->e_comp_screen->num_outputs <= 1) return;
+
+ last_output_idx = e_comp->e_comp_screen->num_outputs - 1;
+ EINA_LIST_FOREACH(edev->seat->devices, l, ed)
+ {
+ if (!(ed->caps & cap)) continue;
+ if (ed == edev) continue;
+ if (ed->output_name)
+ {
+ need_assign_output = EINA_FALSE;
+ break;
+ }
+ need_assign_output = EINA_TRUE;
+ }
+ if (need_assign_output)
+ {
+ output = e_output_find_by_index(last_output_idx);
+ if (!output || !output->info.connected) return;
+ output_name = e_output_output_id_get(output);
+ if (output_name) edev->output_name = eina_stringshare_add(output_name);
+ ELOGF("E_INPUT_EVDEV", "Device is assigned to output:%s", NULL, output_name);
+ }
+}
+
+static void
+_device_touch_count_update(E_Input_Evdev *edev)
+{
+ unsigned int device_touch_count = 0;
+ static unsigned int _max_device_touch_count = 0;
+
+ E_Input *ei = e_input_get();
+ EINA_SAFETY_ON_NULL_RETURN(ei);
+
+ device_touch_count = libinput_device_touch_get_touch_count(edev->device);
+
+ if (_max_device_touch_count < device_touch_count)
+ _max_device_touch_count = device_touch_count;
+
+ if (e_config->configured_max_touch.use)
+ {
+ if (_max_device_touch_count > 0 && e_config->configured_max_touch.count > _max_device_touch_count)
+ {
+ ELOGF("E_INPUT_EVDEV_TOUCH", "Touch max count(%d) must be less or equal to device's touch count(%d) !\nTouch max count has been shrinken to %d.\n",
+ NULL, e_config->configured_max_touch.count, _max_device_touch_count, _max_device_touch_count);
+ ei->touch_max_count = _max_device_touch_count;
+ }
+ else
+ {
+ if (ei->touch_max_count != e_config->configured_max_touch.count)
+ {
+ ELOGF("E_INPUT_EVDEV_TOUCH", "Touch_max_count has been updated to %d -> %d.\n",
+ NULL, ei->touch_max_count, e_config->configured_max_touch.count);
+ ei->touch_max_count = e_config->configured_max_touch.count;
+ }
+ }
+ }
+ else
+ {
+ if (ei->touch_max_count < _max_device_touch_count)
+ {
+ ELOGF("E_INPUT_EVDEV_TOUCH", "Touch_max_count has been updated to %d -> %d.\n", NULL,
+ ei->touch_max_count, _max_device_touch_count);
+ ei->touch_max_count = _max_device_touch_count;
+ }
+ }
+
+ ELOGF("E_INPUT_EVDEV_TOUCH", "Touch max count is %d.\n", NULL, ei->touch_max_count);
+}
+
+static void
_device_configure(E_Input_Evdev *edev)
{
if (libinput_device_config_tap_get_finger_count(edev->device) > 0)
return code;
}
-E_API Ecore_Device *
+EINTERN E_Device *
+e_input_evdev_get_e_device(const char *path, Ecore_Device_Class clas)
+{
+ const GList *dev_list = NULL;
+ const GList *l;
+ E_Device *dev = NULL;
+ const char *identifier;
+
+ if (!path) return NULL;
+
+ dev_list = e_device_list_get();
+ if (!dev_list) return NULL;
+
+ l = dev_list;
+ while (l)
+ {
+ dev = l->data;
+ if (!dev) continue;
+ identifier = e_device_identifier_get(dev);
+ if (!identifier) continue;
+ if ((e_device_class_get(dev) == clas) && !(strcmp(identifier, path)))
+ return dev;
+
+ l = g_list_next(l);
+ }
+
+ return NULL;
+}
+
+EINTERN Ecore_Device *
e_input_evdev_get_ecore_device(const char *path, Ecore_Device_Class clas)
{
const Eina_List *dev_list = NULL;
}
static void
+_e_input_event_mouse_relative_move_cb_free(void *data EINA_UNUSED, void *event)
+{
+ Ecore_Event_Mouse_Relative_Move *ev = event;
+
+ if (ev->dev) ecore_device_unref(ev->dev);
+
+ free(ev);
+}
+
+static void
_e_input_event_mouse_wheel_cb_free(void *data EINA_UNUSED, void *event)
{
Ecore_Event_Mouse_Wheel *ev = event;
{
Ecore_Event_Key *ev = event;
- if (ev->dev) ecore_device_unref(ev->dev);
+ if (e_input_thread_mode_get())
+ {
+ if (ev->dev) g_object_unref(ev->dev);
+ }
+ else
+ {
+ if (ev->dev) ecore_device_unref(ev->dev);
+ }
+
if (ev->data) E_FREE(ev->data);
free(ev);
char *tmp = NULL, *compose = NULL;
E_Keyrouter_Event_Data *key_data;
Ecore_Device *ecore_dev = NULL, *data;
- Eina_List *l, *l_next;
+ E_Device *e_dev = NULL, *e_dev_data;
+ Eina_List *l = NULL, *l_next = NULL;
+ GList *glist = NULL;
E_Comp_Config *comp_conf = NULL;
int *pressed_keycode = NULL, *idata = NULL;
Eina_Bool dup_found = EINA_FALSE;
+ const char *device_name = NULL;
+ Ecore_Device_Subclass device_subclas = ECORE_DEVICE_SUBCLASS_NONE;
if (!(edev = libinput_device_get_user_data(device)))
{
return;
}
- if (edev->ecore_dev) ecore_dev = edev->ecore_dev;
- else if (edev->ecore_dev_list && eina_list_count(edev->ecore_dev_list) > 0)
+ if (!e_input_thread_mode_get())
{
- EINA_LIST_FOREACH(edev->ecore_dev_list, l, data)
+ if (edev->ecore_dev) ecore_dev = edev->ecore_dev;
+ else if (edev->ecore_dev_list && eina_list_count(edev->ecore_dev_list) > 0)
{
- if (ecore_device_class_get(data) == ECORE_DEVICE_CLASS_KEYBOARD)
+ EINA_LIST_FOREACH(edev->ecore_dev_list, l, data)
{
- ecore_dev = data;
- break;
+ if (ecore_device_class_get(data) == ECORE_DEVICE_CLASS_KEYBOARD)
+ {
+ ecore_dev = data;
+ break;
+ }
}
}
+ else
+ {
+ edev->ecore_dev = e_input_evdev_get_ecore_device(edev->path, ECORE_DEVICE_CLASS_KEYBOARD);
+ ecore_dev = edev->ecore_dev;
+ }
+
+ if (!ecore_dev)
+ {
+ ERR("Failed to get source ecore device from event !\n");
+ return;
+ }
+
+ device_name = ecore_device_name_get(ecore_dev);
+ device_subclas = ecore_device_subclass_get(ecore_dev);
}
else
{
- edev->ecore_dev = e_input_evdev_get_ecore_device(edev->path, ECORE_DEVICE_CLASS_KEYBOARD);
- ecore_dev = edev->ecore_dev;
- }
+ if (edev->e_dev) e_dev = edev->e_dev;
+ else if (edev->e_dev_list && g_list_length(edev->e_dev_list) > 0)
+ {
+ glist = edev->e_dev_list;
+ while (glist)
+ {
+ e_dev_data = glist->data;
+ if (e_device_class_get(e_dev_data) == ECORE_DEVICE_CLASS_KEYBOARD)
+ {
+ e_dev = e_dev_data;
+ break;
+ }
+
+ glist = g_list_next(glist);
+ }
+ }
+ else
+ {
+ edev->e_dev = e_input_evdev_get_e_device(edev->path, ECORE_DEVICE_CLASS_KEYBOARD);
+ e_dev = edev->e_dev;
+ }
- if (!ecore_dev)
- {
- ERR("Failed to get source ecore device from event !\n");
- return;
+ if (!e_dev)
+ {
+ ERR("Failed to get source e device from event !\n");
+ return;
+ }
+
+ device_name = e_device_name_get(e_dev);
+ device_subclas = e_device_subclass_get(e_dev);
}
timestamp = libinput_event_keyboard_get_time(event);
if ((edev->seat->dev->blocked & E_INPUT_SEAT_KEYBOARD) ||
(edev->seat->dev->server_blocked & E_INPUT_SEAT_KEYBOARD))
{
+ void *blocked_client = atomic_load(&edev->seat->dev->blocked_client);
ELOGF("Key", "Press (keycode: %d, device: %s) is blocked by %p, server: 0x%x", NULL,
- code, ecore_device_name_get(ecore_dev), edev->seat->dev->blocked_client,
+ code, device_name, blocked_client,
edev->seat->dev->server_blocked);
return;
}
}
if (!dup_found)
{
+ void *blocked_client = atomic_load(&edev->seat->dev->blocked_client);
ELOGF("Key", "Release (keycode: %d, device: %s) is blocked by %p", NULL,
- code, ecore_device_name_get(ecore_dev), edev->seat->dev->blocked_client);
+ code, device_name, blocked_client);
return;
}
}
return;
}
+ e_input_keyboard_grab_key_cb func = e_input_keyboard_grab_key_handler_get();
+ if (func)
+ {
+ if (e_devicemgr_keyboard_grab_subtype_is_grabbed(device_subclas))
+ {
+ if (!e_input_thread_mode_get())
+ func(code, state, timestamp, ecore_dev);
+ else
+ func(code, state, timestamp, e_dev);
+ return;
+ }
+ }
+
xkb_state_update_key(edev->xkb.state, code,
(state ? XKB_KEY_DOWN : XKB_KEY_UP));
/* get the keysym for this code */
nsyms = xkb_key_get_syms(edev->xkb.state, code, &syms);
+
if (nsyms == 1) sym = syms[0];
/* If no keysym was found, name it "Keycode-NNN" */
_device_modifiers_update(edev);
e->modifiers = edev->xkb.modifiers;
- e->dev = ecore_device_ref(ecore_dev);
comp_conf = e_comp_config_get();
+
if (comp_conf && comp_conf->input_log_enable)
- ELOGF("Key", "%s (keyname: %s, keycode: %d, device: %s)", NULL, state?"Press":"Release", e->keyname, e->keycode, ecore_device_name_get(e->dev));
+ ELOGF("Key", "%s (keyname: %s, keycode: %d, timestamp: %u, device: %s)", NULL, state?"Press":"Release", e->keyname, e->keycode, e->timestamp, device_name);
- if (state)
- ecore_event_add(ECORE_EVENT_KEY_DOWN, e, _e_input_event_key_cb_free, NULL);
+ if (e_config->key_input_ttrace_enable)
+ {
+ TRACE_INPUT_BEGIN(ECORE_EVENT_KEY:%s:%s:%u:%lld, state ? "PRESS" : "RELEASE", e->keyname, timestamp, (long long unsigned int)libinput_event_keyboard_get_time_usec(event));
+ ELOGF("INPUT", "ECORE_EVENT_KEY:%s:%s:%u:%lld|B|", NULL, state ? "PRESS" : "RELEASE", e->keyname, timestamp, (long long unsigned int)libinput_event_keyboard_get_time_usec(event));
+ }
+
+ _e_input_key_event_list_add(e);
+
+ if (e_input_thread_mode_get())
+ {
+ e->dev = (Eo *)g_object_ref(e_dev);
+ e_input_event_add(input->event_source, state ? ECORE_EVENT_KEY_DOWN : ECORE_EVENT_KEY_UP, e, _e_input_event_key_cb_free, NULL);
+ }
else
- ecore_event_add(ECORE_EVENT_KEY_UP, e, _e_input_event_key_cb_free, NULL);
+ {
+ e->dev = ecore_device_ref(ecore_dev);
+ ecore_event_add(state ? ECORE_EVENT_KEY_DOWN : ECORE_EVENT_KEY_UP, e, _e_input_event_key_cb_free, NULL);
+ }
+
+ if (e_config->key_input_ttrace_enable)
+ {
+ TRACE_INPUT_END();
+ ELOGF("INPUT", "ECORE_EVENT_KEY|E|", NULL);
+ }
if (tmp) free(tmp);
}
Ecore_Event_Mouse_Move *ev;
Ecore_Device *ecore_dev = NULL, *data, *detent_data = NULL;
Eina_List *l;
+ int x = 0, y = 0, w = 0, h = 0;
if (!(input = edev->seat->input)) return;
+ ecore_thread_main_loop_begin();
+
if (edev->ecore_dev) ecore_dev = edev->ecore_dev;
else if (edev->ecore_dev_list && eina_list_count(edev->ecore_dev_list) > 0)
{
if (!ecore_dev)
{
ERR("Failed to get source ecore device from event !\n");
- return;
+ goto end;
}
else if ((detent_data == ecore_dev) || e_devicemgr_detent_is_detent(ecore_device_name_get(ecore_dev)))
{
/* Do not process detent device's move events. */
- return;
+ goto end;
}
if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Move)))) return;
- if (edev->seat->ptr.ix < edev->mouse.minx)
- edev->seat->ptr.dx = edev->seat->ptr.ix = edev->mouse.minx;
- else if (edev->seat->ptr.ix >= (edev->mouse.minx + edev->mouse.maxw))
- edev->seat->ptr.dx = edev->seat->ptr.ix = (edev->mouse.minx + edev->mouse.maxw - 1);
+ _device_configured_size_get(edev, &x, &y, &w, &h);
+
+ if (edev->seat->ptr.ix < x)
+ edev->seat->ptr.dx = edev->seat->ptr.ix = x;
+ else if (edev->seat->ptr.ix >= (x + w))
+ edev->seat->ptr.dx = edev->seat->ptr.ix = (x + w - 1);
- if (edev->seat->ptr.iy < edev->mouse.miny)
- edev->seat->ptr.dy = edev->seat->ptr.iy = edev->mouse.miny;
- else if (edev->seat->ptr.iy >= (edev->mouse.miny + edev->mouse.maxh))
- edev->seat->ptr.dy = edev->seat->ptr.iy = (edev->mouse.miny + edev->mouse.maxh - 1);
+ if (edev->seat->ptr.iy < y)
+ edev->seat->ptr.dy = edev->seat->ptr.iy = y;
+ else if (edev->seat->ptr.iy >= (y + h))
+ edev->seat->ptr.dy = edev->seat->ptr.iy = (y + h - 1);
edev->mouse.dx = edev->seat->ptr.dx;
edev->mouse.dy = edev->seat->ptr.dy;
ev->multi.y = ev->y;
ev->multi.root.x = ev->x;
ev->multi.root.y = ev->y;
+
ev->dev = ecore_device_ref(ecore_dev);
ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, _e_input_event_mouse_move_cb_free, NULL);
+
+end:
+ ecore_thread_main_loop_end();
}
void
}
static void
-_device_handle_pointer_motion(struct libinput_device *device, struct libinput_event_pointer *event)
+_device_pointer_relative_motion(E_Input_Evdev *edev, struct libinput_event_pointer *event, double dx[2], double dy[2])
{
- E_Input_Evdev *edev;
- double dx, dy, temp;
+ E_Input_Backend *input;
+ Ecore_Event_Mouse_Relative_Move *ev;
+ Ecore_Device *ecore_dev = NULL, *data, *detent_data = NULL;
+ Eina_List *l;
+ E_Comp_Config *comp_conf;
- if (!(edev = libinput_device_get_user_data(device)))
+ if (!(input = edev->seat->input)) return;
+
+ ecore_thread_main_loop_begin();
+
+ if (edev->ecore_dev) ecore_dev = edev->ecore_dev;
+ else if (edev->ecore_dev_list && eina_list_count(edev->ecore_dev_list) > 0)
{
- return;
+ EINA_LIST_FOREACH(edev->ecore_dev_list, l, data)
+ {
+ if (ecore_device_class_get(data) == ECORE_DEVICE_CLASS_MOUSE)
+ {
+ ecore_dev = data;
+ break;
+ }
+ else if (ecore_device_class_get(data) == ECORE_DEVICE_CLASS_NONE)
+ {
+ detent_data = data;
+ }
+ }
+ if (!ecore_dev && e_devicemgr_detent_is_detent(libinput_device_get_name(edev->device)))
+ {
+ ecore_dev = detent_data;
+ }
+ }
+ else
+ {
+ edev->ecore_dev = e_input_evdev_get_ecore_device(edev->path, ECORE_DEVICE_CLASS_MOUSE);
+ ecore_dev = edev->ecore_dev;
}
- dx = libinput_event_pointer_get_dx(event);
- dy = libinput_event_pointer_get_dy(event);
-
- if (edev->seat->ptr.swap)
+ if (!ecore_dev)
{
- temp = dx;
- dx = dy;
- dy = temp;
+ ERR("Failed to get source ecore device from event !\n");
+ goto end;
+ }
+ else if ((detent_data == ecore_dev) || e_devicemgr_detent_is_detent(ecore_device_name_get(ecore_dev)))
+ {
+ /* Do not process detent device's move events. */
+ goto end;
}
- if (edev->seat->ptr.invert_x)
- dx *= -1;
- if (edev->seat->ptr.invert_y)
- dy *= -1;
- edev->seat->ptr.dx += dx;
- edev->seat->ptr.dy += dy;
+ if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Relative_Move)))) return;
- edev->mouse.dx = edev->seat->ptr.dx;
- edev->mouse.dy = edev->seat->ptr.dy;
+ ev->window = (Ecore_Window)input->dev->window;
+ ev->event_window = (Ecore_Window)input->dev->window;
+ if (event) ev->timestamp = libinput_event_pointer_get_time(event);
- if (floor(edev->seat->ptr.dx) == edev->seat->ptr.ix &&
- floor(edev->seat->ptr.dy) == edev->seat->ptr.iy)
+ ev->modifiers = edev->xkb.modifiers;
+
+ ev->dx = (int)dx[0];
+ ev->dy = (int)dy[0];
+ ev->dx_unaccel = (int)dx[1];
+ ev->dy_unaccel = (int)dy[1];
+
+ ev->dev = ecore_device_ref(ecore_dev);
+
+ comp_conf = e_comp_config_get();
+ if (comp_conf && comp_conf->input_log_enable)
+ ELOGF("Mouse", "Relative Move (time: %d, dx: %d, dy: %d, unaccel(%d, %d) device: %s)", NULL, ev->timestamp, ev->dx, ev->dy, ev->dx_unaccel, ev->dy_unaccel, ecore_device_name_get(ev->dev));
+
+ ecore_event_add(ECORE_EVENT_MOUSE_RELATIVE_MOVE, ev, _e_input_event_mouse_relative_move_cb_free, NULL);
+
+end:
+ ecore_thread_main_loop_end();
+}
+
+static void
+_device_pointer_motion_send(E_Input_Evdev *edev, struct libinput_event_pointer *event, double dx[2], double dy[2])
+{
+ e_input_relative_motion_cb func = e_input_relative_motion_handler_get();
+ if (func)
{
- return;
+ //func(dx, dy, time_us);
+ _device_pointer_relative_motion(edev, event, dx, dy);
}
+ else
+ {
+ double seat_dx, seat_dy, temp;
+ if (edev->disable_acceleration)
+ {
+ seat_dx = dx[1];
+ seat_dy = dy[1];
+ }
+ else
+ {
+ seat_dx = dx[0];
+ seat_dy = dy[0];
+ }
- edev->seat->ptr.ix = edev->seat->ptr.dx;
- edev->seat->ptr.iy = edev->seat->ptr.dy;
+ if (edev->seat->ptr.swap)
+ {
+ temp = seat_dx;
+ seat_dx = seat_dy;
+ seat_dy = temp;
+ }
+ if (edev->seat->ptr.invert_x)
+ seat_dx *= -1;
+ if (edev->seat->ptr.invert_y)
+ seat_dy *= -1;
- if ((edev->seat->dev->blocked & E_INPUT_SEAT_POINTER) ||
- (edev->seat->dev->server_blocked & E_INPUT_SEAT_POINTER))
+ edev->seat->ptr.dx += seat_dx;
+ edev->seat->ptr.dy += seat_dy;
+
+ edev->mouse.dx = edev->seat->ptr.dx;
+ edev->mouse.dy = edev->seat->ptr.dy;
+
+ if (floor(edev->seat->ptr.dx) == edev->seat->ptr.ix &&
+ floor(edev->seat->ptr.dy) == edev->seat->ptr.iy)
+ {
+ return;
+ }
+
+ edev->seat->ptr.ix = edev->seat->ptr.dx;
+ edev->seat->ptr.iy = edev->seat->ptr.dy;
+
+ if ((edev->seat->dev->blocked & E_INPUT_SEAT_POINTER) ||
+ (edev->seat->dev->server_blocked & E_INPUT_SEAT_POINTER))
+ {
+ return;
+ }
+
+ _device_pointer_motion(edev, event);
+ }
+}
+
+static void
+_device_handle_pointer_motion(struct libinput_device *device, struct libinput_event_pointer *event)
+{
+ E_Input_Evdev *edev;
+ double delta_x[2]; /* delta_x[0] for accelerated, delta_x[1] for unaccelerated */
+ double delta_y[2]; /* delta_y[0] for accelerated, delta_y[1] for unaccelerated */
+
+ if (!(edev = libinput_device_get_user_data(device)))
{
return;
}
- _device_pointer_motion(edev, event);
+ delta_x[0] = libinput_event_pointer_get_dx(event);
+ delta_x[1] = libinput_event_pointer_get_dx_unaccelerated(event);
+ delta_y[0] = libinput_event_pointer_get_dy(event);
+ delta_y[1] = libinput_event_pointer_get_dy_unaccelerated(event);
+
+ _device_pointer_motion_send(edev, event, &delta_x[0], &delta_y[0]);
}
static void
return;
}
+ ecore_thread_main_loop_begin();
+
if (edev->ecore_dev) ecore_dev = edev->ecore_dev;
else if (edev->ecore_dev_list && eina_list_count(edev->ecore_dev_list) > 0)
{
if (!ecore_dev)
{
ERR("Failed to get source ecore device from event !\n");
- return;
+ goto end;
}
state = libinput_event_pointer_get_button_state(event);
if (button == 3) button = 2;
else if (button == 2) button = 3;
+ void *blocked_client = atomic_load(&edev->seat->dev->blocked_client);
+
if (state)
{
if ((edev->seat->dev->blocked & E_INPUT_SEAT_POINTER) ||
(edev->seat->dev->server_blocked & E_INPUT_SEAT_POINTER))
{
+
ELOGF("Mouse", "Button Press (btn: %d, device: %s) is blocked by %p, server: 0x%x", NULL,
- button, ecore_device_name_get(ecore_dev), edev->seat->dev->blocked_client,
+ button, ecore_device_name_get(ecore_dev), blocked_client,
edev->seat->dev->server_blocked);
- return;
+ goto end;
}
else
{
if (!(edev->mouse.pressed_button & (1 << button)))
{
ELOGF("Mouse", "Button Release (btn: %d, device: %s) is blocked by %p, server: 0x%x", NULL,
- button, ecore_device_name_get(ecore_dev), edev->seat->dev->blocked_client,
+ button, ecore_device_name_get(ecore_dev), blocked_client,
edev->seat->dev->server_blocked);
- return;
+ goto end;
}
edev->mouse.pressed_button &= ~(1 << button);
}
if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Button))))
{
- return;
+ goto end;
}
ev->window = (Ecore_Window)input->dev->window;
edev->mouse.prev_button = button;
}
- ev->buttons = button;
+ ev->buttons = button;
+
+ if (edev->mouse.did_double)
+ ev->double_click = 1;
+ if (edev->mouse.did_triple)
+ ev->triple_click = 1;
+
+ comp_conf = e_comp_config_get();
+ if (comp_conf && comp_conf->input_log_enable)
+ ELOGF("Mouse", "Button %s (btn: %d, device: %s)", NULL, state?"Press":"Release", button, ecore_device_name_get(ev->dev));
+
+ if (state)
+ ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, _e_input_event_mouse_button_cb_free, NULL);
+ else
+ ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, _e_input_event_mouse_button_cb_free, NULL);
+
+end:
+ ecore_thread_main_loop_end();
+}
+
+#if !LIBINPUT_HAVE_SCROLL_VALUE_V120
+static int
+_axis_value_get(struct libinput_event_pointer *pointer_event, enum libinput_pointer_axis axis)
+{
+ enum libinput_pointer_axis_source source;
+ double value = 0.0, value_discrete = 0.0;
+ int ret = 0;
+ E_Comp_Config *comp_conf = NULL;
+
+ comp_conf = e_comp_config_get();
+ source = libinput_event_pointer_get_axis_source(pointer_event);
+ switch (source)
+ {
+ case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL:
+ value_discrete = libinput_event_pointer_get_axis_value_discrete(pointer_event, axis);
+ value = libinput_event_pointer_get_axis_value(pointer_event, axis);
+ if (comp_conf && comp_conf->input_log_enable)
+ {
+ ELOGF("Axis", "SOURCE_WHEEL discrete: %lf (cf. value: %lf)", NULL, value_discrete, value);
+ }
+ ret = (int)value_discrete;
+ break;
+ case LIBINPUT_POINTER_AXIS_SOURCE_FINGER:
+ case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS:
+ value = libinput_event_pointer_get_axis_value(pointer_event, axis);
+ if (comp_conf && comp_conf->input_log_enable)
+ {
+ ELOGF("Axis", "SOURCE_FINGER/CONTINUOUS value: %lf", NULL, value);
+ }
+ if (value >= E_INPUT_FINGER_SCROLL_THRESHOLD)
+ ret = 1;
+ else if (value <= E_INPUT_FINGER_SCROLL_THRESHOLD * (-1))
+ ret = -1;
+ else
+ ret = 0;
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static void
+_device_handle_axis(struct libinput_device *device, struct libinput_event_pointer *event)
+{
+ E_Input_Evdev *edev;
+ E_Input_Backend *input;
+ Ecore_Event_Mouse_Wheel *ev;
+ uint32_t timestamp;
+ enum libinput_pointer_axis axis;
+ Ecore_Device *ecore_dev = NULL, *detent_data = NULL, *data;
+ Eina_List *l;
+ E_Comp_Config *comp_conf = NULL;
+ int direction = 0, z = 0;
+
+ if (!(edev = libinput_device_get_user_data(device)))
+ {
+ return;
+ }
+ if (!(input = edev->seat->input))
+ {
+ return;
+ }
+
+ ecore_thread_main_loop_begin();
+
+ if (edev->ecore_dev) ecore_dev = edev->ecore_dev;
+ else if (edev->ecore_dev_list && eina_list_count(edev->ecore_dev_list) > 0)
+ {
+ EINA_LIST_FOREACH(edev->ecore_dev_list, l, data)
+ {
+ if (ecore_device_class_get(data) == ECORE_DEVICE_CLASS_MOUSE)
+ {
+ ecore_dev = data;
+ break;
+ }
+ else if (ecore_device_class_get(data) == ECORE_DEVICE_CLASS_NONE)
+ {
+ detent_data = data;
+ }
+ }
+ if (!ecore_dev && e_devicemgr_detent_is_detent(libinput_device_get_name(edev->device)))
+ {
+ ecore_dev = detent_data;
+ }
+ }
+ else
+ {
+ edev->ecore_dev = e_input_evdev_get_ecore_device(edev->path, ECORE_DEVICE_CLASS_MOUSE);
+ ecore_dev = edev->ecore_dev;
+ }
+
+ if (!ecore_dev)
+ {
+ ERR("Failed to get source ecore device from event !\n");
+ goto end;
+ }
+
+ axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL;
+ if (libinput_event_pointer_has_axis(event, axis))
+ z = _axis_value_get(event, axis);
+
+ axis = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL;
+ if (libinput_event_pointer_has_axis(event, axis))
+ {
+ direction = 1;
+ z = _axis_value_get(event, axis);
+ }
+
+ if (z == 0)
+ {
+ ELOGF("Mouse", "Axis event is ignored since it has zero value", NULL);
+ goto end;
+ }
+
+ comp_conf = e_comp_config_get();
+ if (comp_conf && comp_conf->e_wheel_click_angle)
+ {
+ z = (int)(z * comp_conf->e_wheel_click_angle);
+ }
+
+ if ((edev->seat->dev->blocked & E_INPUT_SEAT_POINTER) ||
+ (edev->seat->dev->server_blocked & E_INPUT_SEAT_POINTER))
+ {
+ void *blocked_client = atomic_load(&edev->seat->dev->blocked_client);
+
+ if (detent_data)
+ ELOGF("Mouse", "Detent (direction: %d, value: %d) is blocked by %p, server: 0x%x", NULL,
+ direction, z, blocked_client, edev->seat->dev->server_blocked);
+ else
+ ELOGF("Mouse", "Wheel (direction: %d, value: %d) is blocked by %p, server: 0x%x", NULL,
+ direction, z, blocked_client, edev->seat->dev->server_blocked);
+
+ goto end;
+ }
+
+ if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Wheel))))
+ {
+ goto end;
+ }
+
+ timestamp = libinput_event_pointer_get_time(event);
+
+ ev->window = (Ecore_Window)input->dev->window;
+ ev->event_window = (Ecore_Window)input->dev->window;
+ ev->root_window = (Ecore_Window)input->dev->window;
+ ev->timestamp = timestamp;
+ ev->same_screen = 1;
+
+ _device_modifiers_update(edev);
+ ev->modifiers = edev->xkb.modifiers;
+
+ ev->x = edev->seat->ptr.ix;
+ ev->y = edev->seat->ptr.iy;
+ ev->root.x = ev->x;
+ ev->root.y = ev->y;
+ ev->z = z;
+ ev->direction = direction;
+
+ if (comp_conf && comp_conf->input_log_enable)
+ {
+ if (detent_data)
+ ELOGF("Mouse", "Detent (direction: %d, value: %d)", NULL, ev->direction, ev->z);
+ else
+ ELOGF("Mouse", "Wheel (direction: %d, value: %d)", NULL, ev->direction, ev->z);
+ }
+
- if (edev->mouse.did_double)
- ev->double_click = 1;
- if (edev->mouse.did_triple)
- ev->triple_click = 1;
+ ev->dev = ecore_device_ref(ecore_dev);
+ ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, _e_input_event_mouse_wheel_cb_free, NULL);
+
+end:
+ ecore_thread_main_loop_end();
+}
+#endif
+
+#if LIBINPUT_HAVE_SCROLL_VALUE_V120
+static int
+_scroll_value_get(struct libinput_event_pointer *pointer_event, enum libinput_pointer_axis axis, E_Input_Axis_Source source)
+{
+ double value = 0.0;
+ double value_v120 = 0.0;
+ int ret;
+ E_Comp_Config *comp_conf = NULL;
comp_conf = e_comp_config_get();
- if (comp_conf && comp_conf->input_log_enable)
- ELOGF("Mouse", "Button %s (btn: %d, device: %s)", NULL, state?"Press":"Release", button, ecore_device_name_get(ev->dev));
+ switch (source)
+ {
+ case E_INPUT_AXIS_SOURCE_WHEEL:
+ value_v120 = libinput_event_pointer_get_scroll_value_v120(pointer_event, axis);
+ value = libinput_event_pointer_get_scroll_value(pointer_event, axis);
+ if (comp_conf && comp_conf->input_log_enable)
+ {
+ ELOGF("Scroll", "SOURCE_WHEEL value_v120: %lf (cf. value: %lf)", NULL, value_v120, value);
+ }
+ if (((int)value_v120 % E_INPUT_POINTER_AXIS_DISCRETE_STEP) != 0)
+ {
+ ERR("Wheel movements should be multiples (or fractions) of 120!\n");
+ ret = 0;
+ }
+ else
+ {
+ ret = value_v120 / E_INPUT_POINTER_AXIS_DISCRETE_STEP;
+ }
+ break;
+ case E_INPUT_AXIS_SOURCE_FINGER:
+ case E_INPUT_AXIS_SOURCE_CONTINUOUS:
+ value = libinput_event_pointer_get_scroll_value(pointer_event, axis);
+ if (comp_conf && comp_conf->input_log_enable)
+ {
+ ELOGF("Scroll", "SOURCE_FINGER/CONTINUOUS value: %lf", NULL, value);
+ }
+ if (value >= E_INPUT_FINGER_SCROLL_THRESHOLD)
+ ret = 1;
+ else if (value <= E_INPUT_FINGER_SCROLL_THRESHOLD * (-1))
+ ret = -1;
+ else
+ ret = 0;
+ break;
+ default:
+ break;
+ }
- if (state)
- ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, _e_input_event_mouse_button_cb_free, NULL);
- else
- ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, _e_input_event_mouse_button_cb_free, NULL);
+ return ret;
}
static void
-_device_handle_axis(struct libinput_device *device, struct libinput_event_pointer *event)
+_device_handle_axis_v120(struct libinput_device *device, struct libinput_event_pointer *event, E_Input_Axis_Source source)
{
E_Input_Evdev *edev;
E_Input_Backend *input;
return;
}
+ ecore_thread_main_loop_begin();
+
if (edev->ecore_dev) ecore_dev = edev->ecore_dev;
else if (edev->ecore_dev_list && eina_list_count(edev->ecore_dev_list) > 0)
{
if (!ecore_dev)
{
ERR("Failed to get source ecore device from event !\n");
- return;
+ goto end;
}
axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL;
if (libinput_event_pointer_has_axis(event, axis))
- z = libinput_event_pointer_get_axis_value(event, axis);
+ z = _scroll_value_get(event, axis, source);
axis = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL;
if (libinput_event_pointer_has_axis(event, axis))
{
direction = 1;
- z = libinput_event_pointer_get_axis_value(event, axis);
+ z = _scroll_value_get(event, axis, source);
+ }
+
+ if (z == 0)
+ {
+ ELOGF("Mouse", "Scroll event is ignored since it has zero value", NULL);
+ goto end;
+ }
+
+ comp_conf = e_comp_config_get();
+ if (comp_conf && comp_conf->e_wheel_click_angle)
+ {
+ z = (int)(z * comp_conf->e_wheel_click_angle);
}
if ((edev->seat->dev->blocked & E_INPUT_SEAT_POINTER) ||
(edev->seat->dev->server_blocked & E_INPUT_SEAT_POINTER))
{
+ void *blocked_client = atomic_load(&edev->seat->dev->blocked_client);
if (detent_data)
ELOGF("Mouse", "Detent (direction: %d, value: %d) is blocked by %p, server: 0x%x", NULL,
- direction, z, edev->seat->dev->blocked_client, edev->seat->dev->server_blocked);
+ direction, z, blocked_client, edev->seat->dev->server_blocked);
else
ELOGF("Mouse", "Wheel (direction: %d, value: %d) is blocked by %p, server: 0x%x", NULL,
- direction, z, edev->seat->dev->blocked_client, edev->seat->dev->server_blocked);
- return;
+ direction, z, blocked_client, edev->seat->dev->server_blocked);
+
+ goto end;
}
if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Wheel))))
{
- return;
+ goto end;
}
timestamp = libinput_event_pointer_get_time(event);
ev->y = edev->seat->ptr.iy;
ev->root.x = ev->x;
ev->root.y = ev->y;
- ev->dev = ecore_device_ref(ecore_dev);
-
ev->z = z;
ev->direction = direction;
- comp_conf = e_comp_config_get();
if (comp_conf && comp_conf->input_log_enable)
{
if (detent_data)
ELOGF("Mouse", "Wheel (direction: %d, value: %d)", NULL, ev->direction, ev->z);
}
+ ev->dev = ecore_device_ref(ecore_dev);
ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, _e_input_event_mouse_wheel_cb_free, NULL);
+
+end:
+ ecore_thread_main_loop_end();
}
+#endif
static void
_device_handle_touch_event_send(E_Input_Evdev *edev, struct libinput_event_touch *event, int state)
if (!edev) return;
if (!(input = edev->seat->input)) return;
+ ecore_thread_main_loop_begin();
+
if (edev->ecore_dev) ecore_dev = edev->ecore_dev;
else if (edev->ecore_dev_list && eina_list_count(edev->ecore_dev_list) > 0)
{
if (!ecore_dev)
{
ERR("Failed to get source ecore device from event !\n");
- return;
+ goto end;
}
- if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Button)))) return;
+ if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Button)))) goto end;
timestamp = libinput_event_touch_get_time(event);
ev->triple_click = 1;
ecore_event_add(state, ev, _e_input_event_mouse_button_cb_free, NULL);
+
+end:
+ ecore_thread_main_loop_end();
}
static void
if (!edev) return;
if (!(input = edev->seat->input)) return;
+ ecore_thread_main_loop_begin();
+
if (edev->ecore_dev) ecore_dev = edev->ecore_dev;
else if (edev->ecore_dev_list && eina_list_count(edev->ecore_dev_list) > 0)
{
if (!ecore_dev)
{
ERR("Failed to get source ecore device from event !\n");
- return;
+ goto end;
}
- if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Move)))) return;
+ if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Move)))) goto end;
ev->window = (Ecore_Window)input->dev->window;
ev->event_window = (Ecore_Window)input->dev->window;
ev->dev = ecore_device_ref(ecore_dev);
ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, _e_input_event_mouse_move_cb_free, NULL);
+
+end:
+ ecore_thread_main_loop_end();
+}
+
+static void
+_device_handle_touch_cancel_send(E_Input_Evdev *edev, struct libinput_event_touch *event)
+{
+ E_Input_Backend *input;
+ Ecore_Event_Mouse_Button *ev;
+ uint32_t timestamp, button = 0;
+ Ecore_Device *ecore_dev = NULL, *data;
+ Eina_List *l;
+
+ if (!edev) return;
+ if (!(input = edev->seat->input)) return;
+
+ ecore_thread_main_loop_begin();
+
+ if (edev->ecore_dev) ecore_dev = edev->ecore_dev;
+ else if (edev->ecore_dev_list && eina_list_count(edev->ecore_dev_list) > 0)
+ {
+ EINA_LIST_FOREACH(edev->ecore_dev_list, l, data)
+ {
+ if (ecore_device_class_get(data) == ECORE_DEVICE_CLASS_TOUCH)
+ {
+ ecore_dev = data;
+ break;
+ }
+ }
+ }
+ else
+ {
+ edev->ecore_dev = e_input_evdev_get_ecore_device(edev->path, ECORE_DEVICE_CLASS_TOUCH);
+ ecore_dev = edev->ecore_dev;
+ }
+
+ if (!ecore_dev)
+ {
+ ERR("Failed to get source ecore device from event !\n");
+ goto end;
+ }
+
+ if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Button)))) goto end;
+
+ timestamp = libinput_event_touch_get_time(event);
+
+ ev->window = (Ecore_Window)input->dev->window;
+ ev->event_window = (Ecore_Window)input->dev->window;
+ ev->root_window = (Ecore_Window)input->dev->window;
+ ev->timestamp = timestamp;
+ ev->same_screen = 1;
+
+ ev->x = edev->seat->ptr.ix;
+ ev->y = edev->seat->ptr.iy;
+ ev->root.x = ev->x;
+ ev->root.y = ev->y;
+
+ ev->multi.device = edev->mt_slot;
+ ev->multi.radius = 1;
+ ev->multi.radius_x = 1;
+ ev->multi.radius_y = 1;
+ ev->multi.pressure = 1.0;
+ ev->multi.angle = 0.0;
+ ev->multi.x = ev->x;
+ ev->multi.y = ev->y;
+ ev->multi.root.x = ev->x;
+ ev->multi.root.y = ev->y;
+
+ edev->touch.pressed &= ~(1 << ev->multi.device);
+
+ ev->buttons = ((button & 0x00F) + 1);
+ ev->dev = ecore_device_ref(ecore_dev);
+
+ ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_CANCEL, ev, _e_input_event_mouse_button_cb_free, NULL);
+
+end:
+ ecore_thread_main_loop_end();
+}
+
+static void
+_device_configured_size_get(E_Input_Evdev *edev, int *x, int *y, int *w, int *h)
+{
+ E_Output *output = NULL;
+
+ EINA_SAFETY_ON_NULL_RETURN(edev);
+
+ if (!edev->output_configured)
+ {
+ if (edev->output_name)
+ {
+ output = e_output_find(edev->output_name);
+ if (output)
+ {
+ edev->mouse.minx = output->config.geom.x;
+ edev->mouse.miny = output->config.geom.y;
+ edev->mouse.maxw = output->config.geom.w;
+ edev->mouse.maxh = output->config.geom.h;
+ if (edev->caps & E_INPUT_SEAT_POINTER)
+ {
+ edev->seat->ptr.dx = (double)(edev->mouse.maxw / 2);
+ edev->seat->ptr.dy = (double)(edev->mouse.maxh / 2);
+ edev->seat->ptr.ix = (int)edev->seat->ptr.dx;
+ edev->seat->ptr.iy = (int)edev->seat->ptr.dy;
+ edev->mouse.dx = edev->seat->ptr.dx;
+ edev->mouse.dy = edev->seat->ptr.dy;
+ }
+ }
+ }
+
+ edev->output_configured = EINA_TRUE;
+ ELOGF("E_INPUT_EVDEV", "Device is configured by output x:%d,y:%d (w:%d, h:%d)",
+ NULL, edev->mouse.minx, edev->mouse.miny, edev->mouse.maxw, edev->mouse.maxh);
+ }
+ if (x) *x = edev->mouse.minx;
+ if (y) *y = edev->mouse.miny;
+ if (w) *w = edev->mouse.maxw;
+ if (h) *h = edev->mouse.maxh;
}
static void
_device_handle_touch_down(struct libinput_device *device, struct libinput_event_touch *event)
{
E_Input_Evdev *edev;
- int w = 0, h = 0;
+ int x = 0, y = 0, w = 0, h = 0;
E_Comp_Config *comp_conf = NULL;
if (!(edev = libinput_device_get_user_data(device)))
return;
}
- e_output_size_get(e_comp_screen_primary_output_get(e_comp->e_comp_screen), &w, &h);
+ _device_configured_size_get(edev, &x, &y, &w, &h);
edev->mouse.dx = edev->seat->ptr.ix = edev->seat->ptr.dx =
- libinput_event_touch_get_x_transformed(event, w);
+ x + libinput_event_touch_get_x_transformed(event, w);
edev->mouse.dy = edev->seat->ptr.iy = edev->seat->ptr.dy =
- libinput_event_touch_get_y_transformed(event, h);
+ y + libinput_event_touch_get_y_transformed(event, h);
edev->mt_slot = libinput_event_touch_get_slot(event);
if (edev->mt_slot < 0)
}
}
- if (edev->mt_slot < E_INPUT_MAX_SLOTS)
+ if (edev->mt_slot < e_input_touch_max_count_get())
{
edev->touch.coords[edev->mt_slot].x = edev->seat->ptr.ix;
edev->touch.coords[edev->mt_slot].y = edev->seat->ptr.iy;
if (comp_conf && comp_conf->input_log_enable)
ELOGF("Touch", "Down (id: %d, x: %d, y: %d)", NULL, edev->mt_slot, edev->seat->ptr.ix, edev->seat->ptr.iy);
- edev->touch.raw_pressed |= (1 << edev->mt_slot);
+ atomic_fetch_or(&edev->touch.raw_pressed, (1 << edev->mt_slot));
if (edev->touch.blocked)
{
+ void *blocked_client = atomic_load(&edev->seat->dev->blocked_client);
ELOGF("Touch", "Down (id: %d, x: %d, y: %d) is blocked by %p, server: 0x%x", NULL,
- edev->mt_slot, edev->seat->ptr.ix, edev->seat->ptr.iy, edev->seat->dev->blocked_client,
+ edev->mt_slot, edev->seat->ptr.ix, edev->seat->ptr.iy, blocked_client,
edev->seat->dev->server_blocked);
return;
}
_device_handle_touch_motion(struct libinput_device *device, struct libinput_event_touch *event)
{
E_Input_Evdev *edev;
- int w = 0, h = 0;
+ int x = 0, y = 0, w = 0, h = 0;
if (!(edev = libinput_device_get_user_data(device)))
{
return;
}
- e_output_size_get(e_comp_screen_primary_output_get(e_comp->e_comp_screen), &w, &h);
+ _device_configured_size_get(edev, &x, &y, &w, &h);
edev->mouse.dx = edev->seat->ptr.dx =
- libinput_event_touch_get_x_transformed(event, w);
+ x + libinput_event_touch_get_x_transformed(event, w);
edev->mouse.dy = edev->seat->ptr.dy =
- libinput_event_touch_get_y_transformed(event, h);
+ y + libinput_event_touch_get_y_transformed(event, h);
if (floor(edev->seat->ptr.dx) == edev->seat->ptr.ix &&
floor(edev->seat->ptr.dy) == edev->seat->ptr.iy)
}
}
- if (edev->mt_slot < E_INPUT_MAX_SLOTS)
+ if (edev->mt_slot < e_input_touch_max_count_get())
{
edev->touch.coords[edev->mt_slot].x = edev->seat->ptr.ix;
edev->touch.coords[edev->mt_slot].y = edev->seat->ptr.iy;
}
}
- if (edev->mt_slot < E_INPUT_MAX_SLOTS)
+ if (edev->mt_slot < e_input_touch_max_count_get())
{
edev->mouse.dx = edev->seat->ptr.dx = edev->seat->ptr.ix =
edev->touch.coords[edev->mt_slot].x;
if (comp_conf && comp_conf->input_log_enable)
ELOGF("Touch", "Up (id: %d, x: %d, y: %d)", NULL, edev->mt_slot, edev->seat->ptr.ix, edev->seat->ptr.iy);
- edev->touch.raw_pressed &= ~(1 << edev->mt_slot);
+ atomic_fetch_and(&edev->touch.raw_pressed, ~(1 << edev->mt_slot));
if (edev->touch.blocked)
{
if (!(edev->touch.pressed & (1 << edev->mt_slot)))
{
+ void *blocked_client = atomic_load(&edev->seat->dev->blocked_client);
ELOGF("Touch", "Up (id: %d, x: %d, y: %d) is blocked by %p, server(0x%x)", NULL,
- edev->mt_slot, edev->seat->ptr.ix, edev->seat->ptr.iy, edev->seat->dev->blocked_client,
+ edev->mt_slot, edev->seat->ptr.ix, edev->seat->ptr.iy, blocked_client,
edev->seat->dev->server_blocked);
+
if (edev->touch.raw_pressed == 0x0)
{
edev->touch.blocked = EINA_FALSE;
}
static void
+_device_handle_touch_cancel(struct libinput_device *device, struct libinput_event_touch *event)
+{
+ E_Input_Evdev *edev;
+ E_Comp_Config *comp_conf = NULL;
+
+ if (!(edev = libinput_device_get_user_data(device)))
+ {
+ return;
+ }
+
+ edev->mt_slot = libinput_event_touch_get_slot(event);
+ if (edev->mt_slot < 0)
+ {
+ /* FIXME: The single touch device return slot id -1
+ * But currently we have no API to distinguish multi touch or single touch
+ * After libinput 1.11 version, libinput provides get_touch_count API,
+ * so we can distinguish multi touch device or single touch device.
+ */
+ if (edev->mt_slot == -1)
+ edev->mt_slot = 0;
+ else
+ {
+ WRN("%d slot touch up events are not supported\n", edev->mt_slot);
+ return;
+ }
+ }
+
+ comp_conf = e_comp_config_get();
+ if (comp_conf && comp_conf->input_log_enable)
+ ELOGF("Touch", "cancel (id: %d, x: %d, y: %d)", NULL, edev->mt_slot, edev->seat->ptr.ix, edev->seat->ptr.iy);
+
+ _device_handle_touch_cancel_send(edev, event);
+}
+
+
+static void
_device_handle_touch_frame(struct libinput_device *device EINA_UNUSED, struct libinput_event_touch *event EINA_UNUSED)
{
/* DBG("Unhandled Touch Frame Event"); */
Eina_List *l;
E_Comp_Config *comp_conf;
+ ecore_thread_main_loop_begin();
+
if (libinput_event_touch_aux_data_get_type(event) != LIBINPUT_TOUCH_AUX_DATA_TYPE_PALM &&
libinput_event_touch_aux_data_get_value(event) > 0)
goto end;
goto end;
}
- if (!(ev = calloc(1, sizeof(Ecore_Event_Axis_Update))))goto end;
+ if (!(ev = calloc(1, sizeof(Ecore_Event_Axis_Update)))) goto end;
ev->window = (Ecore_Window)input->dev->window;
ev->event_window = (Ecore_Window)input->dev->window;
ev->naxis = 1;
}
ev->axis = axis;
- ev->dev = ecore_device_ref(ecore_dev);
comp_conf = e_comp_config_get();
if (comp_conf && comp_conf->input_log_enable)
ELOGF("Touch", "Axis (label: %d, value: %lf)", NULL, axis?axis->label:-1, axis?axis->value:0.0);
+ ev->dev = ecore_device_ref(ecore_dev);
+
ecore_event_add(ECORE_EVENT_AXIS_UPDATE, ev, _e_input_aux_data_event_free, NULL);
end:
- ;
+ ecore_thread_main_loop_end();
}
E_Input_Evdev *
{
E_Input_Evdev *edev;
E_Input_Backend *b_input;
+ const char *output_name;
EINA_SAFETY_ON_NULL_RETURN_VAL(seat, NULL);
{
libinput_device_touch_set_aux_data(device, palm_code);
}
+
+ _device_touch_count_update(edev);
+
+ edev->touch.coords = calloc(1, sizeof(E_Input_Coord)*e_input_touch_max_count_get());
+
+ if (!edev->touch.coords)
+ ERR("Failed to allocate memory for touch coords !\n");
+ }
+
+ output_name = libinput_device_get_output_name(device);
+ if (output_name)
+ {
+ eina_stringshare_replace(&edev->output_name, output_name);
+ ELOGF("E_INPUT_EVDEV", "Device has output_name:%s", NULL, output_name);
}
libinput_device_set_user_data(device, edev);
_e_input_evdev_device_destroy(E_Input_Evdev *edev)
{
Ecore_Device *dev;
-
EINA_SAFETY_ON_NULL_RETURN(edev);
+ ecore_thread_main_loop_begin();
+
if (edev->caps & E_INPUT_SEAT_KEYBOARD)
{
if (edev->xkb.state) xkb_state_unref(edev->xkb.state);
+
if (edev->xkb.keymap) xkb_map_unref(edev->xkb.keymap);
}
{
ecore_device_del(dev);
}
+
+ if (edev->e_dev) g_object_unref(edev->e_dev);
+ if (edev->e_dev_list)
+ {
+ GList *glist = edev->e_dev_list;
+ E_Device *e_dev;
+ while (glist)
+ {
+ e_dev = glist->data;
+ g_object_unref(e_dev);
+
+ glist = g_list_next(glist);
+ }
+ }
if (edev->path) eina_stringshare_del(edev->path);
if (edev->device) libinput_device_unref(edev->device);
if (edev->key_remap_hash) eina_hash_free(edev->key_remap_hash);
+ if (edev->touch.coords)
+ {
+ free(edev->touch.coords);
+ edev->touch.coords = NULL;
+ }
+ eina_stringshare_del(edev->output_name);
+
+ ecore_thread_main_loop_end();
free(edev);
}
_device_handle_button(device, libinput_event_get_pointer_event(event));
break;
case LIBINPUT_EVENT_POINTER_AXIS:
+#if !LIBINPUT_HAVE_SCROLL_VALUE_V120
_device_handle_axis(device, libinput_event_get_pointer_event(event));
+#endif
break;
+#if LIBINPUT_HAVE_SCROLL_VALUE_V120
+ case LIBINPUT_EVENT_POINTER_SCROLL_WHEEL:
+ _device_handle_axis_v120(device, libinput_event_get_pointer_event(event), E_INPUT_AXIS_SOURCE_WHEEL);
+ break;
+ case LIBINPUT_EVENT_POINTER_SCROLL_FINGER:
+ _device_handle_axis_v120(device, libinput_event_get_pointer_event(event), E_INPUT_AXIS_SOURCE_FINGER);
+ break;
+ case LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS:
+ _device_handle_axis_v120(device, libinput_event_get_pointer_event(event), E_INPUT_AXIS_SOURCE_CONTINUOUS);
+ break;
+#endif
case LIBINPUT_EVENT_TOUCH_DOWN:
_device_handle_touch_down(device, libinput_event_get_touch_event(event));
break;
case LIBINPUT_EVENT_TOUCH_UP:
_device_handle_touch_up(device, libinput_event_get_touch_event(event));
break;
+ case LIBINPUT_EVENT_TOUCH_CANCEL:
+ _device_handle_touch_cancel(device, libinput_event_get_touch_event(event));
+ break;
case LIBINPUT_EVENT_TOUCH_FRAME:
_device_handle_touch_frame(device, libinput_event_get_touch_event(event));
break;
EINTERN void
e_input_evdev_axis_size_set(E_Input_Evdev *edev, int w, int h)
{
- const char *sysname;
float cal[6];
- const char *device;
- Eina_List *devices;
const char *vals;
enum libinput_config_status status;
+ struct udev_device *udev_device = NULL;
EINA_SAFETY_ON_NULL_RETURN(edev);
EINA_SAFETY_ON_TRUE_RETURN((w == 0) || (h == 0));
(libinput_device_config_calibration_get_default_matrix(edev->device, cal) != 0))
return;
- sysname = libinput_device_get_sysname(edev->device);
-
- devices = eeze_udev_find_by_subsystem_sysname("input", sysname);
- if (eina_list_count(devices) < 1) return;
+ udev_device = libinput_device_get_udev_device(edev->device);
+ if (!udev_device)
+ {
+ ERR("no udev_device");
+ return;
+ }
- EINA_LIST_FREE(devices, device)
+ vals = udev_device_get_property_value(udev_device, "WL_CALIBRATION");
+ if ((!vals) ||
+ (sscanf(vals, "%f %f %f %f %f %f",
+ &cal[0], &cal[1], &cal[2], &cal[3], &cal[4], &cal[5]) != 6))
{
- vals = eeze_udev_syspath_get_property(device, "WL_CALIBRATION");
- if ((!vals) ||
- (sscanf(vals, "%f %f %f %f %f %f",
- &cal[0], &cal[1], &cal[2], &cal[3], &cal[4], &cal[5]) != 6))
- goto cont;
+ udev_device_unref(udev_device);
+ return;
+ }
+ udev_device_unref(udev_device);
- cal[2] /= w;
- cal[5] /= h;
+ ELOGF("E_INPUT_EVDEV", "axis_size_set cal[%lf %lf %lf %lf %lf %lf] (%d x %d)",
+ NULL, cal[0], cal[1], cal[2], cal[3], cal[4], cal[5], w, h);
- status =
- libinput_device_config_calibration_set_matrix(edev->device, cal);
+ cal[2] /= w;
+ cal[5] /= h;
- if (status != LIBINPUT_CONFIG_STATUS_SUCCESS)
- ERR("Failed to apply calibration");
+ status =
+ libinput_device_config_calibration_set_matrix(edev->device, cal);
-cont:
- eina_stringshare_del(device);
- continue;
- }
+ if (status != LIBINPUT_CONFIG_STATUS_SUCCESS)
+ ERR("Failed to apply calibration");
}
-E_API const char *
+EINTERN const char *
e_input_evdev_name_get(E_Input_Evdev *evdev)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(evdev, NULL);
return EINA_TRUE;
}
-E_API int
+EINTERN int
e_input_evdev_wheel_click_angle_get(E_Input_Evdev *dev)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(dev, -1);
return edev->touch.pressed;
}
+
+const char *
+e_input_evdev_seatname_get(E_Input_Evdev *evdev)
+{
+ struct libinput_seat *libinput_seat;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(evdev, NULL);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(evdev->device, NULL);
+
+ libinput_seat = libinput_device_get_seat(evdev->device);
+
+ return libinput_seat_get_logical_name(libinput_seat);
+}
+
+Eina_Bool
+e_input_evdev_seatname_set(E_Input_Evdev *evdev, const char *seatname)
+{
+ Eina_Bool res = EINA_FALSE;
+ E_Input_Backend *input;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(seatname, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(evdev, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(evdev->device, EINA_FALSE);
+
+ if (libinput_device_set_seat_logical_name(evdev->device, seatname) == 0)
+ {
+ input = evdev->seat->input;
+ if (!input) return EINA_FALSE;
+
+ if (libinput_dispatch(input->libinput) != 0)
+ {
+ ERR("Failed to dispatch libinput events: %m");
+
+ return EINA_FALSE;
+ }
+
+ /* process pending events */
+ _input_events_process(input);
+ res = EINA_TRUE;
+ }
+
+ return res;
+}