devilhorns pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=7d8059e4c51d4fe7863a6691b9fe15b27ad2d59e
commit 7d8059e4c51d4fe7863a6691b9fe15b27ad2d59e Author: Chris Michael <[email protected]> Date: Tue Mar 11 08:41:42 2014 +0000 ecore-drm: Add code to handle mouse input @feature: Add support in ecore-drm for handling mouse movement, wheel, and buttons. This adds code to pass mouse events from linux input to ecore by raising ecore_events (ecore_event_add). Signed-off-by: Chris Michael <[email protected]> --- src/lib/ecore_drm/ecore_drm_evdev.c | 178 ++++++++++++++++++++++++++++++++++-- 1 file changed, 168 insertions(+), 10 deletions(-) diff --git a/src/lib/ecore_drm/ecore_drm_evdev.c b/src/lib/ecore_drm/ecore_drm_evdev.c index 4c52104..cdc3437 100644 --- a/src/lib/ecore_drm/ecore_drm_evdev.c +++ b/src/lib/ecore_drm/ecore_drm_evdev.c @@ -72,6 +72,10 @@ _device_configure(Ecore_Drm_Evdev *edev) { DBG("Input device %s is a pointer", edev->name); edev->seat_caps |= EVDEV_SEAT_POINTER; + + /* FIXME: make this configurable */ + edev->mouse.threshold = 0.25; + ret = EINA_TRUE; } @@ -345,7 +349,7 @@ _device_notify_key(Ecore_Drm_Evdev *dev, struct input_event *event, unsigned int e->event_window = (Ecore_Window)input->dev->window; e->root_window = (Ecore_Window)input->dev->window; e->timestamp = timestamp; - /* e->same_screen = 1; */ + e->same_screen = 1; _device_modifiers_update(dev); e->modifiers = dev->xkb.modifiers; @@ -354,25 +358,149 @@ _device_notify_key(Ecore_Drm_Evdev *dev, struct input_event *event, unsigned int ecore_event_add(ECORE_EVENT_KEY_DOWN, e, NULL, NULL); else ecore_event_add(ECORE_EVENT_KEY_UP, e, NULL, NULL); +} + +static void +_device_notify_motion(Ecore_Drm_Evdev *dev, unsigned int timestamp) +{ + Ecore_Drm_Input *input; + Ecore_Event_Mouse_Move *ev; + + if (!(input = dev->seat->input)) return; + if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Move)))) return; + + 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; + + /* NB: Commented out. This borks mouse movement if no key has been + * pressed yet due to 'state' not being set */ +// _device_modifiers_update(dev); + ev->modifiers = dev->xkb.modifiers; + + ev->x = dev->mouse.x; + ev->y = dev->mouse.y; + ev->root.x = ev->x; + ev->root.y = ev->y; + + ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, NULL, NULL); +} + +static void +_device_notify_wheel(Ecore_Drm_Evdev *dev, struct input_event *event, unsigned int timestamp) +{ + Ecore_Drm_Input *input; + Ecore_Event_Mouse_Wheel *ev; + + if (!(input = dev->seat->input)) return; + if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Wheel)))) return; + + 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; + + /* NB: Commented out. This borks mouse wheel if no key has been + * pressed yet due to 'state' not being set */ +// _device_modifiers_update(dev); + ev->modifiers = dev->xkb.modifiers; + + ev->x = dev->mouse.x; + ev->y = dev->mouse.y; + ev->root.x = ev->x; + ev->root.y = ev->y; + if (event->value == REL_HWHEEL) ev->direction = 1; + ev->z = event->value; + + ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, NULL, NULL); +} + +static void +_device_notify_button(Ecore_Drm_Evdev *dev, struct input_event *event, unsigned int timestamp) +{ + Ecore_Drm_Input *input; + Ecore_Event_Mouse_Button *ev; + int button; + + if (!(input = dev->seat->input)) return; + if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Button)))) return; + + 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; + + /* NB: Commented out. This borks mouse button if no key has been + * pressed yet due to 'state' not being set */ +// _device_modifiers_update(dev); + ev->modifiers = dev->xkb.modifiers; - if ((event->code >= KEY_ESC) && (event->code <= KEY_COMPOSE)) + ev->x = dev->mouse.x; + ev->y = dev->mouse.y; + ev->root.x = ev->x; + ev->root.y = ev->y; + + button = ((event->code & 0x00F) + 1); + + /* swap buttons 2 & 3 so behaviour is like X */ + if (button == 3) button = 2; + else if (button == 2) button = 3; + + if (event->value) { - /* ignore key repeat */ - if (event->value == 2) + unsigned int current; + + current = timestamp; + dev->mouse.did_double = EINA_FALSE; + dev->mouse.did_triple = EINA_FALSE; + + if (((current - dev->mouse.prev) <= dev->mouse.threshold) && + (button == dev->mouse.prev_button)) { - DBG("\tKey Repeat"); + dev->mouse.did_double = EINA_TRUE; + if (((current - dev->mouse.last) <= (2 * dev->mouse.threshold)) && + (button == dev->mouse.last_button)) + { + dev->mouse.did_triple = EINA_TRUE; + dev->mouse.prev = 0; + dev->mouse.last = 0; + current = 0; + } } + + dev->mouse.last = dev->mouse.prev; + dev->mouse.prev = current; + dev->mouse.last_button = dev->mouse.prev_button; + dev->mouse.prev_button = button; } + + ev->buttons = button; + if (dev->mouse.did_double) + ev->double_click = 1; + if (dev->mouse.did_triple) + ev->triple_click = 1; + + if (event->value) + ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL); + else + ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL); } static void -_device_process_flush(Ecore_Drm_Evdev *dev, unsigned int timestamp EINA_UNUSED) +_device_process_flush(Ecore_Drm_Evdev *dev, unsigned int timestamp) { switch (dev->pending_event) { case EVDEV_NONE: return; case EVDEV_RELATIVE_MOTION: + _device_notify_motion(dev, timestamp); + /* dev->mouse.x = 0; */ + /* dev->mouse.y = 0; */ goto out; break; case EVDEV_ABSOLUTE_MT_DOWN: @@ -402,6 +530,13 @@ out: static void _device_process_key(Ecore_Drm_Evdev *dev, struct input_event *event, unsigned int timestamp) { + /* ignore key repeat */ + if (event->value == 2) + { + DBG("\tKey Repeat"); + return; + } + if (event->code == BTN_TOUCH) { /* TODO: check for mt device */ @@ -420,7 +555,7 @@ _device_process_key(Ecore_Drm_Evdev *dev, struct input_event *event, unsigned in case BTN_FORWARD: case BTN_BACK: case BTN_TASK: - /* TODO: notify button */ + _device_notify_button(dev, event, timestamp); break; default: _device_notify_key(dev, event, timestamp); @@ -429,13 +564,36 @@ _device_process_key(Ecore_Drm_Evdev *dev, struct input_event *event, unsigned in } static void +_device_process_relative(Ecore_Drm_Evdev *dev, struct input_event *event, unsigned int timestamp) +{ + switch (event->code) + { + case REL_X: + if (dev->pending_event != EVDEV_RELATIVE_MOTION) + _device_process_flush(dev, timestamp); + dev->mouse.x += event->value; + dev->pending_event = EVDEV_RELATIVE_MOTION; + break; + case REL_Y: + if (dev->pending_event != EVDEV_RELATIVE_MOTION) + _device_process_flush(dev, timestamp); + dev->mouse.y += event->value; + dev->pending_event = EVDEV_RELATIVE_MOTION; + break; + case REL_WHEEL: + case REL_HWHEEL: + _device_process_flush(dev, timestamp); + _device_notify_wheel(dev, event, timestamp); + break; + } +} + +static void _device_process(Ecore_Drm_Evdev *dev, struct input_event *event, int count) { struct input_event *ev, *end; unsigned int timestamp = 0; - /* DBG("Evdev Device Process"); */ - ev = event; end = ev + count; for (ev = event; ev < end; ev++) @@ -448,7 +606,7 @@ _device_process(Ecore_Drm_Evdev *dev, struct input_event *event, int count) _device_process_key(dev, ev, timestamp); break; case EV_REL: - DBG("\tRelative Event"); + _device_process_relative(dev, ev, timestamp); break; case EV_ABS: DBG("\tAbsolute Event"); --
