devilhorns pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=6a7589bf7805b31b532cd6acf972a3f87f65366f

commit 6a7589bf7805b31b532cd6acf972a3f87f65366f
Author: Chris Michael <cpmich...@osg.samsung.com>
Date:   Wed Apr 6 11:32:42 2016 -0400

    elput: Handle various events from libinput and pass to ecore_event
    
    Signed-off-by: Chris Michael <cpmich...@osg.samsung.com>
---
 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 2036d17..6dd4da4 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 4c1b7f1..8dc2752 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

-- 


Reply via email to