From 453770137f84afe622156290e7c38d2d1d3845c4 Mon Sep 17 00:00:00 2001 From: Guilherme Iscaro Date: Wed, 19 Oct 2016 15:57:18 -0200 Subject: [PATCH] Evas: Add the default input devices for Evas. This will be useful when Ecore_Evas is setting up the EFL_POINTER/KEY_EVENT struct. --- src/lib/evas/canvas/evas_canvas.eo | 10 +++++ src/lib/evas/canvas/evas_device.c | 65 +++++++++++++++++++++++++++++ src/lib/evas/canvas/evas_main.c | 34 ++++++++++++++- src/lib/evas/include/evas_private.h | 4 ++ 4 files changed, 112 insertions(+), 1 deletion(-) diff --git a/src/lib/evas/canvas/evas_canvas.eo b/src/lib/evas/canvas/evas_canvas.eo index bd60468b39..5fcfa63061 100644 --- a/src/lib/evas/canvas/evas_canvas.eo +++ b/src/lib/evas/canvas/evas_canvas.eo @@ -1116,6 +1116,16 @@ class Evas.Canvas (Efl.Object, Efl.Canvas, Efl.Animator, Efl.Input.Interface) re-compute of that data etc. ]] } + default_device_get { + [[Return the default device of a given type. + \@note Currently Evas only creates a seat, mouse and keyboard. + @since 1.19 + ]] + params { + @in type: Efl.Input.Device.Class; [[The class of the default device to fetch.]] + } + return: Efl.Input.Device; [[The default device or $null on error.]] + } coord_world_y_to_screen @const { [[Convert/scale a canvas coordinate into output screen coordinates. diff --git a/src/lib/evas/canvas/evas_device.c b/src/lib/evas/canvas/evas_device.c index f243b894f0..14ebfe3216 100644 --- a/src/lib/evas/canvas/evas_device.c +++ b/src/lib/evas/canvas/evas_device.c @@ -24,6 +24,53 @@ * here (callbacks and canvas private data). */ +static Eina_Bool +_is_pointer(Evas_Device_Class clas) +{ + if (clas == EVAS_DEVICE_CLASS_MOUSE || + clas == EVAS_DEVICE_CLASS_TOUCH || + clas == EVAS_DEVICE_CLASS_WAND || + clas == EVAS_DEVICE_CLASS_PEN) + return EINA_TRUE; + return EINA_FALSE; +} + +static Evas_Device * +_new_default_device_find(Evas_Public_Data *e, Evas_Device *old_dev) +{ + Eina_List *l; + Evas_Device *dev, *def, *old_parent; + Evas_Device_Class old_class; + + old_class = efl_input_device_type_get(old_dev); + old_parent = efl_input_device_parent_get(old_dev); + def = NULL; + + EINA_LIST_FOREACH(e->devices, l, dev) + { + if (efl_input_device_type_get(dev) != old_class) + continue; + + def = dev; + //Prefer devices with the same parent. + if (efl_input_device_parent_get(dev) == old_parent) + break; + } + + if (!def) + { + const char *class_str; + if (old_class == EVAS_DEVICE_CLASS_SEAT) + class_str = "seat"; + else if (old_class == EVAS_DEVICE_CLASS_KEYBOARD) + class_str = "keyboard"; + else + class_str = "mouse"; + WRN("Could not find a default %s device.", class_str); + } + return def; +} + static void _del_cb(void *data, const Efl_Event *ev) { @@ -31,6 +78,14 @@ _del_cb(void *data, const Efl_Event *ev) // can not be done in std destructor e->devices = eina_list_remove(e->devices, ev->object); + + if (e->default_seat == ev->object) + e->default_seat = _new_default_device_find(e, ev->object); + else if (e->default_mouse == ev->object) + e->default_mouse = _new_default_device_find(e, ev->object); + else if (e->default_keyboard == ev->object) + e->default_keyboard = _new_default_device_find(e, ev->object); + efl_event_callback_call(e->evas, EFL_CANVAS_EVENT_DEVICE_REMOVED, ev->object); } @@ -66,6 +121,16 @@ evas_device_add_full(Evas *eo_e, const char *name, const char *desc, d->evas = eo_e; e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS); + + /* This is the case when the user is using wayland backend, + since evas itself will not create the devices we must set them here. */ + if (!e->default_seat && clas == EVAS_DEVICE_CLASS_SEAT) + e->default_seat = dev; + else if (!e->default_keyboard && clas == EVAS_DEVICE_CLASS_KEYBOARD) + e->default_keyboard = dev; + else if (!e->default_mouse && _is_pointer(clas)) + e->default_mouse = dev; + e->devices = eina_list_append(e->devices, dev); efl_event_callback_add(dev, EFL_EVENT_DEL, _del_cb, e); diff --git a/src/lib/evas/canvas/evas_main.c b/src/lib/evas/canvas/evas_main.c index e3283896fe..8155bc8e97 100644 --- a/src/lib/evas/canvas/evas_main.c +++ b/src/lib/evas/canvas/evas_main.c @@ -410,6 +410,20 @@ _evas_canvas_coord_world_y_to_screen(const Eo *eo_e EINA_UNUSED, Evas_Public_Dat else return (int)((((long long)y - (long long)e->viewport.y) * (long long)e->output.h) / (long long)e->viewport.h); } +EOLIAN static Efl_Input_Device * +_evas_canvas_default_device_get(Eo *eo_e EINA_UNUSED, + Evas_Public_Data *e, + Efl_Input_Device_Class klass) +{ + if (klass == EFL_INPUT_DEVICE_CLASS_SEAT) + return e->default_seat; + if (klass == EFL_INPUT_DEVICE_CLASS_MOUSE) + return e->default_mouse; + if (klass == EFL_INPUT_DEVICE_CLASS_KEYBOARD) + return e->default_keyboard; + return NULL; +} + EAPI int evas_render_method_lookup(const char *name) { @@ -807,7 +821,25 @@ evas_output_method_set(Evas *eo_e, int render_method) evas_module_ref(em); /* get the engine info struct */ if (e->engine.func->info) e->engine.info = e->engine.func->info(eo_e); - return; + + //Wayland already handle seats. + if (render_method == evas_render_method_lookup("wayland_shm") || + render_method == evas_render_method_lookup("wayland_egl")) + return; + + e->default_seat = evas_device_add_full(eo_e, "default", "The default seat", + NULL, NULL, EVAS_DEVICE_CLASS_SEAT, + EVAS_DEVICE_SUBCLASS_NONE); + e->default_mouse = evas_device_add_full(eo_e, "keyboard", + "The default mouse", + e->default_seat, NULL, + EVAS_DEVICE_CLASS_MOUSE, + EVAS_DEVICE_SUBCLASS_NONE); + e->default_keyboard = evas_device_add_full(eo_e, "keyboard", + "The default keyboard", + e->default_seat, NULL, + EVAS_DEVICE_CLASS_KEYBOARD, + EVAS_DEVICE_SUBCLASS_NONE); } EAPI int diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index 5d7168451c..dcbcbecf4e 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -905,6 +905,10 @@ struct _Evas_Public_Data Eina_List *outputs; + Evas_Device *default_seat; + Evas_Device *default_mouse; + Evas_Device *default_keyboard; + unsigned char changed : 1; unsigned char delete_me : 1; unsigned char invalidate : 1;