ecore-drm: added drm launcher that is allow to determine whether to launch with logind or root privilege.

Summary:
- allow to launch drm backend without systemd-logind with root privilege.
- allow to open drm device node via logind, not directly open it, in case exist systemd-logind.
- fixes issue that couldn't switch session, because ecore-drm couldn't drop master to drm device with no permission. (allow to switch session appropriate.)

Reviewers: gwanglim, devilhorns

Subscribers: torori, cedric

Differential Revision: https://phab.enlightenment.org/D1704
This commit is contained in:
Seunghun Lee 2014-12-09 09:36:42 -05:00 committed by Chris Michael
parent 05006e6463
commit b10ab1a86f
12 changed files with 607 additions and 79 deletions

View File

@ -673,13 +673,18 @@ fi
AM_CONDITIONAL([HAVE_SYSTEMD_USER_SESSION], [test "x${have_systemd_user_session}" = "xyes"])
AC_SUBST([USER_SESSION_DIR])
if test "x${have_systemd_pkg}" = "xauto" -o "x${have_systemd_pkg}" = "xyes"; then
PKG_CHECK_MODULES([SYSTEMD], [libsystemd-daemon >= 192 libsystemd-journal >= 192],
[have_systemd_pkg="yes"],
[have_systemd_pkg="no"])
fi
PKG_CHECK_MODULES(SYSTEMD_LOGIN, [libsystemd-login >= 198],
[have_systemd_login=yes], [have_systemd_login=no])
AS_IF([test "x$have_systemd_login" = "xyes"],
[AC_DEFINE([HAVE_SYSTEMD_LOGIN], [1], [Have systemd-login])])
AM_CONDITIONAL(HAVE_SYSTEMD_LOGIN, test "x$have_systemd_login" = "xyes")
# check for systemd library if requested
if test "x${want_systemd}" = "xyes" -a "x${have_systemd_pkg}" = "xno"; then
AC_MSG_ERROR([Systemd dependencie requested but not found])
@ -3072,7 +3077,7 @@ EFL_INTERNAL_DEPEND_PKG([ECORE_DRM], [eeze])
EFL_INTERNAL_DEPEND_PKG([ECORE_DRM], [eo])
EFL_INTERNAL_DEPEND_PKG([ECORE_DRM], [eina])
EFL_DEPEND_PKG([ECORE_DRM], [DRM], [libdrm >= 2.4 xkbcommon >= 0.3.0 libsystemd-login >= 192 gbm])
EFL_DEPEND_PKG([ECORE_DRM], [DRM], [libdrm >= 2.4 xkbcommon >= 0.3.0 gbm])
EFL_EVAL_PKGS([ECORE_DRM])

View File

@ -16,10 +16,17 @@ lib/ecore_drm/ecore_drm_inputs.c \
lib/ecore_drm/ecore_drm_output.c \
lib/ecore_drm/ecore_drm_tty.c \
lib/ecore_drm/ecore_drm_device.c \
lib/ecore_drm/ecore_drm_dbus.c \
lib/ecore_drm/ecore_drm_launcher.c \
lib/ecore_drm/ecore_drm.c \
lib/ecore_drm/ecore_drm_logind.h \
lib/ecore_drm/ecore_drm_private.h
if HAVE_SYSTEMD_LOGIN
lib_ecore_drm_libecore_drm_la_SOURCES += \
lib/ecore_drm/ecore_drm_logind.c \
lib/ecore_drm/ecore_drm_dbus.c
endif
lib_ecore_drm_libecore_drm_la_CPPFLAGS = \
-I$(top_builddir)/src/lib/efl \
@ECORE_DRM_CFLAGS@ \

View File

@ -194,4 +194,6 @@ EAPI Eina_Bool ecore_drm_sprites_crtc_supported(Ecore_Drm_Output *output, unsign
EAPI Ecore_Drm_Fb *ecore_drm_fb_create(Ecore_Drm_Device *dev, int width, int height);
EAPI void ecore_drm_fb_destroy(Ecore_Drm_Fb *fb);
EAPI Eina_Bool ecore_drm_launcher_connect(Ecore_Drm_Device *dev);
EAPI void ecore_drm_launcher_disconnect(Ecore_Drm_Device *dev);
#endif

View File

@ -6,7 +6,6 @@
/* local variables */
static int _ecore_drm_init_count = 0;
static char *sid;
/* external variables */
int _ecore_drm_log_dom = -1;
@ -65,12 +64,6 @@ ecore_drm_init(void)
if (!eina_log_domain_level_check(_ecore_drm_log_dom, EINA_LOG_LEVEL_DBG))
eina_log_domain_level_set("ecore_drm", EINA_LOG_LEVEL_DBG);
/* get sd-login properties we need */
if (sd_pid_get_session(getpid(), &sid) < 0) goto sd_err;
/* try to init dbus */
if (!_ecore_drm_dbus_init(sid)) goto dbus_err;
/* try to init eeze */
if (!eeze_init()) goto eeze_err;
@ -78,10 +71,6 @@ ecore_drm_init(void)
return _ecore_drm_init_count;
eeze_err:
_ecore_drm_dbus_shutdown();
dbus_err:
free(sid);
sd_err:
eina_log_domain_unregister(_ecore_drm_log_dom);
_ecore_drm_log_dom = -1;
log_err:
@ -115,9 +104,6 @@ ecore_drm_shutdown(void)
/* close eeze */
eeze_shutdown();
/* cleanup dbus */
_ecore_drm_dbus_shutdown();
/* shutdown ecore_event */
ecore_event_shutdown();
@ -131,8 +117,6 @@ ecore_drm_shutdown(void)
/* shutdown eina */
eina_shutdown();
free(sid);
/* return init count */
return _ecore_drm_init_count;
}

View File

@ -175,7 +175,7 @@ _ecore_drm_dbus_session_release(const char *session)
return EINA_TRUE;
}
static void
void
_ecore_drm_dbus_device_release(uint32_t major, uint32_t minor)
{
Eldbus_Proxy *proxy;
@ -199,11 +199,35 @@ _ecore_drm_dbus_device_release(uint32_t major, uint32_t minor)
eldbus_proxy_send(proxy, msg, NULL, NULL, -1);
}
static int
_ecore_drm_dbus_device_take(uint32_t major, uint32_t minor, Eldbus_Message_Cb callback, const void *data)
static void
_cb_device_taken(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
{
const char *errname, *errmsg;
Ecore_Drm_Open_Cb callback = NULL;
Eina_Bool b = EINA_FALSE;
int fd = -1;
if (eldbus_message_error_get(msg, &errname, &errmsg))
{
ERR("Eldbus Message Error: %s %s", errname, errmsg);
goto eldbus_err;
}
/* DBUS_TYPE_UNIX_FD == 'h' */
if (!eldbus_message_arguments_get(msg, "hb", &fd, &b))
ERR("\tCould not get UNIX_FD from eldbus message: %d %d", fd, b);
eldbus_err:
callback = (Ecore_Drm_Open_Cb)eldbus_pending_data_del(pending, "callback");
if (callback) callback(data, fd, b);
}
int
_ecore_drm_dbus_device_take(uint32_t major, uint32_t minor, Ecore_Drm_Open_Cb callback, void *data)
{
Eldbus_Proxy *proxy;
Eldbus_Message *msg;
Eldbus_Pending *pending;
/* try to get the Session proxy */
if (!(proxy = eldbus_proxy_get(dobj, "org.freedesktop.login1.Session")))
@ -219,11 +243,45 @@ _ecore_drm_dbus_device_take(uint32_t major, uint32_t minor, Eldbus_Message_Cb ca
}
eldbus_message_arguments_append(msg, "uu", major, minor);
eldbus_proxy_send(proxy, msg, callback, data, -1);
pending = eldbus_proxy_send(proxy, msg, _cb_device_taken, data, -1);
if (callback) eldbus_pending_data_set(pending, "callback", callback);
return 1;
}
int
_ecore_drm_dbus_device_take_no_pending(uint32_t major, uint32_t minor, Eina_Bool *paused_out, double timeout)
{
Eldbus_Proxy *proxy;
Eldbus_Message *msg, *reply;
Eina_Bool b;
int fd;
/* try to get the Session proxy */
if (!(proxy = eldbus_proxy_get(dobj, "org.freedesktop.login1.Session")))
{
ERR("Could not get eldbus session proxy");
return -1;
}
if (!(msg = eldbus_proxy_method_call_new(proxy, "TakeDevice")))
{
ERR("Could not create method call for proxy");
return -1;
}
if (!eldbus_message_arguments_append(msg, "uu", major, minor))
return -1;
reply = eldbus_proxy_send_and_block(proxy, msg, timeout);
if (!eldbus_message_arguments_get(reply, "hb", &fd, &b))
return -1;
if (paused_out) *paused_out = b;
return fd;
}
int
_ecore_drm_dbus_init(const char *session)
{
@ -343,25 +401,3 @@ _ecore_drm_dbus_shutdown(void)
return _dbus_init_count;
}
void
_ecore_drm_dbus_device_open(const char *device, Eldbus_Message_Cb callback, const void *data)
{
struct stat st;
if (stat(device, &st) < 0) return;
if (!S_ISCHR(st.st_mode)) return;
_ecore_drm_dbus_device_take(major(st.st_rdev), minor(st.st_rdev), callback, data);
}
void
_ecore_drm_dbus_device_close(const char *device)
{
struct stat st;
if (stat(device, &st) < 0) return;
if (!S_ISCHR(st.st_mode)) return;
_ecore_drm_dbus_device_release(major(st.st_rdev), minor(st.st_rdev));
}

View File

@ -254,7 +254,8 @@ ecore_drm_device_open(Ecore_Drm_Device *dev)
/* check for valid device */
if ((!dev) || (!dev->drm.name)) return EINA_FALSE;
dev->drm.fd = open(dev->drm.name, O_RDWR | O_CLOEXEC);
/* DRM device node is needed immediately to keep going. */
dev->drm.fd = _ecore_drm_launcher_device_open_no_pending(dev->drm.name, O_RDWR);
if (dev->drm.fd < 0) return EINA_FALSE;
DBG("Opened Device %s : %d", dev->drm.name, dev->drm.fd);
@ -319,7 +320,7 @@ ecore_drm_device_close(Ecore_Drm_Device *dev)
if (dev->drm.hdlr) ecore_main_fd_handler_del(dev->drm.hdlr);
dev->drm.hdlr = NULL;
close(dev->drm.fd);
_ecore_drm_launcher_device_close(dev->drm.name, dev->drm.fd);
/* reset device fd */
dev->drm.fd = -1;

View File

@ -57,29 +57,18 @@ flag_err:
}
static void
_cb_device_opened(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
_cb_device_opened(void *data, int fd, Eina_Bool paused EINA_UNUSED)
{
Ecore_Drm_Device_Open_Data *d;
Ecore_Drm_Evdev *edev;
Eina_Bool b = EINA_FALSE;
const char *errname, *errmsg;
int fd = -1;
if (!(d = data)) return;
if (eldbus_message_error_get(msg, &errname, &errmsg))
{
ERR("Eldbus Message Error: %s %s", errname, errmsg);
ERR("\tFailed to open device: %s", d->node);
return;
}
/* DBG("Input Device Opened: %s", d->node); */
/* DBUS_TYPE_UNIX_FD == 'h' */
if (!eldbus_message_arguments_get(msg, "hb", &fd, &b))
if (fd < 0)
{
ERR("\tCould not get UNIX_FD from eldbus message: %d %d", fd, b);
ERR("\tFailed to open device: %s", d->node);
goto cleanup;
}
@ -100,7 +89,7 @@ _cb_device_opened(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending
goto cleanup;
release:
_ecore_drm_dbus_device_close(d->node);
_ecore_drm_launcher_device_close(d->node, fd);
cleanup:
eina_stringshare_del(d->node);
free(d);
@ -162,7 +151,8 @@ _device_add(Ecore_Drm_Input *input, const char *device)
DBG("\tDevice Path: %s", data->node);
_ecore_drm_dbus_device_open(data->node, _cb_device_opened, data);
if (!_ecore_drm_launcher_device_open(data->node, _cb_device_opened, data, O_RDWR | O_NONBLOCK))
goto dev_err;
return EINA_TRUE;
@ -311,7 +301,7 @@ ecore_drm_inputs_destroy(Ecore_Drm_Device *dev)
EINA_LIST_FREE(seat->devices, edev)
{
_ecore_drm_dbus_device_close(edev->path);
_ecore_drm_launcher_device_close(edev->path, edev->fd);
_ecore_drm_evdev_device_destroy(edev);
}
}

View File

@ -0,0 +1,139 @@
#include "ecore_drm_private.h"
#include "ecore_drm_logind.h"
static Eina_Bool logind = EINA_FALSE;
EAPI Eina_Bool
ecore_drm_launcher_connect(Ecore_Drm_Device *dev)
{
if (!(logind = _ecore_drm_logind_connect(dev)))
{
DBG("Launcher: Not Support loignd\n");
if (geteuid() == 0)
{
DBG("Launcher: Try to keep going with root privilege\n");
if (!ecore_drm_tty_open(dev, NULL))
{
ERR("Launcher: failed to open tty with root privilege\n");
return EINA_FALSE;
}
}
else
{
ERR("Launcher: Need Root Privilege or logind\n");
return EINA_FALSE;
}
}
DBG("Launcher: Success Connect\n");
return EINA_TRUE;
}
EAPI void
ecore_drm_launcher_disconnect(Ecore_Drm_Device *dev)
{
if (logind)
{
logind = EINA_FALSE;
_ecore_drm_logind_disconnect(dev);
}
else
{
ecore_drm_tty_close(dev);
}
}
static int
_device_flags_set(int fd, int flags)
{
int fl;
fl = fcntl(fd, F_GETFL);
if (fl < 0)
return -1;
if (flags & O_NONBLOCK)
fl |= O_NONBLOCK;
if (fcntl(fd, F_SETFL, fl) < 0)
return -1;
fl = fcntl(fd, F_GETFD);
if (fl < 0)
return -1;
if (!(flags & O_CLOEXEC))
fl &= ~FD_CLOEXEC;
if (fcntl(fd, F_SETFD, fl) < 0)
return -1;
return fd;
}
Eina_Bool
_ecore_drm_launcher_device_open(const char *device, Ecore_Drm_Open_Cb callback, void *data, int flags)
{
int fd = -1;
struct stat s;
if (logind)
{
if (!_ecore_drm_logind_device_open(device, callback, data))
return EINA_FALSE;
}
else
{
fd = open(device, flags | O_CLOEXEC);
if (fd < 0) return EINA_FALSE;
if (fstat(fd, &s) == -1)
{
close(fd);
fd = -1;
return EINA_FALSE;
}
callback(data, fd, EINA_FALSE);
}
return EINA_TRUE;
}
int
_ecore_drm_launcher_device_open_no_pending(const char *device, int flags)
{
int fd = -1;
struct stat s;
if (logind)
{
fd = _ecore_drm_logind_device_open_no_pending(device);
if ((fd = _device_flags_set(fd, flags)) == -1)
{
_ecore_drm_logind_device_close(device);
return -1;
}
}
else
{
fd = open(device, flags, flags | O_CLOEXEC);
if (fd < 0) return fd;
if (fstat(fd, &s) == -1)
{
close(fd);
return -1;
}
}
DBG("Device opened %s", device);
return fd;
}
void
_ecore_drm_launcher_device_close(const char *device, int fd)
{
if (logind)
return _ecore_drm_logind_device_close(device);
close(fd);
}

View File

@ -0,0 +1,310 @@
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/vt.h>
#include <linux/kd.h>
#include <linux/major.h>
#include "ecore_drm_private.h"
#include "ecore_drm_logind.h"
#ifndef KDSKBMUTE
# define KDSKBMUTE 0x4B51
#endif
static char *sid;
static Eina_Bool
_ecore_drm_logind_cb_vt_switch(void *data, int type EINA_UNUSED, void *event)
{
Ecore_Drm_Device *dev;
Ecore_Event_Key *ev;
int keycode;
int vt;
dev = data;
ev = event;
keycode = ev->keycode - 8;
if ((ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) &&
(ev->modifiers & ECORE_EVENT_MODIFIER_ALT) &&
(keycode >= KEY_F1) && (keycode <= KEY_F8))
{
vt = (keycode - KEY_F1 + 1);
if (ioctl(dev->tty.fd, VT_ACTIVATE, vt) < 0)
ERR("Failed to activate vt: %m");
}
return ECORE_CALLBACK_PASS_ON;
}
static Eina_Bool
_ecore_drm_logind_cb_vt_signal(void *data, int type EINA_UNUSED, void *event)
{
Ecore_Drm_Device *dev;
Ecore_Event_Signal_User *ev;
siginfo_t sigdata;
dev = data;
ev = event;
sigdata = ev->data;
if (sigdata.si_code != SI_KERNEL) return ECORE_CALLBACK_RENEW;
if (ev->number == 1)
{
Ecore_Drm_Input *input;
Ecore_Drm_Output *output;
Ecore_Drm_Sprite *sprite;
Eina_List *l;
/* disable inputs (suspends) */
EINA_LIST_FOREACH(dev->inputs, l, input)
ecore_drm_inputs_disable(input);
/* disable hardware cursor */
EINA_LIST_FOREACH(dev->outputs, l, output)
ecore_drm_output_cursor_size_set(output, 0, 0, 0);
/* disable sprites */
EINA_LIST_FOREACH(dev->sprites, l, sprite)
ecore_drm_sprites_fb_set(sprite, 0, 0);
if (!ecore_drm_tty_release(dev))
ERR("Could not release VT: %m");
}
else if (ev->number == 2)
{
if (ecore_drm_tty_acquire(dev))
{
Ecore_Drm_Output *output;
Ecore_Drm_Input *input;
Eina_List *l;
/* set output mode */
EINA_LIST_FOREACH(dev->outputs, l, output)
ecore_drm_output_enable(output);
/* enable inputs */
EINA_LIST_FOREACH(dev->inputs, l, input)
ecore_drm_inputs_enable(input);
}
else
ERR("Could not acquire VT: %m");
}
return ECORE_CALLBACK_PASS_ON;
}
static Eina_Bool
_ecore_drm_logind_tty_setup(Ecore_Drm_Device *dev)
{
struct stat st;
int kmode;
struct vt_mode vtmode = { 0 };
if (fstat(dev->tty.fd, &st) == -1)
{
ERR("Failed to get stats for tty: %m");
return EINA_FALSE;
}
if (ioctl(dev->tty.fd, KDGETMODE, &kmode))
{
ERR("Could not get tty mode: %m");
return EINA_FALSE;
}
if (ioctl(dev->tty.fd, VT_ACTIVATE, minor(st.st_rdev)) < 0)
{
ERR("Failed to activate vt: %m");
return EINA_FALSE;
}
if (ioctl(dev->tty.fd, VT_WAITACTIVE, minor(st.st_rdev)) < 0)
{
ERR("Failed to wait active: %m");
return EINA_FALSE;
}
/* NB: Don't set this. This Turns OFF keyboard on the VT */
/* if (ioctl(dev->tty.fd, KDSKBMUTE, 1) && */
/* ioctl(dev->tty.fd, KDSKBMODE, K_OFF)) */
/* { */
/* ERR("Could not set K_OFF keyboard mode: %m"); */
/* return EINA_FALSE; */
/* } */
if (kmode != KD_GRAPHICS)
{
if (ioctl(dev->tty.fd, KDSETMODE, KD_GRAPHICS))
{
ERR("Could not set graphics mode: %m");
goto err_kmode;
}
}
vtmode.mode = VT_PROCESS;
vtmode.waitv = 0;
vtmode.relsig = SIGUSR1;
vtmode.acqsig = SIGUSR2;
if (ioctl(dev->tty.fd, VT_SETMODE, &vtmode) < 0)
{
ERR("Could not set Terminal Mode: %m");
goto err_setmode;
}
return EINA_TRUE;
err_setmode:
ioctl(dev->tty.fd, KDSETMODE, KD_TEXT);
err_kmode:
return EINA_FALSE;
}
static Eina_Bool
_ecore_drm_logind_vt_open(Ecore_Drm_Device *dev, const char *name)
{
char tty[32] = "<stdin>";
/* check for valid device */
if ((!dev) || (!dev->drm.name)) return EINA_FALSE;
/* assign default tty fd of -1 */
dev->tty.fd = -1;
if (!name)
{
char *env;
if ((env = getenv("ECORE_DRM_TTY")))
snprintf(tty, sizeof(tty), "%s", env);
else
dev->tty.fd = dup(STDIN_FILENO);
}
else
snprintf(tty, sizeof(tty), "%s", name);
if (dev->tty.fd < 0)
{
DBG("Trying to Open Tty: %s", tty);
dev->tty.fd = open(tty, O_RDWR | O_NOCTTY);
if (dev->tty.fd < 0)
{
DBG("Failed to Open Tty: %m");
return EINA_FALSE;
}
}
/* save tty name */
dev->tty.name = eina_stringshare_add(tty);
/* FIXME */
if (!_ecore_drm_logind_tty_setup(dev))
{
close(dev->tty.fd);
dev->tty.fd = -1;
return EINA_FALSE;
}
/* setup handler for signals */
dev->tty.event_hdlr =
ecore_event_handler_add(ECORE_EVENT_SIGNAL_USER,
_ecore_drm_logind_cb_vt_signal, dev);
/* setup handler for key event of vt switch */
dev->tty.switch_hdlr =
ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
_ecore_drm_logind_cb_vt_switch, dev);
/* set current tty into env */
setenv("ECORE_DRM_TTY", tty, 1);
return EINA_TRUE;
}
static void
_ecore_drm_logind_vt_close(Ecore_Drm_Device *dev)
{
struct vt_mode mode = { 0 };
ioctl(dev->tty.fd, KDSETMODE, KD_TEXT);
mode.mode = VT_AUTO;
ioctl(dev->tty.fd, VT_SETMODE, &mode);
if (dev->tty.event_hdlr) ecore_event_handler_del(dev->tty.event_hdlr);
dev->tty.event_hdlr = NULL;
if (dev->tty.switch_hdlr) ecore_event_handler_del(dev->tty.switch_hdlr);
dev->tty.switch_hdlr = NULL;
if (dev->tty.name) eina_stringshare_del(dev->tty.name);
dev->tty.name = NULL;
unsetenv("ECORE_DRM_TTY");
}
Eina_Bool
_ecore_drm_logind_connect(Ecore_Drm_Device *dev)
{
/* get sd-login properties we need */
if (sd_pid_get_session(getpid(), &sid) < 0) return EINA_FALSE;
/* try to init dbus */
if (!_ecore_drm_dbus_init(sid))
{
free(sid);
return EINA_FALSE;
}
if (!_ecore_drm_logind_vt_open(dev, NULL))
{
free(sid);
return EINA_FALSE;
}
return EINA_TRUE;
}
void
_ecore_drm_logind_disconnect(Ecore_Drm_Device *dev)
{
_ecore_drm_logind_vt_close(dev);
_ecore_drm_dbus_shutdown();
}
Eina_Bool
_ecore_drm_logind_device_open(const char *device, Ecore_Drm_Open_Cb callback, void *data)
{
struct stat st;
if (stat(device, &st) < 0) return EINA_FALSE;
if (!S_ISCHR(st.st_mode)) return EINA_FALSE;
if (_ecore_drm_dbus_device_take(major(st.st_rdev), minor(st.st_rdev), callback, data) < 0)
return EINA_FALSE;
return EINA_TRUE;
}
int
_ecore_drm_logind_device_open_no_pending(const char *device)
{
struct stat st;
if (stat(device, &st) < 0) return EINA_FALSE;
if (!S_ISCHR(st.st_mode)) return EINA_FALSE;
return _ecore_drm_dbus_device_take_no_pending(major(st.st_rdev), minor(st.st_rdev), NULL, -1);
}
void
_ecore_drm_logind_device_close(const char *device)
{
struct stat st;
if (stat(device, &st) < 0) return;
if (!S_ISCHR(st.st_mode)) return;
_ecore_drm_dbus_device_release(major(st.st_rdev), minor(st.st_rdev));
}

View File

@ -0,0 +1,55 @@
#ifndef _ECORE_DRM_LOGIN_H_
# define _ECORE_DRM_LOGIN_H_
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
#ifdef HAVE_SYSTEMD_LOGIN
# include <systemd/sd-login.h>
Eina_Bool _ecore_drm_logind_connect(Ecore_Drm_Device *dev);
void _ecore_drm_logind_disconnect(Ecore_Drm_Device *dev);
Eina_Bool _ecore_drm_logind_device_open(const char *device, Ecore_Drm_Open_Cb callback, void *data);
int _ecore_drm_logind_device_open_no_pending(const char *device);
void _ecore_drm_logind_device_close(const char *device);
int _ecore_drm_dbus_init(const char *session);
int _ecore_drm_dbus_shutdown(void);
int _ecore_drm_dbus_device_take(uint32_t major, uint32_t minor, Ecore_Drm_Open_Cb callback, void *data);
int _ecore_drm_dbus_device_take_no_pending(uint32_t major, uint32_t minor, Eina_Bool *paused_out, double timeout);
void _ecore_drm_dbus_device_release(uint32_t major, uint32_t minor);
#else
static inline Eina_Bool
_ecore_drm_logind_connect(Ecore_Drm_Device *dev EINA_UNUSED)
{
return EINA_FALSE;
}
static inline void
_ecore_drm_logind_disconnect(Ecore_Drm_Device *dev EINA_UNUSED)
{
return;
}
static inline Eina_Bool
_ecore_drm_logind_device_open(const char *device EINA_UNUSED, Ecore_Drm_Open_Cb callback EINA_UNUSED, void *data EINA_UNUSED)
{
return EINA_FALSE;
}
static inline int
_ecore_drm_logind_device_open_no_pending(const char *device EINA_UNUSED)
{
return -1;
}
static inline void
_ecore_drm_logind_device_close(const char *device EINA_UNUSED)
{
return;
}
#endif
#endif

View File

@ -21,7 +21,6 @@
# include <linux/input.h>
//# include <libinput.h>
# include <systemd/sd-login.h>
# include <xkbcommon/xkbcommon.h>
# include <xf86drm.h>
@ -228,10 +227,11 @@ struct _Ecore_Drm_Sprite
unsigned int formats[];
};
int _ecore_drm_dbus_init(const char *session);
int _ecore_drm_dbus_shutdown(void);
void _ecore_drm_dbus_device_open(const char *device, Eldbus_Message_Cb callback, const void *data);
void _ecore_drm_dbus_device_close(const char *device);
typedef void (*Ecore_Drm_Open_Cb)(void *data, int fd, Eina_Bool b);
Eina_Bool _ecore_drm_launcher_device_open(const char *device, Ecore_Drm_Open_Cb callback, void *data, int flags);
int _ecore_drm_launcher_device_open_no_pending(const char *device, int flags);
void _ecore_drm_launcher_device_close(const char *device, int fd);
Ecore_Drm_Evdev *_ecore_drm_evdev_device_create(Ecore_Drm_Seat *seat, const char *path, int fd);
void _ecore_drm_evdev_device_destroy(Ecore_Drm_Evdev *evdev);

View File

@ -474,6 +474,12 @@ _ecore_evas_drm_init(const char *device)
goto dev_err;
}
if (!ecore_drm_launcher_connect(dev))
{
ERR("Could not connect DRM launcher");
goto launcher_err;
}
/* try to open the graphics card */
if (!ecore_drm_device_open(dev))
{
@ -481,13 +487,6 @@ _ecore_evas_drm_init(const char *device)
goto dev_open_err;
}
/* try to open the tty */
if (!ecore_drm_tty_open(dev, NULL))
{
ERR("Could not open tty: %m");
goto tty_open_err;
}
/* try to create sprites */
if (!ecore_drm_sprites_create(dev))
{
@ -516,11 +515,11 @@ _ecore_evas_drm_init(const char *device)
output_err:
ecore_drm_sprites_destroy(dev);
sprite_err:
ecore_drm_tty_close(dev);
tty_open_err:
ecore_drm_device_close(dev);
dev_open_err:
ecore_drm_device_free(dev);
ecore_drm_launcher_disconnect(dev);
launcher_err:
dev_err:
ecore_drm_shutdown();
return --_ecore_evas_init_count;
@ -534,9 +533,9 @@ _ecore_evas_drm_shutdown(void)
ecore_drm_sprites_destroy(dev);
/* NB: No need to free outputs here. Is done in device free */
ecore_drm_inputs_destroy(dev);
ecore_drm_tty_close(dev);
ecore_drm_device_close(dev);
ecore_drm_device_free(dev);
ecore_drm_launcher_disconnect(dev);
ecore_drm_shutdown();
ecore_event_evas_shutdown();