wayland/drm: create evas_devices and add device pointer to input events

this is still semi-broken if a seat has many pointer-ish type devices since
pointer devices in ecore-evas were never correctly implemented to be 1:1 with
seat:cursor relationships

@feature
This commit is contained in:
Mike Blumenkrantz 2017-05-26 16:34:10 -04:00
parent 6775b23212
commit ed4e54ebe2
6 changed files with 102 additions and 4 deletions

View File

@ -271,6 +271,7 @@ modules_ecore_evas_engines_drm_module_la_SOURCES = $(DRMSOURCES)
modules_ecore_evas_engines_drm_module_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
@ECORE_EVAS_CFLAGS@ \
@ECORE_DRM2_CFLAGS@ \
@ELPUT_CFLAGS@ \
-I$(top_srcdir)/src/modules/evas/engines/drm \
-I$(top_srcdir)/src/modules/evas/engines/gl_drm
modules_ecore_evas_engines_drm_module_la_LIBADD = \

View File

@ -20,6 +20,7 @@
# include <sys/ioctl.h>
# include <dlfcn.h>
#ifndef DRM2_NODEFS
extern int _ecore_drm2_log_dom;
extern Eina_Bool _ecore_drm2_use_atomic;
@ -52,7 +53,7 @@ extern Eina_Bool _ecore_drm2_use_atomic;
# undef CRIT
# endif
# define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_drm2_log_dom, __VA_ARGS__)
#endif
/* The following defines and structures were borrowed from drm.h */
/**

View File

@ -300,6 +300,7 @@ _keyboard_key_send(Elput_Device *dev, enum libinput_key_state state, const char
ev->modifiers = dev->seat->modifiers;
ev->timestamp = timestamp;
ev->same_screen = 1;
ev->dev = dev->evas_device;
ev->window = dev->seat->manager->window;
ev->event_window = dev->seat->manager->window;
@ -803,6 +804,7 @@ _pointer_motion_send(Elput_Device *edev)
ev->root_window = edev->seat->manager->window;
ev->timestamp = ptr->timestamp;
ev->same_screen = 1;
ev->dev = edev->evas_device;
ev->x = ptr->x;
ev->y = ptr->y;
@ -912,6 +914,7 @@ _pointer_button_send(Elput_Device *edev, enum libinput_button_state state)
ev->root_window = edev->seat->manager->window;
ev->timestamp = ptr->timestamp;
ev->same_screen = 1;
ev->dev = edev->evas_device;
ev->x = ptr->x;
ev->y = ptr->y;
@ -1033,6 +1036,7 @@ _pointer_axis_send(Elput_Device *dev, int direction, int value)
ev->root_window = dev->seat->manager->window;
ev->timestamp = ptr->timestamp;
ev->same_screen = 1;
ev->dev = dev->evas_device;
ev->x = ptr->x;
ev->y = ptr->y;
@ -1189,6 +1193,7 @@ _touch_motion_send(Elput_Device *dev)
ev->root_window = dev->seat->manager->window;
ev->timestamp = touch->timestamp;
ev->same_screen = 1;
ev->dev = dev->evas_device;
ev->x = lround(touch->x);
ev->y = lround(touch->y);
@ -1447,6 +1452,7 @@ _tablet_tool_axis(struct libinput_device *idev, struct libinput_event_tablet_too
ev->root_window = dev->seat->manager->window;
ev->timestamp = ptr->timestamp;
ev->naxis = num;
ev->dev = dev->evas_device;
ev->axis = axis = calloc(num, sizeof(Ecore_Axis));
for (i = 0; i < num; i++)
{

View File

@ -28,6 +28,7 @@
# include <systemd/sd-login.h>
# endif
#ifndef ELPUT_NODEFS
# ifdef ELPUT_DEFAULT_LOG_COLOR
# undef ELPUT_DEFAULT_LOG_COLOR
# endif
@ -59,7 +60,7 @@ extern int _elput_log_dom;
# undef CRIT
# endif
# define CRIT(...) EINA_LOG_DOM_CRIT(_elput_log_dom, __VA_ARGS__)
#endif
typedef struct _Elput_Interface
{
Eina_Bool (*connect)(Elput_Manager **manager, const char *seat, unsigned int tty);
@ -218,6 +219,7 @@ struct _Elput_Device
Elput_Device_Caps caps;
Eina_Hash *key_remap_hash;
Eo *evas_device;
Eina_Bool left_handed : 1;
Eina_Bool key_remap : 1;

View File

@ -1006,9 +1006,11 @@ evas_output_method_set(Evas *eo_e, int render_method)
output->info = e->engine.func->info(eo_e);
}
// Wayland already handles seats.
// Wayland/drm already handles seats.
if (em->definition && (eina_streq(em->definition->name, "wayland_shm") ||
eina_streq(em->definition->name, "wayland_egl")))
eina_streq(em->definition->name, "wayland_egl") ||
eina_streq(em->definition->name, "drm") ||
eina_streq(em->definition->name, "gl_drm")))
return;
e->default_seat = evas_device_add_full(eo_e, "default", "The default seat",

View File

@ -13,6 +13,12 @@
#include <Ecore_Drm2.h>
#include <Evas_Engine_Drm.h>
#define DRM2_NODEFS
#include "ecore_drm2_private.h"
#define ELPUT_NODEFS
#include "elput_private.h"
#ifdef BUILD_ECORE_EVAS_GL_DRM
# include <Evas_Engine_GL_Drm.h>
# include <dlfcn.h>
@ -83,11 +89,80 @@ typedef struct _Ecore_Evas_Engine_Drm_Data
Ecore_Fd_Handler *hdlr;
Ecore_Drm2_Device *dev;
Ecore_Drm2_Output *output;
Evas_Device *seat;
Eina_Bool pending : 1;
Eina_Bool ticking : 1;
} Ecore_Evas_Engine_Drm_Data;
static int _drm_init_count = 0;
static Eina_List *handlers;
static Eina_List *canvases;
static Eina_Bool
_drm_device_change(void *d EINA_UNUSED, int t EINA_UNUSED, void *event)
{
Elput_Event_Device_Change *ev = event;
const Eina_List *l;
Ecore_Evas *ee;
Ecore_Evas_Engine_Drm_Data *edata;
Elput_Seat *seat;
Elput_Manager *manager;
Eina_Bool found = EINA_FALSE;
Elput_Device_Caps caps;
Evas_Device_Class devclass = EVAS_DEVICE_CLASS_NONE;
Eo *dev;
seat = elput_device_seat_get(ev->device);
manager = elput_seat_manager_get(seat);
caps = elput_device_caps_get(ev->device);
EINA_LIST_FOREACH(canvases, l, ee)
{
edata = ee->engine.data;
found = edata->dev->em == manager;
if (found) break;
}
if (!found) return ECORE_CALLBACK_RENEW;
if (caps & ELPUT_DEVICE_CAPS_TABLET_TOOL)
devclass = EVAS_DEVICE_CLASS_PEN; // idk how "pen" is a device class?
else if (caps & ELPUT_DEVICE_CAPS_POINTER)
devclass = EVAS_DEVICE_CLASS_MOUSE;
else if (caps & ELPUT_DEVICE_CAPS_TOUCH)
devclass = EVAS_DEVICE_CLASS_TOUCH;
else if (caps & ELPUT_DEVICE_CAPS_KEYBOARD)
devclass = EVAS_DEVICE_CLASS_KEYBOARD;
switch (ev->type)
{
case ELPUT_DEVICE_ADDED:
{
if (!edata->seat)
{
Eina_Stringshare *name = elput_seat_name_get(seat);
edata->seat = evas_device_add_full(ee->evas, name,
"drm seat", NULL, NULL, EVAS_DEVICE_CLASS_SEAT, EVAS_DEVICE_CLASS_NONE);
evas_device_seat_id_set(edata->seat, strtol(name, NULL, 10));
}
dev = evas_device_add_full(ee->evas, elput_device_output_name_get(ev->device),
"drm device", edata->seat, NULL, devclass, EVAS_DEVICE_CLASS_NONE);
ev->device->evas_device = dev;
break;
}
case ELPUT_DEVICE_REMOVED:
{
EINA_LIST_FOREACH(evas_device_list(ee->evas, edata->seat), l, dev)
{
if (dev != ev->device->evas_device) continue;
evas_device_del(dev);
break;
}
break;
}
}
return ECORE_CALLBACK_RENEW;
}
static int
_ecore_evas_drm_init(Ecore_Evas *ee, Ecore_Evas_Engine_Drm_Data *edata, const char *device)
@ -130,6 +205,11 @@ _ecore_evas_drm_init(Ecore_Evas *ee, Ecore_Evas_Engine_Drm_Data *edata, const ch
else WRN("Could not find output at %d %d", edata->x, edata->y);
ecore_event_evas_init();
if (!handlers)
{
handlers = eina_list_append(handlers,
ecore_event_handler_add(ELPUT_EVENT_DEVICE_CHANGE, _drm_device_change, NULL));
}
return _drm_init_count;
@ -146,6 +226,7 @@ init_err:
static int
_ecore_evas_drm_shutdown(Ecore_Evas_Engine_Drm_Data *edata)
{
Ecore_Event_Handler *h;
if (--_drm_init_count != 0) return _drm_init_count;
ecore_drm2_outputs_destroy(edata->dev);
@ -153,6 +234,8 @@ _ecore_evas_drm_shutdown(Ecore_Evas_Engine_Drm_Data *edata)
ecore_drm2_device_free(edata->dev);
ecore_drm2_shutdown();
ecore_event_evas_shutdown();
EINA_LIST_FREE(handlers, h)
ecore_event_handler_del(h);
return _drm_init_count;
}
@ -165,6 +248,7 @@ _drm_free(Ecore_Evas *ee)
ecore_evas_input_event_unregister(ee);
edata = ee->engine.data;
canvases = eina_list_remove(canvases, ee);
_ecore_evas_drm_shutdown(edata);
free(edata);
}
@ -843,6 +927,8 @@ _ecore_evas_new_internal(const char *device, int x, int y, int w, int h, Eina_Bo
edata->hdlr =
ecore_main_fd_handler_add(edata->fd, ECORE_FD_READ, _cb_drm_event, ee,
NULL, NULL);
canvases = eina_list_append(canvases, ee);
return ee;
eng_err: