Merge branch 'devs/bdilly/ecore_evas_wayland'

This series adds multiseat support to wayland engine.

Evas devices are created for seats (parent), keyboard, mouses and
touch input devices.

This way an application would be able to differentiate between
source seat of input events.

Reviewed By: devilhorns, ManMower, iscaro

Differential Revision: https://phab.enlightenment.org/D4370

@feature
This commit is contained in:
Bruno Dilly 2016-11-01 16:07:05 -02:00
commit 3ac1812a1f
11 changed files with 795 additions and 25 deletions

View File

@ -24,6 +24,7 @@
/ecore_evas_extn_plug_example
/ecore_evas_extn_socket_example
/ecore_evas_object_example
/ecore_evas_wayland_multiseat_example
/ecore_evas_window_sizes_example
/ecore_evas_vnc_example
/ecore_event_example_01

View File

@ -59,6 +59,7 @@ ecore_evas_extn_plug_example \
ecore_evas_callbacks \
ecore_evas_ews_example \
ecore_evas_object_example \
ecore_evas_wayland_multiseat_example \
ecore_evas_window_sizes_example \
ecore_evas_vnc_example \
ecore_event_example_01 \
@ -205,6 +206,10 @@ ecore_evas_ews_example_LDADD = $(ECORE_EVAS_COMMON_LDADD)
ecore_evas_object_example_SOURCES = ecore_evas_object_example.c
ecore_evas_object_example_LDADD = $(ECORE_EVAS_COMMON_LDADD)
ecore_evas_wayland_multiseat_example_SOURCES = ecore_evas_wayland_multiseat_example.c
ecore_evas_wayland_multiseat_example_LDADD = $(ECORE_EVAS_COMMON_LDADD) \
$(top_builddir)/src/lib/ecore_input/libecore_input.la
ecore_evas_window_sizes_example_SOURCES = ecore_evas_window_sizes_example.c
ecore_evas_window_sizes_example_LDADD = $(ECORE_EVAS_COMMON_LDADD)
@ -353,6 +358,7 @@ ecore_evas_extn_plug_example.c \
ecore_evas_callbacks.c \
ecore_evas_ews_example.c \
ecore_evas_object_example.c \
ecore_evas_wayland_multiseat_example.c \
ecore_evas_window_sizes_example.c \
ecore_evas_vnc_example.c \
ecore_event_example_01.c \

View File

@ -0,0 +1,242 @@
#define EFL_EO_API_SUPPORT
#define EFL_BETA_API_SUPPORT
#include <Efl.h>
#include <stdio.h>
#include <Ecore.h>
#include <Evas.h>
#include <Eina.h>
#include <Ecore_Evas.h>
#include <Ecore_Input.h>
static Efl_Input_Device *
_get_seat(Efl_Input_Device *dev)
{
if (!dev) return NULL;
while ((dev = efl_input_device_parent_get(dev)))
{
if (efl_input_device_type_get(dev) == EFL_INPUT_DEVICE_CLASS_SEAT)
return dev;
}
return NULL;
}
static Eina_Bool
_keyboard_event(void *data EINA_UNUSED, int type, void *event)
{
Ecore_Event_Key *e = event;
Efl_Input_Device *seat = NULL;
if (e->dev)
seat = _get_seat(e->dev);
printf("The keyboard on seat '%s' %s the key '%s'\n", seat ?
efl_input_device_name_get(seat) : "unknown",
type == ECORE_EVENT_KEY_DOWN ? "pressed" : "released",
e->keyname);
return ECORE_CALLBACK_PASS_ON;
}
static Eina_Bool
_mouse_move(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
Ecore_Event_Mouse_Move *e = event;
Efl_Input_Device *seat = NULL;
if (e->dev)
seat = _get_seat(e->dev);
printf("The mouse on seat '%s' is at X: %d Y:%d\n",
seat ? efl_input_device_name_get(seat) : "unknown", e->x, e->y);
return ECORE_CALLBACK_PASS_ON;
}
static Eina_Bool
_mouse_button(void *data EINA_UNUSED, int type, void *event)
{
Ecore_Event_Mouse_Button *e = event;
Efl_Input_Device *seat = NULL;
if (e->dev)
seat = _get_seat(e->dev);
printf("The mouse on seat '%s' %s the following button '%d'\n",
seat ? efl_input_device_name_get(seat) : "unknown",
type == ECORE_EVENT_MOUSE_BUTTON_DOWN ? "pressed" : "released",
e->buttons);
return ECORE_CALLBACK_PASS_ON;
}
static Eina_Bool
_mouse_wheel(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
Ecore_Event_Mouse_Wheel *e = event;
Efl_Input_Device *seat = NULL;
if (e->dev)
seat = _get_seat(e->dev);
printf("The mouse on seat '%s' moved the wheel '%s'\n",
seat ? efl_input_device_name_get(seat) : "unknown",
e->z < 0 ? "up" : "down");
return ECORE_CALLBACK_PASS_ON;
}
static const char *
_device_type_to_string(Efl_Input_Device_Class klass)
{
switch (klass)
{
case EFL_INPUT_DEVICE_CLASS_NONE:
return "None";
case EFL_INPUT_DEVICE_CLASS_SEAT:
return "Seat";
case EFL_INPUT_DEVICE_CLASS_KEYBOARD:
return "Keyboard";
case EFL_INPUT_DEVICE_CLASS_MOUSE:
return "Mouse";
case EFL_INPUT_DEVICE_CLASS_TOUCH:
return "Touch";
case EFL_INPUT_DEVICE_CLASS_PEN:
return "Pen";
case EFL_INPUT_DEVICE_CLASS_WAND:
return "Wand";
case EFL_INPUT_DEVICE_CLASS_GAMEPAD:
return "Gamepad";
default:
return "Unknown";
}
}
static void
_dev_added_or_removed(void *data, const Efl_Event *event)
{
Efl_Input_Device *dev = event->info;
printf("The device %p '%s' - class: '%s' - desc: '%s' was '%s' on ee %p\n",
dev, efl_input_device_name_get(dev),
_device_type_to_string(efl_input_device_type_get(dev)),
efl_input_device_description_get(dev),
event->desc == EFL_CANVAS_EVENT_DEVICE_ADDED ? "added" : "removed",
data);
}
static void
_dev_changed(void *data, const Efl_Event *event)
{
Efl_Input_Device *dev = event->info;
printf("The device %p '%s' - class: '%s' was changed on ee %p\n",
dev, efl_input_device_name_get(dev),
_device_type_to_string(efl_input_device_type_get(dev)), data);
}
int
main(int argc EINA_UNUSED, char *argv[] EINA_UNUSED)
{
Ecore_Evas *ee1, *ee2;
Evas *evas1, *evas2;
Evas_Object *bg, *rect1, *rect2;
Ecore_Event_Handler *keydown_handler, *keyup_handler, *mouse_move,
*mouse_down, *mouse_up, *mouse_wheel;
ecore_evas_init();
ee1 = ecore_evas_new("wayland_shm", 0, 0, 800, 600, NULL);
if (!ee1)
ee1 = ecore_evas_new("wayland_egl", 0, 0, 800, 600, NULL);
if (!ee1)
{
fprintf(stderr, "Could not create the ecore evas\n");
return -1;
}
evas1 = ecore_evas_get(ee1);
bg = evas_object_rectangle_add(evas1);
evas_object_color_set(bg, 255, 255, 255, 255);
evas_object_move(bg, 0, 0);
evas_object_resize(bg, 800, 600);
evas_object_show(bg);
/* TODO play with focus */
rect1 = evas_object_rectangle_add(evas1);
evas_object_color_set(rect1, 0, 255, 0, 255);
evas_object_resize(rect1, 50, 50);
evas_object_move(rect1, (800 - 50) /2, (600 - 50)/2);
evas_object_show(rect1);
rect2 = evas_object_rectangle_add(evas1);
evas_object_color_set(rect2, 0, 0, 255, 255);
evas_object_resize(rect2, 50, 50);
evas_object_move(rect2, 50, 50);
evas_object_show(rect2);
ecore_evas_show(ee1);
ee2 = ecore_evas_new("wayland_shm", 0, 0, 300, 200, NULL);
if (!ee2)
ee2 = ecore_evas_new("wayland_egl", 0, 0, 300, 200, NULL);
if (!ee2)
{
fprintf(stderr, "Could not create the ecore evas\n");
return -1;
}
evas2 = ecore_evas_get(ee2);
bg = evas_object_rectangle_add(evas2);
evas_object_color_set(bg, 100, 100, 100, 255);
evas_object_move(bg, 0, 0);
evas_object_resize(bg, 300, 200);
evas_object_show(bg);
ecore_evas_show(ee2);
keydown_handler = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
_keyboard_event, NULL);
keyup_handler = ecore_event_handler_add(ECORE_EVENT_KEY_UP,
_keyboard_event, NULL);
mouse_move = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _mouse_move,
NULL);
mouse_up = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
_mouse_button, NULL);
mouse_down = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
_mouse_button, NULL);
mouse_wheel = ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL,
_mouse_wheel, NULL);
efl_event_callback_add(evas1, EFL_CANVAS_EVENT_DEVICE_ADDED,
_dev_added_or_removed, ee1);
efl_event_callback_add(evas1, EFL_CANVAS_EVENT_DEVICE_REMOVED,
_dev_added_or_removed, ee1);
efl_event_callback_add(evas1, EFL_CANVAS_EVENT_DEVICE_CHANGED,
_dev_changed, ee1);
efl_event_callback_add(evas2, EFL_CANVAS_EVENT_DEVICE_ADDED,
_dev_added_or_removed, ee2);
efl_event_callback_add(evas2, EFL_CANVAS_EVENT_DEVICE_REMOVED,
_dev_added_or_removed, ee2);
efl_event_callback_add(evas2, EFL_CANVAS_EVENT_DEVICE_CHANGED,
_dev_changed, ee2);
ecore_main_loop_begin();
ecore_event_handler_del(mouse_wheel);
ecore_event_handler_del(keydown_handler);
ecore_event_handler_del(keyup_handler);
ecore_event_handler_del(mouse_move);
ecore_event_handler_del(mouse_up);
ecore_event_handler_del(mouse_down);
ecore_evas_free(ee1);
ecore_evas_free(ee2);
ecore_evas_shutdown();
return 0;
}

View File

@ -139,6 +139,36 @@ typedef struct _Ecore_Wl2_Event_Data_Source_Send
int fd;
} Ecore_Wl2_Event_Data_Source_Send;
typedef struct _Ecore_Wl2_Event_Seat_Name
{
Eina_Stringshare *name;
unsigned int id;
} Ecore_Wl2_Event_Seat_Name;
typedef struct _Ecore_Wl2_Event_Seat_Capabilities
{
unsigned int id;
Eina_Bool pointer_enabled : 1;
Eina_Bool keyboard_enabled : 1;
Eina_Bool touch_enabled : 1;
} Ecore_Wl2_Event_Seat_Capabilities;
typedef enum
{
ECORE_WL2_DEVICE_TYPE_SEAT,
ECORE_WL2_DEVICE_TYPE_POINTER,
ECORE_WL2_DEVICE_TYPE_KEYBOARD,
ECORE_WL2_DEVICE_TYPE_TOUCH
} Ecore_Wl2_Device_Type;
typedef struct _Ecore_Wl2_Event_Device
{
Eo *dev;
int window_id;
unsigned int seat_id;
Ecore_Wl2_Device_Type type;
} Ecore_Wl2_Event_Device;
typedef enum
{
ECORE_WL2_SELECTION_CNP,
@ -203,6 +233,10 @@ EAPI extern int ECORE_WL2_EVENT_DATA_SOURCE_SEND; /** @since 1.17 */
EAPI extern int ECORE_WL2_EVENT_WINDOW_CONFIGURE; /** @since 1.17 */
EAPI extern int ECORE_WL2_EVENT_SYNC_DONE; /** @since 1.17 */
EAPI extern int ECORE_WL2_EVENT_OFFER_DATA_READY; /** @since 1.19 */
EAPI extern int ECORE_WL2_EVENT_SEAT_NAME_CHANGED; /** @since 1.19 */
EAPI extern int ECORE_WL2_EVENT_SEAT_CAPABILITIES_CHANGED; /** @since 1.19 */
EAPI extern int ECORE_WL2_EVENT_DEVICE_ADDED; /** @since 1.19 */
EAPI extern int ECORE_WL2_EVENT_DEVICE_REMOVED; /** @since 1.19 */
/**
* @file
* @brief Ecore functions for dealing with the Wayland display protocol

View File

@ -31,6 +31,10 @@ EAPI int ECORE_WL2_EVENT_DATA_SOURCE_SEND = 0;
EAPI int ECORE_WL2_EVENT_WINDOW_CONFIGURE = 0;
EAPI int ECORE_WL2_EVENT_SYNC_DONE = 0;
EAPI int ECORE_WL2_EVENT_OFFER_DATA_READY = 0;
EAPI int ECORE_WL2_EVENT_SEAT_NAME_CHANGED = 0;
EAPI int ECORE_WL2_EVENT_SEAT_CAPABILITIES_CHANGED = 0;
EAPI int ECORE_WL2_EVENT_DEVICE_ADDED = 0;
EAPI int ECORE_WL2_EVENT_DEVICE_REMOVED = 0;
EAPI int _ecore_wl2_event_window_www = -1;
EAPI int _ecore_wl2_event_window_www_drag = -1;
@ -89,6 +93,10 @@ ecore_wl2_init(void)
ECORE_WL2_EVENT_WINDOW_CONFIGURE = ecore_event_type_new();
ECORE_WL2_EVENT_SYNC_DONE = ecore_event_type_new();
ECORE_WL2_EVENT_OFFER_DATA_READY = ecore_event_type_new();
ECORE_WL2_EVENT_SEAT_NAME_CHANGED = ecore_event_type_new();
ECORE_WL2_EVENT_SEAT_CAPABILITIES_CHANGED = ecore_event_type_new();
ECORE_WL2_EVENT_DEVICE_ADDED = ecore_event_type_new();
ECORE_WL2_EVENT_DEVICE_REMOVED = ecore_event_type_new();
_ecore_wl2_event_window_www = ecore_event_type_new();
_ecore_wl2_event_window_www_drag = ecore_event_type_new();
}
@ -140,6 +148,10 @@ ecore_wl2_shutdown(void)
ECORE_WL2_EVENT_WINDOW_CONFIGURE = 0;
ECORE_WL2_EVENT_SYNC_DONE = 0;
ECORE_WL2_EVENT_OFFER_DATA_READY = 0;
ECORE_WL2_EVENT_SEAT_NAME_CHANGED = 0;
ECORE_WL2_EVENT_SEAT_CAPABILITIES_CHANGED = 0;
ECORE_WL2_EVENT_DEVICE_ADDED = 0;
ECORE_WL2_EVENT_DEVICE_REMOVED = 0;
/* shutdown Ecore_Event */
ecore_event_shutdown();

View File

@ -18,6 +18,14 @@
#include <sys/mman.h>
#include "ecore_wl2_private.h"
typedef struct _Ecore_Wl2_Input_Devices
{
Eo *pointer_dev;
Eo *keyboard_dev;
Eo *touch_dev;
int window_id;
} Ecore_Wl2_Input_Devices;
typedef struct _Ecore_Wl2_Mouse_Down_Info
{
EINA_INLIST;
@ -57,6 +65,33 @@ _ecore_wl2_input_mouse_down_info_get(int device)
return info;
}
static Ecore_Wl2_Input_Devices *
_ecore_wl2_devices_get(Ecore_Wl2_Input *input, int window_id)
{
Ecore_Wl2_Input_Devices *devices;
Eina_List *l;
EINA_LIST_FOREACH(input->devices_list, l, devices)
{
if (devices->window_id == window_id)
return devices;
}
return NULL;
}
static Eo *
_ecore_wl2_mouse_dev_get(Ecore_Wl2_Input *input, int window_id)
{
Ecore_Wl2_Input_Devices *devices;
devices = _ecore_wl2_devices_get(input, window_id);
if (devices)
return devices->pointer_dev;
return NULL;
}
static void
_ecore_wl2_input_mouse_in_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window)
{
@ -71,6 +106,7 @@ _ecore_wl2_input_mouse_in_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window)
ev->event_window = window->id;
ev->timestamp = input->timestamp;
ev->modifiers = input->keyboard.modifiers;
ev->dev = _ecore_wl2_mouse_dev_get(input, window->id);
ecore_event_add(ECORE_EVENT_MOUSE_IN, ev, NULL, NULL);
}
@ -89,6 +125,7 @@ _ecore_wl2_input_mouse_out_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window
ev->event_window = window->id;
ev->timestamp = input->timestamp;
ev->modifiers = input->keyboard.modifiers;
ev->dev = _ecore_wl2_mouse_dev_get(input, window->id);
ecore_event_add(ECORE_EVENT_MOUSE_OUT, ev, NULL, NULL);
}
@ -120,6 +157,7 @@ _ecore_wl2_input_mouse_move_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *windo
ev->multi.y = input->pointer.sy;
ev->multi.root.x = input->pointer.sx;
ev->multi.root.y = input->pointer.sy;
ev->dev = _ecore_wl2_mouse_dev_get(input, window->id);
info = _ecore_wl2_input_mouse_down_info_get(device);
if (info)
@ -165,6 +203,7 @@ _ecore_wl2_input_mouse_wheel_send(Ecore_Wl2_Input *input, unsigned int axis, int
ev->window = input->focus.pointer->id;
ev->event_window = input->focus.pointer->id;
}
ev->dev = _ecore_wl2_mouse_dev_get(input, ev->window);
ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, NULL, NULL);
}
@ -254,6 +293,7 @@ _ecore_wl2_input_mouse_down_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *windo
{
ev->window = window->id;
ev->event_window = window->id;
ev->dev = _ecore_wl2_mouse_dev_get(input, window->id);
}
ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL);
@ -324,6 +364,7 @@ _ecore_wl2_input_mouse_up_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window,
ev->window = window->id;
ev->event_window = window->id;
ev->dev = _ecore_wl2_mouse_dev_get(input, window->id);
ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL);
}
@ -432,6 +473,18 @@ _ecore_wl2_input_symbol_rep_find(xkb_keysym_t keysym, char *buffer, int size, un
snprintf(buffer, size, "Keycode-%u", code);
}
static Eo *
_ecore_wl2_keyboard_dev_get(Ecore_Wl2_Input *input, int window_id)
{
Ecore_Wl2_Input_Devices *devices;
devices = _ecore_wl2_devices_get(input, window_id);
if (devices)
return devices->keyboard_dev;
return NULL;
}
static void
_ecore_wl2_input_key_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, xkb_keysym_t sym, xkb_keysym_t sym_name, unsigned int code, unsigned int state, unsigned int timestamp)
{
@ -466,6 +519,7 @@ _ecore_wl2_input_key_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, xkb_
ev->timestamp = timestamp;
ev->modifiers = input->keyboard.modifiers;
ev->keycode = code;
ev->dev = _ecore_wl2_keyboard_dev_get(input, window->id);
/* DBG("Emitting Key event (%s,%s,%s,%s)\n", ev->keyname, ev->key, ev->compose, ev->string); */
@ -1130,6 +1184,7 @@ static const struct wl_data_device_listener _data_listener =
static void
_seat_cb_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps)
{
Ecore_Wl2_Event_Seat_Capabilities *ev;
Ecore_Wl2_Input *input;
input = data;
@ -1185,14 +1240,44 @@ _seat_cb_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability
wl_touch_destroy(input->wl.touch);
input->wl.touch = NULL;
}
ev = calloc(1, sizeof(Ecore_Wl2_Event_Seat_Capabilities));
EINA_SAFETY_ON_NULL_RETURN(ev);
ev->id = input->id;
ev->pointer_enabled = !!(caps & WL_SEAT_CAPABILITY_POINTER);
ev->keyboard_enabled = !!(caps & WL_SEAT_CAPABILITY_KEYBOARD);
ev->touch_enabled = !!(caps & WL_SEAT_CAPABILITY_TOUCH);
ecore_event_add(ECORE_WL2_EVENT_SEAT_CAPABILITIES_CHANGED, ev, NULL, NULL);
}
static void
_seat_cb_name(void *data EINA_UNUSED, struct wl_seat *seat EINA_UNUSED, const char *name EINA_UNUSED)
_cb_seat_event_free(void *data EINA_UNUSED, void *event)
{
/* NB: No-Op as we don't care about seat name right now.
*
* This will likely change as we hash out remaining multi-seat issues */
Ecore_Wl2_Event_Seat_Name *ev;
ev = event;
eina_stringshare_del(ev->name);
free(ev);
}
static void
_seat_cb_name(void *data, struct wl_seat *seat EINA_UNUSED, const char *name)
{
Ecore_Wl2_Event_Seat_Name *ev;
Ecore_Wl2_Input *input;
input = data;
ev = calloc(1, sizeof(Ecore_Wl2_Event_Seat_Name));
EINA_SAFETY_ON_NULL_RETURN(ev);
ev->id = input->id;
ev->name = eina_stringshare_add(name);
ecore_event_add(ECORE_WL2_EVENT_SEAT_NAME_CHANGED, ev,
_cb_seat_event_free, NULL);
}
static const struct wl_seat_listener _seat_listener =
@ -1233,6 +1318,90 @@ _ecore_wl2_input_cursor_update(void *data)
return ECORE_CALLBACK_RENEW;
}
static void
_ecore_wl2_devices_free(Ecore_Wl2_Input_Devices *devices)
{
if (devices->pointer_dev)
efl_unref(devices->pointer_dev);
if (devices->keyboard_dev)
efl_unref(devices->keyboard_dev);
if (devices->touch_dev)
efl_unref(devices->touch_dev);
free(devices);
}
static Eina_Bool
_ecore_evas_wl_common_cb_device_event(void *data, int type, void *event)
{
Ecore_Wl2_Input_Devices *devs, *devices = NULL;;
Ecore_Wl2_Event_Device *ev = event;
Ecore_Wl2_Input *input = data;
Eina_List *l;
if (input->id != ev->seat_id)
return ECORE_CALLBACK_PASS_ON;
EINA_LIST_FOREACH(input->devices_list, l, devs)
{
if (devs->window_id == ev->window_id)
{
devices = devs;
break;
}
}
if (type == ECORE_WL2_EVENT_DEVICE_ADDED)
{
if (!devices)
{
devices = calloc(1, sizeof(Ecore_Wl2_Input_Devices));
EINA_SAFETY_ON_NULL_RETURN_VAL(devices, ECORE_CALLBACK_PASS_ON);
input->devices_list = eina_list_append(input->devices_list,
devices);
devices->window_id = ev->window_id;
}
if (ev->type == ECORE_WL2_DEVICE_TYPE_POINTER)
devices->pointer_dev = efl_ref(ev->dev);
else if (ev->type == ECORE_WL2_DEVICE_TYPE_KEYBOARD)
devices->keyboard_dev = efl_ref(ev->dev);
else if (ev->type == ECORE_WL2_DEVICE_TYPE_TOUCH)
devices->touch_dev = efl_ref(ev->dev);
return ECORE_CALLBACK_PASS_ON;
}
if (!devices)
return ECORE_CALLBACK_PASS_ON;
if (ev->type == ECORE_WL2_DEVICE_TYPE_SEAT)
{
input->devices_list = eina_list_remove(input->devices_list,
devices);
_ecore_wl2_devices_free(devices);
return ECORE_CALLBACK_PASS_ON;
}
if (ev->type == ECORE_WL2_DEVICE_TYPE_POINTER && devices->pointer_dev)
{
efl_unref(devices->pointer_dev);
devices->pointer_dev = NULL;
}
else if (ev->type == ECORE_WL2_DEVICE_TYPE_KEYBOARD && devices->keyboard_dev)
{
efl_unref(devices->keyboard_dev);
devices->keyboard_dev = NULL;
}
else if (ev->type == ECORE_WL2_DEVICE_TYPE_TOUCH && devices->touch_dev)
{
efl_unref(devices->touch_dev);
devices->touch_dev = NULL;
}
return ECORE_CALLBACK_PASS_ON;
}
void
_ecore_wl2_input_add(Ecore_Wl2_Display *display, unsigned int id, unsigned int version)
{
@ -1241,6 +1410,7 @@ _ecore_wl2_input_add(Ecore_Wl2_Display *display, unsigned int id, unsigned int v
input = calloc(1, sizeof(Ecore_Wl2_Input));
if (!input) return;
input->id = id;
input->display = display;
input->seat_version = version;
input->repeat.rate = 0.025;
@ -1267,11 +1437,19 @@ _ecore_wl2_input_add(Ecore_Wl2_Display *display, unsigned int id, unsigned int v
wl_data_device_manager_get_data_device(display->wl.data_device_manager,
input->wl.seat);
wl_data_device_add_listener(input->data.device, &_data_listener, input);
input->dev_add_handler = ecore_event_handler_add(
ECORE_WL2_EVENT_DEVICE_ADDED, _ecore_evas_wl_common_cb_device_event,
input);
input->dev_remove_handler = ecore_event_handler_add(
ECORE_WL2_EVENT_DEVICE_REMOVED, _ecore_evas_wl_common_cb_device_event,
input);
}
void
_ecore_wl2_input_del(Ecore_Wl2_Input *input)
{
Ecore_Wl2_Input_Devices *devices;
Ecore_Wl2_Display *display;
Eina_Inlist *l = NULL;
Ecore_Wl2_Mouse_Down_Info *info = NULL;
@ -1316,6 +1494,11 @@ _ecore_wl2_input_del(Ecore_Wl2_Input *input)
if (input->wl.seat) wl_seat_destroy(input->wl.seat);
ecore_event_handler_del(input->dev_add_handler);
ecore_event_handler_del(input->dev_remove_handler);
EINA_LIST_FREE(input->devices_list, devices)
_ecore_wl2_devices_free(devices);
display->inputs =
eina_inlist_remove(display->inputs, EINA_INLIST_GET(input));
@ -1341,6 +1524,31 @@ _ecore_wl2_input_cursor_update_stop(Ecore_Wl2_Input *input)
}
}
void
_ecore_wl2_input_window_remove(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window)
{
Ecore_Wl2_Input_Devices *devices;
Eina_List *l, *l_next;
if ((input->focus.pointer) &&
(input->focus.pointer == window))
input->focus.pointer = NULL;
if ((input->focus.keyboard) &&
(input->focus.keyboard == window))
{
input->focus.keyboard = NULL;
ecore_timer_del(input->repeat.timer);
input->repeat.timer = NULL;
}
EINA_LIST_FOREACH_SAFE(input->devices_list, l, l_next, devices)
if (devices->window_id == window->id)
{
_ecore_wl2_devices_free(devices);
input->devices_list = eina_list_remove_list(input->devices_list, l);
}
}
EAPI void
ecore_wl2_input_grab(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, unsigned int button)
{

View File

@ -405,6 +405,11 @@ struct _Ecore_Wl2_Input
Ecore_Wl2_Offer *drag, *selection;
unsigned int seat_version;
unsigned int id;
Ecore_Event_Handler *dev_add_handler;
Ecore_Event_Handler *dev_remove_handler;
Eina_List *devices_list;
};
typedef struct Ecore_Wl2_Event_Window_WWW
@ -435,6 +440,7 @@ void _ecore_wl2_input_grab(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, uns
void _ecore_wl2_input_cursor_set(Ecore_Wl2_Input *input, const char *cursor);
Eina_Bool _ecore_wl2_input_cursor_update(void *data);
void _ecore_wl2_input_cursor_update_stop(Ecore_Wl2_Input *input);
void _ecore_wl2_input_window_remove(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window);
void _ecore_wl2_dnd_add(Ecore_Wl2_Input *input, struct wl_data_offer *offer);
void _ecore_wl2_dnd_enter(Ecore_Wl2_Input *input, struct wl_data_offer *offer, struct wl_surface *surface, int x, int y, uint32_t serial);

View File

@ -488,18 +488,7 @@ ecore_wl2_window_free(Ecore_Wl2_Window *window)
display = window->display;
EINA_INLIST_FOREACH(display->inputs, input)
{
if ((input->focus.pointer) &&
(input->focus.pointer == window))
input->focus.pointer = NULL;
if ((input->focus.keyboard) &&
(input->focus.keyboard == window))
{
input->focus.keyboard = NULL;
ecore_timer_del(input->repeat.timer);
input->repeat.timer = NULL;
}
}
_ecore_wl2_input_window_remove(input, window);
EINA_INLIST_FOREACH_SAFE(window->subsurfs, tmp, subsurf)
_ecore_wl2_subsurf_free(subsurf);

View File

@ -1151,7 +1151,7 @@ EAPI Evas_Device *evas_device_add(Evas *e);
* @see evas_device_del
* @since 1.19
*/
EAPI Evas_Device *evas_device_add_full(Evas *eo_e, const char *name,
EAPI Evas_Device *evas_device_add_full(Evas *e, const char *name,
const char *desc,
Evas_Device *parent_dev,
Evas_Device *emulation_dev,

View File

@ -25,6 +25,17 @@ struct _EE_Wl_Smart_Data
Evas_Coord border_size[4]; // same as border
};
/* local structure for evas devices with IDs */
typedef struct _EE_Wl_Device EE_Wl_Device;
struct _EE_Wl_Device
{
Evas_Device *seat;
Evas_Device *pointer;
Evas_Device *keyboard;
Evas_Device *touch;
unsigned int id;
};
static const Evas_Smart_Cb_Description _smart_callbacks[] =
{
{NULL, NULL}
@ -36,7 +47,7 @@ EVAS_SMART_SUBCLASS_NEW(_smart_frame_type, _ecore_evas_wl_frame,
/* local variables */
static int _ecore_evas_wl_init_count = 0;
static Ecore_Event_Handler *_ecore_evas_wl_event_hdls[8];
static Ecore_Event_Handler *_ecore_evas_wl_event_hdls[12];
static void _ecore_evas_wayland_resize(Ecore_Evas *ee, int location);
@ -438,6 +449,254 @@ _ecore_evas_wl_common_cb_www(void *d EINA_UNUSED, int t EINA_UNUSED, void *event
return ECORE_CALLBACK_RENEW;
}
static void
_ecore_evas_wl_common_cb_device_event_free(void *user_data, void *func_data)
{
efl_unref(user_data);
free(func_data);
}
static void
_ecore_evas_wl_common_device_event_add(int event_type, Ecore_Wl2_Device_Type device_type, unsigned int id, Evas_Device *dev, Ecore_Evas *ee)
{
Ecore_Wl2_Event_Device *ev;
ev = calloc(1, sizeof(Ecore_Wl2_Event_Device));
EINA_SAFETY_ON_NULL_RETURN(ev);
ev->dev = efl_ref(dev);
ev->type = device_type;
ev->seat_id = id;
ev->window_id = ee->prop.window;
ecore_event_add(event_type, ev, _ecore_evas_wl_common_cb_device_event_free,
dev);
}
static Eina_Bool
_ecore_evas_wl_common_cb_global_added(void *d EINA_UNUSED, int t EINA_UNUSED, void *event)
{
Ecore_Wl2_Event_Global *ev = event;
EE_Wl_Device *device;
Ecore_Evas *ee;
Eina_List *l;
char buf[32];
if ((!ev->interface) || (strcmp(ev->interface, "wl_seat")))
return ECORE_CALLBACK_PASS_ON;
snprintf(buf, sizeof(buf), "seat-%u", ev->id);
EINA_LIST_FOREACH(ee_list, l, ee)
{
Ecore_Evas_Engine_Wl_Data *wdata;
Evas_Device *dev;
device = calloc(1, sizeof(EE_Wl_Device));
EINA_SAFETY_ON_NULL_GOTO(device, err_device);
dev = evas_device_add_full(ee->evas, buf, "Wayland seat",
NULL, NULL,
EVAS_DEVICE_CLASS_SEAT,
EVAS_DEVICE_SUBCLASS_NONE);
EINA_SAFETY_ON_NULL_GOTO(dev, err_dev);
device->seat = dev;
device->id = ev->id;
wdata = ee->engine.data;
wdata->devices_list = eina_list_append(wdata->devices_list, device);
_ecore_evas_wl_common_device_event_add(ECORE_WL2_EVENT_DEVICE_ADDED,
ECORE_WL2_DEVICE_TYPE_SEAT,
ev->id, dev, ee);
}
return ECORE_CALLBACK_PASS_ON;
err_dev:
free(device);
err_device:
return ECORE_CALLBACK_PASS_ON;
}
static void
_ecore_evas_wl_common_device_free(EE_Wl_Device *device)
{
if (device->seat)
evas_device_del(device->seat);
if (device->pointer)
evas_device_del(device->pointer);
if (device->keyboard)
evas_device_del(device->keyboard);
if (device->touch)
evas_device_del(device->touch);
free(device);
}
static Eina_Bool
_ecore_evas_wl_common_cb_global_removed(void *d EINA_UNUSED, int t EINA_UNUSED, void *event)
{
Ecore_Wl2_Event_Global *ev = event;
Ecore_Evas *ee;
Eina_List *l, *ll;
if ((!ev->interface) || (strcmp(ev->interface, "wl_seat")))
return ECORE_CALLBACK_PASS_ON;
EINA_LIST_FOREACH(ee_list, l, ee)
{
Ecore_Evas_Engine_Wl_Data *wdata;
EE_Wl_Device *device;
Eina_Bool found = EINA_FALSE;
wdata = ee->engine.data;
EINA_LIST_FOREACH(wdata->devices_list, ll, device)
{
if (device->id == ev->id)
{
found = EINA_TRUE;
break;
}
}
if (found)
{
_ecore_evas_wl_common_device_event_add(
ECORE_WL2_EVENT_DEVICE_REMOVED, ECORE_WL2_DEVICE_TYPE_SEAT,
ev->id, device->seat, ee);
wdata->devices_list = eina_list_remove(wdata->devices_list,
device);
_ecore_evas_wl_common_device_free(device);
}
}
return ECORE_CALLBACK_PASS_ON;
}
static Eina_Bool
_ecore_evas_wl_common_cb_seat_name_changed(void *d EINA_UNUSED, int t EINA_UNUSED, void *event)
{
Ecore_Wl2_Event_Seat_Name *ev = event;
Ecore_Evas *ee;
Eina_List *l, *ll;
EINA_LIST_FOREACH(ee_list, l, ee)
{
Ecore_Evas_Engine_Wl_Data *wdata;
EE_Wl_Device *device;
wdata = ee->engine.data;
EINA_LIST_FOREACH(wdata->devices_list, ll, device)
{
if (device->id == ev->id)
{
evas_device_name_set(device->seat, ev->name);
break;
}
}
}
return ECORE_CALLBACK_PASS_ON;
}
static Eina_Bool
_ecore_evas_wl_common_cb_seat_capabilities_changed(void *d EINA_UNUSED, int t EINA_UNUSED, void *event)
{
Ecore_Wl2_Event_Seat_Capabilities *ev = event;
Ecore_Evas *ee;
Eina_List *l, *ll;
EINA_LIST_FOREACH(ee_list, l, ee)
{
Ecore_Evas_Engine_Wl_Data *wdata;
EE_Wl_Device *device;
wdata = ee->engine.data;
EINA_LIST_FOREACH(wdata->devices_list, ll, device)
{
if (device->id == ev->id)
{
if (ev->pointer_enabled && !device->pointer)
{
device->pointer = evas_device_add_full(
ee->evas, "Mouse",
"A wayland pointer device",
device->seat, NULL,
EVAS_DEVICE_CLASS_MOUSE,
EVAS_DEVICE_SUBCLASS_NONE);
_ecore_evas_wl_common_device_event_add(
ECORE_WL2_EVENT_DEVICE_ADDED,
ECORE_WL2_DEVICE_TYPE_POINTER,
ev->id, device->pointer, ee);
}
else if (!ev->pointer_enabled && device->pointer)
{
_ecore_evas_wl_common_device_event_add(
ECORE_WL2_EVENT_DEVICE_REMOVED,
ECORE_WL2_DEVICE_TYPE_POINTER,
ev->id, NULL, ee);
evas_device_del(device->pointer);
device->pointer = NULL;
}
if (ev->keyboard_enabled && !device->keyboard)
{
device->keyboard = evas_device_add_full(
ee->evas, "Keyboard",
"A wayland keyboard device",
device->seat, NULL,
EVAS_DEVICE_CLASS_KEYBOARD,
EVAS_DEVICE_SUBCLASS_NONE);
_ecore_evas_wl_common_device_event_add(
ECORE_WL2_EVENT_DEVICE_ADDED,
ECORE_WL2_DEVICE_TYPE_KEYBOARD,
ev->id, device->keyboard, ee);
}
else if (!ev->keyboard_enabled && device->keyboard)
{
_ecore_evas_wl_common_device_event_add(
ECORE_WL2_EVENT_DEVICE_REMOVED,
ECORE_WL2_DEVICE_TYPE_KEYBOARD,
ev->id, NULL, ee);
evas_device_del(device->keyboard);
device->keyboard = NULL;
}
if (ev->touch_enabled && !device->touch)
{
device->touch = evas_device_add_full(
ee->evas, "Touch",
"A wayland touch device",
device->seat, NULL,
EVAS_DEVICE_CLASS_TOUCH,
EVAS_DEVICE_SUBCLASS_NONE);
_ecore_evas_wl_common_device_event_add(
ECORE_WL2_EVENT_DEVICE_ADDED,
ECORE_WL2_DEVICE_TYPE_TOUCH,
ev->id, device->touch, ee);
}
else if (!ev->touch_enabled && device->touch)
{
_ecore_evas_wl_common_device_event_add(
ECORE_WL2_EVENT_DEVICE_REMOVED,
ECORE_WL2_DEVICE_TYPE_TOUCH,
ev->id, NULL, ee);
evas_device_del(device->touch);
device->touch = NULL;
}
break;
}
}
}
return ECORE_CALLBACK_PASS_ON;
}
int
_ecore_evas_wl_common_init(void)
{
@ -470,6 +729,20 @@ _ecore_evas_wl_common_init(void)
_ecore_evas_wl_event_hdls[7] =
ecore_event_handler_add(ECORE_WL2_EVENT_DISCONNECT,
_ecore_evas_wl_common_cb_disconnect, NULL);
_ecore_evas_wl_event_hdls[8] =
ecore_event_handler_add(ECORE_WL2_EVENT_GLOBAL_ADDED,
_ecore_evas_wl_common_cb_global_added, NULL);
_ecore_evas_wl_event_hdls[9] =
ecore_event_handler_add(ECORE_WL2_EVENT_GLOBAL_REMOVED,
_ecore_evas_wl_common_cb_global_removed, NULL);
_ecore_evas_wl_event_hdls[10] =
ecore_event_handler_add(ECORE_WL2_EVENT_SEAT_NAME_CHANGED,
_ecore_evas_wl_common_cb_seat_name_changed, NULL);
_ecore_evas_wl_event_hdls[11] =
ecore_event_handler_add(ECORE_WL2_EVENT_SEAT_CAPABILITIES_CHANGED,
_ecore_evas_wl_common_cb_seat_capabilities_changed,
NULL);
ecore_event_evas_init();
return _ecore_evas_wl_init_count;
@ -512,6 +785,7 @@ void
_ecore_evas_wl_common_free(Ecore_Evas *ee)
{
Ecore_Evas_Engine_Wl_Data *wdata;
EE_Wl_Device *device;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
@ -521,16 +795,14 @@ _ecore_evas_wl_common_free(Ecore_Evas *ee)
ee_list = eina_list_remove(ee_list, ee);
eina_list_free(wdata->regen_objs);
if (wdata->anim_callback) wl_callback_destroy(wdata->anim_callback);
wdata->anim_callback = NULL;
ecore_event_handler_del(wdata->sync_handler);
if (wdata->win) ecore_wl2_window_free(wdata->win);
wdata->win = NULL;
ecore_wl2_display_disconnect(wdata->display);
EINA_LIST_FREE(wdata->devices_list, device)
free(device);
free(wdata);
ecore_event_window_unregister(ee->prop.window);

View File

@ -49,8 +49,8 @@ struct _Ecore_Evas_Engine_Wl_Data
int x_rel;
int y_rel;
uint32_t timestamp;
Eina_List *devices_list;
Eina_Bool dragging : 1;
Eina_Bool sync_done : 1;
Eina_Bool defer_show : 1;
Eina_Bool reset_pending : 1;