From 044219226cf171aec201a9c4ee05b6e14e565e00 Mon Sep 17 00:00:00 2001 From: Guilherme Iscaro Date: Wed, 30 Nov 2016 13:29:19 -0200 Subject: [PATCH] Ecore Evas: Add support for multiple mouse positions. Since it's possible to have more than one mouse, Ecore Evas must take into account the position of all mouses and update them correctly. --- src/lib/ecore_evas/ecore_evas.c | 4 ++-- src/lib/ecore_evas/ecore_evas_private.h | 6 ++---- .../ecore_evas/engines/fb/ecore_evas_fb.c | 13 ++++++++---- .../engines/psl1ght/ecore_evas_psl1ght.c | 8 +++++++- .../wayland/ecore_evas_wayland_common.c | 20 +++++++++++++++---- .../engines/win32/ecore_evas_win32.c | 19 +++++++++++++++--- .../ecore_evas/engines/x/ecore_evas_x.c | 19 +++++++++++++++--- 7 files changed, 68 insertions(+), 21 deletions(-) diff --git a/src/lib/ecore_evas/ecore_evas.c b/src/lib/ecore_evas/ecore_evas.c index da485a8211..15217ce079 100644 --- a/src/lib/ecore_evas/ecore_evas.c +++ b/src/lib/ecore_evas/ecore_evas.c @@ -3140,8 +3140,6 @@ _ecore_evas_mouse_move_process_internal(Ecore_Evas *ee, Eina_Bool send_event = EINA_TRUE; Ecore_Evas_Cursor *cursor; int fx, fy, fw, fh, evt_x, evt_y; - ee->mouse.x = x; - ee->mouse.y = y; evas_output_framespace_get(ee->evas, &fx, &fy, &fw, &fh); @@ -3149,6 +3147,8 @@ _ecore_evas_mouse_move_process_internal(Ecore_Evas *ee, pointer = evas_default_device_get(ee->evas, EFL_INPUT_DEVICE_CLASS_MOUSE); cursor = eina_hash_find(ee->prop.cursors, &pointer); EINA_SAFETY_ON_NULL_RETURN(cursor); + cursor->pos_x = x; + cursor->pos_y = y; if (cursor->object) { evas_object_show(cursor->object); diff --git a/src/lib/ecore_evas/ecore_evas_private.h b/src/lib/ecore_evas/ecore_evas_private.h index 74af4dccf3..aa1d7953a7 100644 --- a/src/lib/ecore_evas/ecore_evas_private.h +++ b/src/lib/ecore_evas/ecore_evas_private.h @@ -194,6 +194,8 @@ struct _Ecore_Evas_Cursor { struct { int x, y; } hot; + int pos_x; + int pos_y; }; struct _Ecore_Evas @@ -227,10 +229,6 @@ struct _Ecore_Evas int changed : 1; } shadow; - struct { - int x, y; - } mouse; - struct { int w, h; } expecting_resize; diff --git a/src/modules/ecore_evas/engines/fb/ecore_evas_fb.c b/src/modules/ecore_evas/engines/fb/ecore_evas_fb.c index d1ab63ab0b..3ab0cdf006 100644 --- a/src/modules/ecore_evas/engines/fb/ecore_evas_fb.c +++ b/src/modules/ecore_evas/engines/fb/ecore_evas_fb.c @@ -60,14 +60,13 @@ _ecore_evas_mouse_move_process_fb(Ecore_Evas *ee, int x, int y) Ecore_Evas_Cursor *cursor; int fbw, fbh; - ee->mouse.x = x; - ee->mouse.y = y; ecore_fb_size_get(&fbw, &fbh); pointer = evas_default_device_get(ee->evas, EFL_INPUT_DEVICE_CLASS_MOUSE); cursor = eina_hash_find(ee->prop.cursors, &pointer); EINA_SAFETY_ON_NULL_RETURN(cursor); - + cursor->pos_x = x; + cursor->pos_y = y; if (cursor->object) { evas_object_show(cursor->object); @@ -361,9 +360,15 @@ _ecore_evas_move_resize(Ecore_Evas *ee, int x EINA_UNUSED, int y EINA_UNUSED, in static void _ecore_evas_rotation_set(Ecore_Evas *ee, int rotation, int resize EINA_UNUSED) { + Evas_Device *pointer; + Ecore_Evas_Cursor *cursor; Evas_Engine_Info_FB *einfo; int rot_dif; + pointer = evas_default_device_get(ee->evas, EFL_INPUT_DEVICE_CLASS_MOUSE); + cursor = eina_hash_find(ee->prop.cursors, &pointer); + EINA_SAFETY_ON_NULL_RETURN(cursor); + if (ee->rotation == rotation) return; einfo = (Evas_Engine_Info_FB *)evas_engine_info_get(ee->evas); if (!einfo) return; @@ -416,7 +421,7 @@ _ecore_evas_rotation_set(Ecore_Evas *ee, int rotation, int resize EINA_UNUSED) else evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w); - _ecore_evas_mouse_move_process_fb(ee, ee->mouse.x, ee->mouse.y); + _ecore_evas_mouse_move_process_fb(ee, cursor->pos_x, cursor->pos_y); if (ee->func.fn_resize) ee->func.fn_resize(ee); } diff --git a/src/modules/ecore_evas/engines/psl1ght/ecore_evas_psl1ght.c b/src/modules/ecore_evas/engines/psl1ght/ecore_evas_psl1ght.c index 935a7571ef..2ea7429d60 100644 --- a/src/modules/ecore_evas/engines/psl1ght/ecore_evas_psl1ght.c +++ b/src/modules/ecore_evas/engines/psl1ght/ecore_evas_psl1ght.c @@ -255,6 +255,8 @@ _ecore_evas_psl1ght_callback_delete_request_set(Ecore_Evas *ee, Ecore_Evas_Event static void _ecore_evas_screen_resized(Ecore_Evas *ee) { + Evas_Device *pointer; + Ecore_Evas_Cursor *cursor; int w, h; /* Do not resize if the window is not fullscreen */ @@ -262,6 +264,10 @@ _ecore_evas_screen_resized(Ecore_Evas *ee) ecore_psl1ght_screen_resolution_get (&w, &h); + pointer = evas_default_device_get(ee->evas, EFL_INPUT_DEVICE_CLASS_MOUSE); + cursor = eina_hash_find(ee->prop.cursors, &pointer); + EINA_SAFETY_ON_NULL_RETURN(cursor); + if (w != ee->w || h != ee->h) { ee->req.w = ee->w = w; @@ -271,7 +277,7 @@ _ecore_evas_screen_resized(Ecore_Evas *ee) ecore_psl1ght_resolution_set (w, h); evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); - _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y, + _ecore_evas_mouse_move_process(ee, cursor->pos_x, cursor->pos_y, _ecore_evas_time_get()); if (ee->func.fn_resize) ee->func.fn_resize(ee); } diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c index 5eeae7c809..fea3638e66 100644 --- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c +++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c @@ -301,6 +301,20 @@ _ecore_evas_wl_common_cb_window_configure(void *data EINA_UNUSED, int type EINA_ return ECORE_CALLBACK_PASS_ON; } +static void +_mouse_move_dispatch(Ecore_Evas *ee) +{ + Ecore_Evas_Cursor *cursor; + Eina_Iterator *itr = eina_hash_iterator_data_new(ee->prop.cursors); + + EINA_SAFETY_ON_NULL_RETURN(itr); + + EINA_ITERATOR_FOREACH(itr, cursor) + _ecore_evas_mouse_move_process(ee, cursor->pos_x, cursor->pos_y, + ecore_loop_time_get()); + eina_iterator_free(itr); +} + static void _rotation_do(Ecore_Evas *ee, int rotation, int resize) { @@ -422,8 +436,7 @@ _rotation_do(Ecore_Evas *ee, int rotation, int resize) * Yes, it's required to update the mouse position, relatively to * widgets. After a rotation change, e.g., the mouse might not be over * a button anymore. */ - _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y, - ecore_loop_time_get()); + _mouse_move_dispatch(ee); } else { @@ -437,8 +450,7 @@ _rotation_do(Ecore_Evas *ee, int rotation, int resize) * * NB: Is This Really Needed ? Yes, it's required to update the mouse * position, relatively to widgets. */ - _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y, - ecore_loop_time_get()); + _mouse_move_dispatch(ee); /* call the ecore_evas' resize function */ if (ee->func.fn_resize) ee->func.fn_resize(ee); diff --git a/src/modules/ecore_evas/engines/win32/ecore_evas_win32.c b/src/modules/ecore_evas/engines/win32/ecore_evas_win32.c index e9dbd37693..30c322cccb 100644 --- a/src/modules/ecore_evas/engines/win32/ecore_evas_win32.c +++ b/src/modules/ecore_evas/engines/win32/ecore_evas_win32.c @@ -371,9 +371,12 @@ _ecore_evas_win32_event_window_hide(void *data EINA_UNUSED, int type EINA_UNUSED static Eina_Bool _ecore_evas_win32_event_window_configure(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) { + Evas_Device *pointer; + Ecore_Evas_Cursor *cursor; Ecore_Evas *ee; Ecore_Win32_Event_Window_Configure *e; + INF("window configure"); e = event; @@ -381,6 +384,10 @@ _ecore_evas_win32_event_window_configure(void *data EINA_UNUSED, int type EINA_U if (!ee) return 1; /* pass on event */ if ((Ecore_Window)e->window != ee->prop.window) return 1; + pointer = evas_default_device_get(ee->evas, EFL_INPUT_DEVICE_CLASS_MOUSE); + cursor = eina_hash_find(ee->prop.cursors, &pointer); + EINA_SAFETY_ON_NULL_RETURN_VAL(cursor, 1); + if (ee->prop.override) { if ((ee->x != e->x) || (ee->y != e->y)) @@ -426,7 +433,7 @@ _ecore_evas_win32_event_window_configure(void *data EINA_UNUSED, int type EINA_U { if ((ee->expecting_resize.w == ee->w) && (ee->expecting_resize.h == ee->h)) - _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y, + _ecore_evas_mouse_move_process(ee, cursor->pos_x, cursor->pos_y, ecore_win32_current_time_get()); ee->expecting_resize.w = 0; ee->expecting_resize.h = 0; @@ -588,11 +595,17 @@ _ecore_evas_win32_move_resize(Ecore_Evas *ee, int x, int y, int width, int heigh static void _ecore_evas_win32_rotation_set_internal(Ecore_Evas *ee, int rotation) { + Evas_Device *pointer; + Ecore_Evas_Cursor *cursor; int rot_dif; rot_dif = ee->rotation - rotation; if (rot_dif < 0) rot_dif = -rot_dif; + pointer = evas_default_device_get(ee->evas, EFL_INPUT_DEVICE_CLASS_MOUSE); + cursor = eina_hash_find(ee->prop.cursors, &pointer); + EINA_SAFETY_ON_NULL_RETURN(cursor); + if (rot_dif != 180) { int minw, minh, maxw, maxh, basew, baseh, stepw, steph; @@ -633,13 +646,13 @@ _ecore_evas_win32_rotation_set_internal(Ecore_Evas *ee, int rotation) ecore_evas_size_max_set(ee, maxh, maxw); ecore_evas_size_base_set(ee, baseh, basew); ecore_evas_size_step_set(ee, steph, stepw); - _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y, + _ecore_evas_mouse_move_process(ee, cursor->pos_x, cursor->pos_y, ecore_win32_current_time_get()); } else { ee->rotation = rotation; - _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y, + _ecore_evas_mouse_move_process(ee, cursor->pos_x, cursor->pos_y, ecore_win32_current_time_get()); if (ee->func.fn_resize) ee->func.fn_resize(ee); } diff --git a/src/modules/ecore_evas/engines/x/ecore_evas_x.c b/src/modules/ecore_evas/engines/x/ecore_evas_x.c index 2b4e00bfd5..7949326ee3 100644 --- a/src/modules/ecore_evas/engines/x/ecore_evas_x.c +++ b/src/modules/ecore_evas/engines/x/ecore_evas_x.c @@ -1616,6 +1616,9 @@ _ecore_evas_x_shadow_update(Ecore_Evas *ee) static Eina_Bool _ecore_evas_x_event_window_configure(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) { + + Evas_Device *pointer; + Ecore_Evas_Cursor *cursor; Ecore_Evas *ee; Ecore_X_Event_Window_Configure *e; Ecore_Evas_Engine_Data_X11 *edata; @@ -1628,6 +1631,10 @@ _ecore_evas_x_event_window_configure(void *data EINA_UNUSED, int type EINA_UNUSE if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; if (edata->direct_resize) return ECORE_CALLBACK_PASS_ON; + pointer = evas_default_device_get(ee->evas, EFL_INPUT_DEVICE_CLASS_MOUSE); + cursor = eina_hash_find(ee->prop.cursors, &pointer); + EINA_SAFETY_ON_NULL_RETURN_VAL(cursor, ECORE_CALLBACK_PASS_ON); + if (edata->configure_reqs > 0) edata->configure_reqs--; edata->configure_coming = 0; @@ -1684,7 +1691,7 @@ _ecore_evas_x_event_window_configure(void *data EINA_UNUSED, int type EINA_UNUSE { if ((ee->expecting_resize.w == ee->w) && (ee->expecting_resize.h == ee->h)) - _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y, + _ecore_evas_mouse_move_process(ee, cursor->pos_x, cursor->pos_y, ecore_x_current_time_get()); ee->expecting_resize.w = 0; ee->expecting_resize.h = 0; @@ -2340,10 +2347,16 @@ static void _ecore_evas_x_rotation_set_internal(Ecore_Evas *ee, int rotation, int resize, Evas_Engine_Info *einfo) { + Evas_Device *pointer; + Ecore_Evas_Cursor *cursor; int rot_dif; Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data; int fw = 0, fh = 0; + pointer = evas_default_device_get(ee->evas, EFL_INPUT_DEVICE_CLASS_MOUSE); + cursor = eina_hash_find(ee->prop.cursors, &pointer); + EINA_SAFETY_ON_NULL_RETURN(cursor); + rot_dif = ee->rotation - rotation; if (rot_dif < 0) rot_dif = -rot_dif; @@ -2422,7 +2435,7 @@ _ecore_evas_x_rotation_set_internal(Ecore_Evas *ee, int rotation, int resize, ecore_evas_size_max_set(ee, maxh, maxw); ecore_evas_size_base_set(ee, baseh, basew); ecore_evas_size_step_set(ee, steph, stepw); - _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y, + _ecore_evas_mouse_move_process(ee, cursor->pos_x, cursor->pos_y, ecore_x_current_time_get()); } else @@ -2432,7 +2445,7 @@ _ecore_evas_x_rotation_set_internal(Ecore_Evas *ee, int rotation, int resize, ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); } ee->rotation = rotation; - _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y, + _ecore_evas_mouse_move_process(ee, cursor->pos_x, cursor->pos_y, ecore_x_current_time_get()); if (ee->func.fn_resize) ee->func.fn_resize(ee);