tommy       14/12/28 09:43:36

  Added:                efl-1.12.2-lauch_via_logind_or_root_privilege.patch
  Log:
  Add missing patch
  
  (Portage version: 2.2.15/cvs/Linux x86_64, signed Manifest commit with key 
0x35899067)

Revision  Changes    Path
1.1                  
dev-libs/efl/files/efl-1.12.2-lauch_via_logind_or_root_privilege.patch

file : 
http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-libs/efl/files/efl-1.12.2-lauch_via_logind_or_root_privilege.patch?rev=1.1&view=markup
plain: 
http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-libs/efl/files/efl-1.12.2-lauch_via_logind_or_root_privilege.patch?rev=1.1&content-type=text/plain

Index: efl-1.12.2-lauch_via_logind_or_root_privilege.patch
===================================================================
>From b10ab1a86f35ab793ba6efb49224d9ecdd1b7dbd Mon Sep 17 00:00:00 2001
From: Seunghun Lee <shiin....@samsung.com>
Date: Tue, 9 Dec 2014 09:36:42 -0500
Subject: 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

diff --git a/configure.ac b/configure.ac
index e09213d..5911192 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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])
 
diff --git a/src/Makefile_Ecore_Drm.am b/src/Makefile_Ecore_Drm.am
index 8867f37..b558277 100644
--- a/src/Makefile_Ecore_Drm.am
+++ b/src/Makefile_Ecore_Drm.am
@@ -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@ \
diff --git a/src/lib/ecore_drm/Ecore_Drm.h b/src/lib/ecore_drm/Ecore_Drm.h
index 80efaf5..3238a20 100644
--- a/src/lib/ecore_drm/Ecore_Drm.h
+++ b/src/lib/ecore_drm/Ecore_Drm.h
@@ -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
diff --git a/src/lib/ecore_drm/ecore_drm.c b/src/lib/ecore_drm/ecore_drm.c
index c341c19..6413270 100644
--- a/src/lib/ecore_drm/ecore_drm.c
+++ b/src/lib/ecore_drm/ecore_drm.c
@@ -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;
 }
diff --git a/src/lib/ecore_drm/ecore_drm_dbus.c 
b/src/lib/ecore_drm/ecore_drm_dbus.c
index 222b5e9..bfac33f 100644
--- a/src/lib/ecore_drm/ecore_drm_dbus.c
+++ b/src/lib/ecore_drm/ecore_drm_dbus.c
@@ -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));
-}
diff --git a/src/lib/ecore_drm/ecore_drm_device.c 
b/src/lib/ecore_drm/ecore_drm_device.c
index e8ca052..957c439e 100644
--- a/src/lib/ecore_drm/ecore_drm_device.c
+++ b/src/lib/ecore_drm/ecore_drm_device.c
@@ -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;
diff --git a/src/lib/ecore_drm/ecore_drm_inputs.c 
b/src/lib/ecore_drm/ecore_drm_inputs.c
index f03af36..a1ca008 100644
--- a/src/lib/ecore_drm/ecore_drm_inputs.c
+++ b/src/lib/ecore_drm/ecore_drm_inputs.c
@@ -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);
           }
      }
diff --git a/src/lib/ecore_drm/ecore_drm_launcher.c 
b/src/lib/ecore_drm/ecore_drm_launcher.c
new file mode 100644
index 0000000..e2d64d5
--- /dev/null
+++ b/src/lib/ecore_drm/ecore_drm_launcher.c
@@ -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);
+}
diff --git a/src/lib/ecore_drm/ecore_drm_logind.c 
b/src/lib/ecore_drm/ecore_drm_logind.c
new file mode 100644
index 0000000..a3c6c1e
--- /dev/null
+++ b/src/lib/ecore_drm/ecore_drm_logind.c
@@ -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));
+}
diff --git a/src/lib/ecore_drm/ecore_drm_logind.h 
b/src/lib/ecore_drm/ecore_drm_logind.h
new file mode 100644
index 0000000..4315722
--- /dev/null
+++ b/src/lib/ecore_drm/ecore_drm_logind.h
@@ -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
diff --git a/src/lib/ecore_drm/ecore_drm_private.h 
b/src/lib/ecore_drm/ecore_drm_private.h
index fe769a4..7a3c0a0 100644
--- a/src/lib/ecore_drm/ecore_drm_private.h
+++ b/src/lib/ecore_drm/ecore_drm_private.h
@@ -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);
diff --git a/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c 
b/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c
index ce6ce84..776939e 100644
--- a/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c
+++ b/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c
@@ -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();
-- 
cgit v0.10.1





Reply via email to