From 6a7589bf7805b31b532cd6acf972a3f87f65366f Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Wed, 6 Apr 2016 11:32:42 -0400 Subject: [PATCH] elput: Handle various events from libinput and pass to ecore_event Signed-off-by: Chris Michael --- src/lib/elput/elput_evdev.c | 819 ++++++++++++++++++++++++++++++++++ src/lib/elput/elput_private.h | 12 +- 2 files changed, 830 insertions(+), 1 deletion(-) diff --git a/src/lib/elput/elput_evdev.c b/src/lib/elput/elput_evdev.c index 2036d17546..6dd4da4103 100644 --- a/src/lib/elput/elput_evdev.c +++ b/src/lib/elput/elput_evdev.c @@ -28,6 +28,35 @@ _seat_frame_send(Elput_Seat *seat) ecore_event_add(ELPUT_EVENT_SEAT_FRAME, ev, NULL, NULL); } +static void +_keyboard_modifiers_update(Elput_Keyboard *kbd, Elput_Seat *seat) +{ + xkb_mod_mask_t mask; + + kbd->mods.depressed = + xkb_state_serialize_mods(kbd->state, XKB_STATE_DEPRESSED); + kbd->mods.latched = + xkb_state_serialize_mods(kbd->state, XKB_STATE_LATCHED); + kbd->mods.locked = + xkb_state_serialize_mods(kbd->state, XKB_STATE_LOCKED); + kbd->mods.group = + xkb_state_serialize_mods(kbd->state, XKB_STATE_EFFECTIVE); + + mask = (kbd->mods.depressed | kbd->mods.latched); + + seat->modifiers = 0; + if (mask & kbd->info->mods.ctrl) + seat->modifiers |= ECORE_EVENT_MODIFIER_CTRL; + if (mask & kbd->info->mods.alt) + seat->modifiers |= ECORE_EVENT_MODIFIER_ALT; + if (mask & kbd->info->mods.shift) + seat->modifiers |= ECORE_EVENT_MODIFIER_SHIFT; + if (mask & kbd->info->mods.super) + seat->modifiers |= ECORE_EVENT_MODIFIER_WIN; + if (mask & kbd->info->mods.altgr) + seat->modifiers |= ECORE_EVENT_MODIFIER_ALTGR; +} + static int _keyboard_fd_get(off_t size) { @@ -248,6 +277,245 @@ _keyboard_release(Elput_Seat *seat) } } +static void +_keyboard_key_send(Elput_Device *dev, enum libinput_key_state state, const char *keyname, const char *key, const char *compose, unsigned int code, unsigned int timestamp) +{ + Ecore_Event_Key *ev; + + ev = calloc(1, sizeof(Ecore_Event_Key) + strlen(key) + strlen(keyname) + + ((compose[0] != '\0') ? strlen(compose) : 0) + 3); + if (!ev) return; + + ev->keyname = (char *)(ev + 1); + ev->key = ev->keyname + strlen(keyname) + 1; + ev->compose = strlen(compose) ? ev->key + strlen(key) + 1 : NULL; + ev->string = ev->compose; + + strcpy((char *)ev->keyname, keyname); + strcpy((char *)ev->key, key); + if (strlen(compose)) strcpy((char *)ev->compose, compose); + + /* ev->string = ev->compose; */ + ev->keycode = code; + ev->modifiers = dev->seat->modifiers; + ev->timestamp = timestamp; + ev->same_screen = 1; + + ev->window = dev->window; + ev->event_window = dev->window; + ev->root_window = dev->window; + + if (state == LIBINPUT_KEY_STATE_PRESSED) + ecore_event_add(ECORE_EVENT_KEY_DOWN, ev, NULL, NULL); + else + ecore_event_add(ECORE_EVENT_KEY_UP, ev, NULL, NULL); +} + +static void +_keyboard_keymap_send(Elput_Keyboard_Info *info) +{ + Elput_Event_Keymap_Send *ev; + + ev = calloc(1, sizeof(Elput_Event_Keymap_Send)); + if (!ev) return; + + ev->fd = info->keymap.fd; + ev->size = info->keymap.size; + ev->format = XKB_KEYMAP_FORMAT_TEXT_V1; + + ecore_event_add(ELPUT_EVENT_KEYMAP_SEND, ev, NULL, NULL); +} + +static void +_keyboard_modifiers_send(Elput_Keyboard *kbd) +{ + Elput_Event_Modifiers_Send *ev; + + ev = calloc(1, sizeof(Elput_Event_Modifiers_Send)); + if (!ev) return; + + ev->depressed = kbd->mods.depressed; + ev->latched = kbd->mods.latched; + ev->locked = kbd->mods.locked; + ev->group = kbd->mods.group; + + ecore_event_add(ELPUT_EVENT_MODIFIERS_SEND, ev, NULL, NULL); +} + +static void +_keyboard_keymap_update(Elput_Seat *seat) +{ + Elput_Keyboard *kbd; + Elput_Keyboard_Info *info; + struct xkb_state *state; + xkb_mod_mask_t latched, locked; + + kbd = _evdev_keyboard_get(seat); + if (!kbd) return; + + info = _keyboard_info_create(kbd->pending_map, kbd->external_map); + xkb_keymap_unref(kbd->pending_map); + kbd->pending_map = NULL; + + if (!info) return; + + state = xkb_state_new(info->keymap.map); + if (!state) + { + _keyboard_info_destroy(info, kbd->external_map); + return; + } + + latched = xkb_state_serialize_mods(kbd->state, XKB_STATE_MODS_LATCHED); + locked = xkb_state_serialize_mods(kbd->state, XKB_STATE_MODS_LOCKED); + xkb_state_update_mask(state, 0, latched, locked, 0, 0, 0); + + _keyboard_info_destroy(kbd->info, kbd->external_map); + kbd->info = info; + + xkb_state_unref(kbd->state); + kbd->state = state; + + _keyboard_modifiers_update(kbd, seat); + _keyboard_keymap_send(kbd->info); + + if ((!latched) && (!locked)) return; + + _keyboard_modifiers_send(kbd); +} + +static int +_keyboard_keysym_translate(xkb_keysym_t keysym, unsigned int modifiers, char *buffer, int bytes) +{ + unsigned long hbytes = 0; + unsigned char c; + + if (!keysym) return 0; + hbytes = (keysym >> 8); + + if (!(bytes && + ((hbytes == 0) || + ((hbytes == 0xFF) && + (((keysym >= XKB_KEY_BackSpace) && (keysym <= XKB_KEY_Clear)) || + (keysym == XKB_KEY_Return) || (keysym == XKB_KEY_Escape) || + (keysym == XKB_KEY_KP_Space) || (keysym == XKB_KEY_KP_Tab) || + (keysym == XKB_KEY_KP_Enter) || + ((keysym >= XKB_KEY_KP_Multiply) && (keysym <= XKB_KEY_KP_9)) || + (keysym == XKB_KEY_KP_Equal) || (keysym == XKB_KEY_Delete)))))) + return 0; + + if (keysym == XKB_KEY_KP_Space) + c = (XKB_KEY_space & 0x7F); + else if (hbytes == 0xFF) + c = (keysym & 0x7F); + else + c = (keysym & 0xFF); + + if (modifiers & ECORE_EVENT_MODIFIER_CTRL) + { + if (((c >= '@') && (c < '\177')) || c == ' ') + c &= 0x1F; + else if (c == '2') + c = '\000'; + else if ((c >= '3') && (c <= '7')) + c -= ('3' - '\033'); + else if (c == '8') + c = '\177'; + else if (c == '/') + c = '_' & 0x1F; + } + buffer[0] = c; + return 1; +} + +static void +_keyboard_key(struct libinput_device *idevice, struct libinput_event_keyboard *event) +{ + Elput_Device *dev; + Elput_Keyboard *kbd; + enum libinput_key_state state; + xkb_keysym_t sym = XKB_KEY_NoSymbol; + const xkb_keysym_t *syms; + unsigned int code = 0; + unsigned int nsyms; + unsigned int timestamp; + char key[256], keyname[256], buffer[256]; + char *tmp = NULL, *compose = NULL; + int count; + + dev = libinput_device_get_user_data(idevice); + if (!dev) return; + + kbd = _evdev_keyboard_get(dev->seat); + if (!kbd) return; + + state = libinput_event_keyboard_get_key_state(event); + count = libinput_event_keyboard_get_seat_key_count(event); + + /* Ignore key events that are not seat wide state changes. */ + if (((state == LIBINPUT_KEY_STATE_PRESSED) && (count != 1)) || + ((state == LIBINPUT_KEY_STATE_RELEASED) && (count != 0))) + return; + + code = libinput_event_keyboard_get_key(event) + 8; + timestamp = libinput_event_keyboard_get_time(event); + + if (state == LIBINPUT_KEY_STATE_PRESSED) + xkb_state_update_key(kbd->state, code, XKB_KEY_DOWN); + else + xkb_state_update_key(kbd->state, code, XKB_KEY_UP); + + nsyms = xkb_key_get_syms(kbd->state, code, &syms); + if (nsyms == 1) sym = syms[0]; + + memset(key, 0, sizeof(key)); + xkb_keysym_get_name(sym, key, sizeof(key)); + + memset(keyname, 0, sizeof(keyname)); + memcpy(keyname, key, sizeof(keyname)); + + if (keyname[0] == '\0') + snprintf(keyname, sizeof(keyname), "Keycode-%u", code); + + if (xkb_state_mod_index_is_active(kbd->state, kbd->info->mods.shift, + XKB_STATE_MODS_EFFECTIVE)) + { + if (keyname[0] != '\0') + keyname[0] = tolower(keyname[0]); + } + + _keyboard_modifiers_update(kbd, dev->seat); + + memset(buffer, 0, sizeof(buffer)); + if (_keyboard_keysym_translate(sym, dev->seat->modifiers, + buffer, sizeof(buffer))) + { + compose = eina_str_convert("ISO8859-1", "UTF-8", buffer); + if (!compose) + { + ERR("Ecore_Drm2 cannot convert input key string '%s' to UTF-8. " + "Is Eina built with iconv support?", buffer); + } + else + tmp = compose; + } + + if (!compose) compose = buffer; + + _keyboard_key_send(dev, state, keyname, key, compose, code, timestamp); + + if (tmp) free(tmp); + + if ((kbd->pending_map) && (count == 0)) + _keyboard_keymap_update(dev->seat); + + if (state == LIBINPUT_KEY_STATE_PRESSED) + { + kbd->grab.key = code; + kbd->grab.timestamp = timestamp; + } +} + static Elput_Pointer * _pointer_create(Elput_Seat *seat) { @@ -348,6 +616,521 @@ _touch_release(Elput_Seat *seat) } } +static void +_pointer_motion_send(Elput_Device *edev) +{ + Elput_Pointer *ptr; + Elput_Keyboard *kbd; + Elput_Touch *touch; + Ecore_Event_Mouse_Move *ev; + double x, y; + + ptr = _evdev_pointer_get(edev->seat); + if (!ptr) return; + + ev = calloc(1, sizeof(Ecore_Event_Mouse_Move)); + if (!ev) return; + + x = ptr->x; + y = ptr->y; + + if (x < ptr->minx) + x = ptr->minx; + else if (x >= ptr->minx + ptr->maxw) + x = ptr->minx + ptr->maxw - 1; + + if (y < ptr->miny) + y = ptr->miny; + else if (y >= ptr->miny + ptr->maxh) + y = ptr->miny + ptr->maxh - 1; + + ev->window = edev->window; + ev->event_window = edev->window; + ev->root_window = edev->window; + ev->timestamp = ptr->timestamp; + ev->same_screen = 1; + + ev->x = x; + ev->y = y; + ev->root.x = x; + ev->root.y = y; + + kbd = _evdev_keyboard_get(edev->seat); + if (kbd) _keyboard_modifiers_update(kbd, edev->seat); + + ev->modifiers = edev->seat->modifiers; + + touch = _evdev_touch_get(edev->seat); + if (touch) ev->multi.device = touch->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; + + ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, NULL, NULL); +} + +static Eina_Bool +_pointer_motion(struct libinput_device *idev, struct libinput_event_pointer *event) +{ + Elput_Device *edev; + Elput_Pointer *ptr; + double x, y; + + edev = libinput_device_get_user_data(idev); + if (!edev) return EINA_FALSE; + + ptr = _evdev_pointer_get(edev->seat); + if (!ptr) return EINA_FALSE; + + x = ptr->x + libinput_event_pointer_get_dx(event); + y = ptr->y + libinput_event_pointer_get_dy(event); + + if (x < ptr->minx) + x = ptr->minx; + else if (x >= ptr->minx + ptr->maxw) + x = ptr->minx + ptr->maxw - 1; + + if (y < ptr->miny) + y = ptr->miny; + else if (y >= ptr->miny + ptr->maxh) + y = ptr->miny + ptr->maxh - 1; + + ptr->x = x; + ptr->y = y; + ptr->timestamp = libinput_event_pointer_get_time(event); + + _pointer_motion_send(edev); + + return EINA_TRUE; +} + +static Eina_Bool +_pointer_motion_abs(struct libinput_device *idev, struct libinput_event_pointer *event) +{ + Elput_Device *edev; + Elput_Pointer *ptr; + + edev = libinput_device_get_user_data(idev); + if (!edev) return EINA_FALSE; + + ptr = _evdev_pointer_get(edev->seat); + if (!ptr) return EINA_FALSE; + + ptr->x = libinput_event_pointer_get_absolute_x_transformed(event, edev->ow); + ptr->y = libinput_event_pointer_get_absolute_y_transformed(event, edev->oh); + ptr->timestamp = libinput_event_pointer_get_time(event); + + /* TODO: these needs to run a matrix transform based on output */ + + _pointer_motion_send(edev); + + return EINA_TRUE; +} + +static void +_pointer_button_send(Elput_Device *edev, enum libinput_button_state state) +{ + Elput_Pointer *ptr; + Elput_Keyboard *kbd; + Elput_Touch *touch; + Ecore_Event_Mouse_Button *ev; + + ptr = _evdev_pointer_get(edev->seat); + if (!ptr) return; + + ev = calloc(1, sizeof(Ecore_Event_Mouse_Button)); + if (!ev) return; + + ev->window = edev->window; + ev->event_window = edev->window; + ev->root_window = edev->window; + ev->timestamp = ptr->timestamp; + ev->same_screen = 1; + + ev->x = ptr->x; + ev->y = ptr->y; + ev->root.x = ptr->x; + ev->root.y = ptr->y; + + touch = _evdev_touch_get(edev->seat); + if (touch) ev->multi.device = touch->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; + + ev->buttons = ptr->buttons; + + ev->double_click = ptr->mouse.double_click; + ev->triple_click = ptr->mouse.triple_click; + + kbd = _evdev_keyboard_get(edev->seat); + if (kbd) + _keyboard_modifiers_update(kbd, edev->seat); + ev->modifiers = edev->seat->modifiers; + + if (state) + ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL); + else + ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL); +} + +static Eina_Bool +_pointer_button(struct libinput_device *idev, struct libinput_event_pointer *event) +{ + Elput_Device *edev; + Elput_Pointer *ptr; + int count; + enum libinput_button_state state; + unsigned int btn; + + edev = libinput_device_get_user_data(idev); + if (!edev) return EINA_FALSE; + + ptr = _evdev_pointer_get(edev->seat); + if (!ptr) return EINA_FALSE; + + state = libinput_event_pointer_get_button_state(event); + count = libinput_event_pointer_get_seat_button_count(event); + + /* Ignore button events that are not seat wide state changes. */ + if (((state == LIBINPUT_BUTTON_STATE_PRESSED) && (count != 1)) || + ((state == LIBINPUT_BUTTON_STATE_RELEASED) && (count != 0))) + return EINA_FALSE; + + btn = libinput_event_pointer_get_button(event); + + btn = ((btn & 0x00F) + 1); + if (btn == 3) btn = 2; + else if (btn == 2) btn = 3; + + ptr->buttons = btn; + ptr->timestamp = libinput_event_pointer_get_time(event); + + if (state) + { + unsigned int current; + + current = ptr->timestamp; + ptr->mouse.double_click = EINA_FALSE; + ptr->mouse.triple_click = EINA_FALSE; + + if (((current - ptr->mouse.prev_time) <= ptr->mouse.threshold) && + (btn == ptr->mouse.prev_button)) + { + ptr->mouse.double_click = EINA_TRUE; + if (((current - ptr->mouse.last_time) <= + (2 * ptr->mouse.threshold)) && + (btn == ptr->mouse.last_button)) + { + ptr->mouse.triple_click = EINA_TRUE; + ptr->mouse.prev_time = 0; + ptr->mouse.last_time = 0; + current = 0; + } + } + + ptr->mouse.last_time = ptr->mouse.prev_time; + ptr->mouse.prev_time = current; + ptr->mouse.last_button = ptr->mouse.prev_button; + ptr->mouse.prev_button = ptr->buttons; + } + + _pointer_button_send(edev, state); + + return EINA_TRUE; +} + +static void +_pointer_axis_send(Elput_Device *dev, int direction, int value) +{ + Elput_Pointer *ptr; + Elput_Keyboard *kbd; + Ecore_Event_Mouse_Wheel *ev; + + ptr = _evdev_pointer_get(dev->seat); + if (!ptr) return; + + ev = calloc(1, sizeof(Ecore_Event_Mouse_Wheel)); + if (!ev) return; + + ev->window = dev->window; + ev->event_window = dev->window; + ev->root_window = dev->window; + ev->timestamp = ptr->timestamp; + ev->same_screen = 1; + + ev->x = ptr->x; + ev->y = ptr->y; + ev->root.x = ptr->x; + ev->root.y = ptr->y; + + ev->z = value; + ev->direction = direction; + + kbd = _evdev_keyboard_get(dev->seat); + if (kbd) _keyboard_modifiers_update(kbd, dev->seat); + + ev->modifiers = dev->seat->modifiers; + + ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, NULL, NULL); +} + +static double +_pointer_axis_value(struct libinput_event_pointer *event, enum libinput_pointer_axis axis) +{ + enum libinput_pointer_axis_source source; + double val = 0.0; + + source = libinput_event_pointer_get_axis_source(event); + switch (source) + { + case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL: + val = 10 * libinput_event_pointer_get_axis_value_discrete(event, axis); + break; + case LIBINPUT_POINTER_AXIS_SOURCE_FINGER: + case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS: + val = libinput_event_pointer_get_axis_value(event, axis); + break; + } + + return val; +} + +static Eina_Bool +_pointer_axis(struct libinput_device *idevice, struct libinput_event_pointer *event) +{ + Elput_Device *dev; + Elput_Pointer *ptr; + enum libinput_pointer_axis axis; + Eina_Bool vert = EINA_FALSE, horiz = EINA_FALSE; + int dir = 0, val = 0; + + dev = libinput_device_get_user_data(idevice); + if (!dev) return EINA_FALSE; + + ptr = _evdev_pointer_get(dev->seat); + if (!ptr) return EINA_FALSE; + +#ifdef LIBINPUT_HIGHER_08 + vert = + libinput_event_pointer_has_axis(event, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); + horiz = + libinput_event_pointer_has_axis(event, + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); + if ((!vert) && (!horiz)) return EINA_FALSE; + + if (vert) + { + axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL; + val = _pointer_axis_value(event, axis); + } + + if (horiz) + { + axis = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL; + val = _pointer_axis_value(event, axis); + dir = 1; + } + +#else + axis = libinput_event_pointer_get_axis(event); + if (axis == LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL) dir = 1; + val = libinput_event_pointer_get_axis_value(event); +#endif + + ptr->timestamp = libinput_event_pointer_get_time(event); + + _pointer_axis_send(dev, dir, val); + + return EINA_TRUE; +} + +static void +_touch_event_send(Elput_Device *dev, struct libinput_event_touch *event, int type) +{ + Elput_Touch *touch; + Ecore_Event_Mouse_Button *ev; + unsigned int btn = 0; + + touch = _evdev_touch_get(dev->seat); + if (!touch) return; + + ev = calloc(1, sizeof(Ecore_Event_Mouse_Button)); + if (!ev) return; + + ev->window = dev->window; + ev->event_window = dev->window; + ev->root_window = dev->window; + ev->timestamp = libinput_event_touch_get_time(event); + ev->same_screen = 1; + + ev->x = touch->x; + ev->y = touch->y; + ev->root.x = touch->x; + ev->root.y = touch->y; + + ev->modifiers = dev->seat->modifiers; + + ev->multi.device = touch->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; + + btn = ((btn & 0x00F) + 1); + if (btn == 3) btn = 2; + else if (btn == 2) btn = 3; + ev->buttons = btn; + + ecore_event_add(type, ev, NULL, NULL); +} + +static void +_touch_down(struct libinput_device *idevice, struct libinput_event_touch *event) +{ + Elput_Device *dev; + Elput_Touch *touch; + unsigned int timestamp; + int slot; + + dev = libinput_device_get_user_data(idevice); + if (!dev) return; + + touch = _evdev_touch_get(dev->seat); + if (!touch) return; + + slot = libinput_event_touch_get_seat_slot(event); + timestamp = libinput_event_touch_get_time(event); + + touch->x = libinput_event_touch_get_x_transformed(event, dev->ow); + touch->y = libinput_event_touch_get_y_transformed(event, dev->oh); + + /* TODO: these needs to run a matrix transform based on output */ + /* _ecore_drm2_output_coordinate_transform(dev->output, */ + /* touch->x, touch->y, */ + /* &touch->x, &touch->y); */ + + if (slot == touch->grab.id) + { + touch->grab.x = touch->x; + touch->grab.y = touch->y; + } + + touch->slot = slot; + touch->points++; + + _touch_event_send(dev, event, ECORE_EVENT_MOUSE_BUTTON_DOWN); + + if (touch->points == 1) + { + touch->grab.id = slot; + touch->grab.x = touch->x; + touch->grab.y = touch->y; + touch->grab.timestamp = timestamp; + } +} + +static void +_touch_up(struct libinput_device *idevice, struct libinput_event_touch *event) +{ + Elput_Device *dev; + Elput_Touch *touch; + + dev = libinput_device_get_user_data(idevice); + if (!dev) return; + + touch = _evdev_touch_get(dev->seat); + if (!touch) return; + + touch->points--; + touch->slot = libinput_event_touch_get_seat_slot(event); + + _touch_event_send(dev, event, ECORE_EVENT_MOUSE_BUTTON_UP); +} + +static void +_touch_motion_send(Elput_Device *dev, struct libinput_event_touch *event) +{ + Elput_Touch *touch; + Ecore_Event_Mouse_Move *ev; + + touch = _evdev_touch_get(dev->seat); + if (!touch) return; + + ev = calloc(1, sizeof(Ecore_Event_Mouse_Move)); + if (!ev) return; + + ev->window = dev->window; + ev->event_window = dev->window; + ev->root_window = dev->window; + ev->timestamp = libinput_event_touch_get_time(event); + ev->same_screen = 1; + + ev->x = touch->x; + ev->y = touch->y; + ev->root.x = touch->x; + ev->root.y = touch->y; + + ev->modifiers = dev->seat->modifiers; + + ev->multi.device = touch->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; + + ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, NULL, NULL); +} + +static void +_touch_motion(struct libinput_device *idevice, struct libinput_event_touch *event) +{ + Elput_Device *dev; + Elput_Touch *touch; + + dev = libinput_device_get_user_data(idevice); + if (!dev) return; + + touch = _evdev_touch_get(dev->seat); + if (!touch) return; + + touch->x = libinput_event_touch_get_x_transformed(event, dev->ow); + touch->y = libinput_event_touch_get_y_transformed(event, dev->oh); + + /* TODO: these needs to run a matrix transform based on output */ + /* _ecore_drm2_output_coordinate_transform(dev->output, */ + /* touch->x, touch->y, */ + /* &touch->x, &touch->y); */ + + touch->slot = libinput_event_touch_get_seat_slot(event); + + _touch_motion_send(dev, event); +} + int _evdev_event_process(struct libinput_event *event) { @@ -359,20 +1142,32 @@ _evdev_event_process(struct libinput_event *event) switch (libinput_event_get_type(event)) { case LIBINPUT_EVENT_KEYBOARD_KEY: + _keyboard_key(idev, libinput_event_get_keyboard_event(event)); break; case LIBINPUT_EVENT_POINTER_MOTION: + frame = + _pointer_motion(idev, libinput_event_get_pointer_event(event)); break; case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE: + frame = + _pointer_motion_abs(idev, libinput_event_get_pointer_event(event)); break; case LIBINPUT_EVENT_POINTER_BUTTON: + frame = + _pointer_button(idev, libinput_event_get_pointer_event(event)); break; case LIBINPUT_EVENT_POINTER_AXIS: + frame = + _pointer_axis(idev, libinput_event_get_pointer_event(event)); break; case LIBINPUT_EVENT_TOUCH_DOWN: + _touch_down(idev, libinput_event_get_touch_event(event)); break; case LIBINPUT_EVENT_TOUCH_MOTION: + _touch_motion(idev, libinput_event_get_touch_event(event)); break; case LIBINPUT_EVENT_TOUCH_UP: + _touch_up(idev, libinput_event_get_touch_event(event)); break; case LIBINPUT_EVENT_TOUCH_FRAME: default: @@ -487,3 +1282,27 @@ _evdev_touch_destroy(Elput_Touch *touch) /* FIXME: destroy any resources inside touch structure */ free(touch); } + +Elput_Pointer * +_evdev_pointer_get(Elput_Seat *seat) +{ + if (!seat) return NULL; + if (seat->count.ptr) return seat->ptr; + return NULL; +} + +Elput_Keyboard * +_evdev_keyboard_get(Elput_Seat *seat) +{ + if (!seat) return NULL; + if (seat->count.kbd) return seat->kbd; + return NULL; +} + +Elput_Touch * +_evdev_touch_get(Elput_Seat *seat) +{ + if (!seat) return NULL; + if (seat->count.touch) return seat->touch; + return NULL; +} diff --git a/src/lib/elput/elput_private.h b/src/lib/elput/elput_private.h index 4c1b7f1c8e..8dc2752185 100644 --- a/src/lib/elput/elput_private.h +++ b/src/lib/elput/elput_private.h @@ -143,7 +143,7 @@ struct _Elput_Pointer unsigned int timestamp; int minx, miny; - int maxx, maxy; + int maxw, maxh; int hotx, hoty; struct @@ -190,6 +190,8 @@ struct _Elput_Seat int kbd, ptr, touch; } count; + unsigned int modifiers; + Elput_Keyboard *kbd; Elput_Pointer *ptr; Elput_Touch *touch; @@ -201,6 +203,10 @@ struct _Elput_Device { Elput_Seat *seat; + /* TODO: we will need an API to set this */ + uint32_t window; + uint32_t ow, oh; + const char *path; const char *output_name; struct libinput_device *device; @@ -236,6 +242,10 @@ void _evdev_keyboard_destroy(Elput_Keyboard *kbd); void _evdev_pointer_destroy(Elput_Pointer *ptr); void _evdev_touch_destroy(Elput_Touch *touch); +Elput_Pointer *_evdev_pointer_get(Elput_Seat *seat); +Elput_Keyboard *_evdev_keyboard_get(Elput_Seat *seat); +Elput_Touch *_evdev_touch_get(Elput_Seat *seat); + extern Elput_Interface _logind_interface; #endif