Add support for storing mulitple touch points.
authorChris Michael <cp.michael@samsung.com>
Tue, 19 Nov 2013 10:34:27 +0000 (10:34 +0000)
committerChris Michael <cp.michael@samsung.com>
Tue, 19 Nov 2013 10:38:23 +0000 (10:38 +0000)
Send events to properly focused surface.
Fill in missing parts of the event structures (ev->root, ev->multi).

Signed-off-by: Chris Michael <cp.michael@samsung.com>
src/lib/ecore_wayland/ecore_wl_input.c

index b4d3a33..c686691 100644 (file)
 # define BTN_BACK 0x116
 #endif
 
+typedef struct _Ecore_Wl_Touch_Point
+{
+   int id;
+   Ecore_Wl_Window *window;
+   struct wl_list link;
+} Ecore_Wl_Touch_Point;
+
 typedef struct _Ecore_Wl_Mouse_Down_Info
 {
    EINA_INLIST;
@@ -315,6 +322,7 @@ _ecore_wl_input_add(Ecore_Wl_Display *ewd, unsigned int id)
    input->display = ewd;
    input->pointer_focus = NULL;
    input->keyboard_focus = NULL;
+   input->touch_focus = NULL;
 
    input->seat = 
      wl_registry_bind(ewd->wl.registry, id, &wl_seat_interface, 1);
@@ -324,6 +332,7 @@ _ecore_wl_input_add(Ecore_Wl_Display *ewd, unsigned int id)
                         &_ecore_wl_seat_listener, input);
    wl_seat_set_user_data(input->seat, input);
 
+   wl_list_init(&input->touch_points);
    wl_array_init(&input->data_types);
 
    input->data_device = 
@@ -347,6 +356,26 @@ _ecore_wl_input_del(Ecore_Wl_Input *input)
    if (input->cursor_name) eina_stringshare_del(input->cursor_name);
    input->cursor_name = NULL;
 
+   if (input->touch_focus)
+     {
+        Ecore_Wl_Window *win = NULL;
+
+        if ((win = input->touch_focus))
+          win->touch_device = NULL;
+
+        input->touch_focus = NULL;
+     }
+
+   if (input->pointer_focus)
+     {
+        Ecore_Wl_Window *win = NULL;
+
+        if ((win = input->pointer_focus))
+          win->pointer_device = NULL;
+
+        input->pointer_focus = NULL;
+     }
+
    if (input->keyboard_focus)
      {
         Ecore_Wl_Window *win = NULL;
@@ -965,24 +994,33 @@ _ecore_wl_input_cb_keyboard_leave(void *data, struct wl_keyboard *keyboard EINA_
 }
 
 static void 
-_ecore_wl_input_cb_touch_down(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int serial, unsigned int timestamp, struct wl_surface *surface EINA_UNUSED, int id, wl_fixed_t x, wl_fixed_t y)
+_ecore_wl_input_cb_touch_down(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int serial, unsigned int timestamp, struct wl_surface *surface, int id, wl_fixed_t x, wl_fixed_t y)
 {
    Ecore_Wl_Input *input;
+   Ecore_Wl_Window *win;
+   Ecore_Wl_Touch_Point *point;
 
    LOGFN(__FILE__, __LINE__, __FUNCTION__);
 
    if (!surface) return;
    if (!(input = data)) return;
 
-   /* FIXME: NB: Not sure yet if input->timestamp should be set here. 
-    * This needs to be tested with an actual touch device */
-   /* input->timestamp = timestamp; */
+   if (!(win = ecore_wl_window_surface_find(surface))) return;
+
+   if (!(point = malloc(sizeof(Ecore_Wl_Touch_Point))))
+     return;
+
+   point->id = id;
+   point->window = win;
+   wl_list_insert(&input->touch_points, &point->link);
+
+   input->touch_focus = win;
+   input->timestamp = timestamp;
    input->display->serial = serial;
    input->sx = wl_fixed_to_int(x);
    input->sy = wl_fixed_to_int(y);
-   /* _ecore_wl_input_mouse_move_send(input, input->pointer_focus, timestamp, id); */
-   /* _ecore_wl_input_cb_pointer_enter(data, NULL, serial, surface, x, y); */
-   _ecore_wl_input_mouse_down_send(input, input->pointer_focus,
+
+   _ecore_wl_input_mouse_down_send(input, input->touch_focus,
                                    id, 0, timestamp);
 }
 
@@ -990,34 +1028,52 @@ static void
 _ecore_wl_input_cb_touch_up(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int serial, unsigned int timestamp, int id)
 {
    Ecore_Wl_Input *input;
+   Ecore_Wl_Touch_Point *point, *tmp;
 
    LOGFN(__FILE__, __LINE__, __FUNCTION__);
 
    if (!(input = data)) return;
+   if (!input->touch_focus) return;
 
-   /* FIXME: NB: Not sure yet if input->timestamp should be set here. 
-    * This needs to be tested with an actual touch device */
-   /* input->timestamp = timestamp; */
+   input->timestamp = timestamp;
    input->display->serial = serial;
-   _ecore_wl_input_mouse_up_send(input, input->pointer_focus,
-                                 id, 0, timestamp);
+
+   wl_list_for_each_safe(point, tmp, &input->touch_points, link)
+     {
+        if (point->id != id) continue;
+
+        _ecore_wl_input_mouse_up_send(input, input->touch_focus,
+                                      id, 0, timestamp);
+
+        wl_list_remove(&point->link);
+        free(point);
+
+        return;
+     }
 }
 
 static void 
 _ecore_wl_input_cb_touch_motion(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int timestamp, int id, wl_fixed_t x, wl_fixed_t y)
 {
    Ecore_Wl_Input *input;
+   Ecore_Wl_Touch_Point *point;
 
    LOGFN(__FILE__, __LINE__, __FUNCTION__);
 
    if (!(input = data)) return;
+   if (!input->touch_focus) return;
 
-   /* FIXME: NB: Not sure yet if input->timestamp should be set here. 
-    * This needs to be tested with an actual touch device */
-   /* input->timestamp = timestamp; */
+   input->timestamp = timestamp;
    input->sx = wl_fixed_to_int(x);
    input->sy = wl_fixed_to_int(y);
-   _ecore_wl_input_mouse_move_send(input, input->pointer_focus, timestamp, id);
+
+   wl_list_for_each(point, &input->touch_points, link)
+     {
+        if (point->id != id) continue;
+        _ecore_wl_input_mouse_move_send(input, 
+                                        input->touch_focus, timestamp, id);
+        return;
+     }
 }
 
 static void 
@@ -1095,8 +1151,8 @@ _ecore_wl_input_mouse_move_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, uns
    ev->timestamp = timestamp;
    ev->x = input->sx;
    ev->y = input->sy;
-   /* ev->root.x = input->sx; */
-   /* ev->root.y = input->sy; */
+   ev->root.x = input->sx;
+   ev->root.y = input->sy;
    ev->modifiers = input->modifiers;
    ev->multi.device = device;
    ev->multi.radius = 1;
@@ -1106,6 +1162,8 @@ _ecore_wl_input_mouse_move_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, uns
    ev->multi.angle = 0.0;
    ev->multi.x = input->sx;
    ev->multi.y = input->sy;
+   ev->multi.root.x = input->sx;
+   ev->multi.root.y = input->sy;
 
    if ((down_info = _ecore_wl_mouse_down_info_get(device)))
      {
@@ -1133,8 +1191,8 @@ _ecore_wl_input_mouse_in_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsig
 
    ev->x = input->sx;
    ev->y = input->sy;
-   /* ev->root.x = input->sx; */
-   /* ev->root.y = input->sy; */
+   ev->root.x = input->sx;
+   ev->root.y = input->sy;
    ev->modifiers = input->modifiers;
    ev->timestamp = timestamp;
 
@@ -1158,8 +1216,8 @@ _ecore_wl_input_mouse_out_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsi
 
    ev->x = input->sx;
    ev->y = input->sy;
-   /* ev->root.x = input->sx; */
-   /* ev->root.y = input->sy; */
+   ev->root.x = input->sx;
+   ev->root.y = input->sy;
    ev->modifiers = input->modifiers;
    ev->timestamp = timestamp;
 
@@ -1220,8 +1278,8 @@ _ecore_wl_input_mouse_down_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, int
    ev->timestamp = timestamp;
    ev->x = input->sx;
    ev->y = input->sy;
-   /* ev->root.x = input->sx; */
-   /* ev->root.y = input->sy; */
+   ev->root.x = input->sx;
+   ev->root.y = input->sy;
    ev->modifiers = input->modifiers;
 
    ev->double_click = 0;
@@ -1284,6 +1342,8 @@ _ecore_wl_input_mouse_down_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, int
    ev->multi.angle = 0.0;
    ev->multi.x = input->sx;
    ev->multi.y = input->sy;
+   ev->multi.root.x = input->sx;
+   ev->multi.root.y = input->sy;
 
    if (win)
      {
@@ -1327,8 +1387,8 @@ _ecore_wl_input_mouse_up_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, int d
    ev->timestamp = timestamp;
    ev->x = input->sx;
    ev->y = input->sy;
-   /* ev->root.x = input->sx; */
-   /* ev->root.y = input->sy; */
+   ev->root.x = input->sx;
+   ev->root.y = input->sy;
    ev->modifiers = input->modifiers;
 
    ev->double_click = 0;
@@ -1355,6 +1415,8 @@ _ecore_wl_input_mouse_up_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, int d
    ev->multi.radius_y = 1;
    ev->multi.pressure = 1.0;
    ev->multi.angle = 0.0;
+   ev->multi.root.x = input->sx;
+   ev->multi.root.y = input->sy;
 
    if (win)
      {