devilhorns pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=1ce6cd438244d644a63e6d1ab1dde88633bba34e

commit 1ce6cd438244d644a63e6d1ab1dde88633bba34e
Author: Chris Michael <cpmich...@osg.samsung.com>
Date:   Fri Apr 1 09:12:36 2016 -0400

    elput: Add API functions to open and close an input device
    
    This adds new API functions which can be called to open or close an input
    device and take control (or release control) of said device
    
    Signed-off-by: Chris Michael <cpmich...@osg.samsung.com>
---
 src/lib/elput/Elput.h         |  25 +++++++++
 src/lib/elput/elput_logind.c  | 122 +++++++++++++++++++++++++++++++++++++++++-
 src/lib/elput/elput_manager.c |  25 +++++++++
 src/lib/elput/elput_private.h |   1 +
 4 files changed, 171 insertions(+), 2 deletions(-)

diff --git a/src/lib/elput/Elput.h b/src/lib/elput/Elput.h
index e098b13..44a861c 100644
--- a/src/lib/elput/Elput.h
+++ b/src/lib/elput/Elput.h
@@ -102,6 +102,31 @@ EAPI Elput_Manager *elput_manager_connect(const char 
*seat, unsigned int tty, Ei
  */
 EAPI void elput_manager_disconnect(Elput_Manager *manager);
 
+/**
+ * Request input manager to open a file
+ *
+ * @param manager
+ * @param path
+ * @param flags
+ *
+ * @return Filedescriptor of opened file or -1 on failure
+ *
+ * @ingroup Elput_Manager_Group
+ * @since 1.18
+ */
+EAPI int elput_manager_open(Elput_Manager *manager, const char *path, int 
flags);
+
+/**
+ * Request input manager to close a file
+ *
+ * @param manager
+ * @param fd
+ *
+ * @ingroup Elput_Manager_Group
+ * @since 1.18
+ */
+EAPI void elput_manager_close(Elput_Manager *manager, int fd);
+
 # endif
 
 # undef EAPI
diff --git a/src/lib/elput/elput_logind.c b/src/lib/elput/elput_logind.c
index d649bf3..ec3cb7e 100644
--- a/src/lib/elput/elput_logind.c
+++ b/src/lib/elput/elput_logind.c
@@ -302,6 +302,78 @@ end:
    eldbus_proxy_unref(proxy);
 }
 
+static int
+_logind_device_take(Elput_Manager *em, uint32_t major, uint32_t minor)
+{
+   Eldbus_Proxy *proxy;
+   Eldbus_Message *msg, *reply;
+   Eina_Bool p = EINA_FALSE;
+   const char *errname, *errmsg;
+   int fd = -1;
+
+   proxy =
+     eldbus_proxy_get(em->dbus.obj, "org.freedesktop.login1.Session");
+   if (!proxy)
+     {
+        ERR("Could not get dbus proxy");
+        return -1;
+     }
+
+   msg = eldbus_proxy_method_call_new(proxy, "TakeDevice");
+   if (!msg)
+     {
+        ERR("Could not create method call for proxy");
+        goto err;
+     }
+
+   eldbus_message_arguments_append(msg, "uu", major, minor);
+
+   reply = eldbus_proxy_send_and_block(proxy, msg, -1);
+   if (eldbus_message_error_get(reply, &errname, &errmsg))
+     {
+        ERR("Eldbus Message Error: %s %s", errname, errmsg);
+        goto err;
+     }
+
+   if (!eldbus_message_arguments_get(reply, "hb", &fd, &p))
+     ERR("Could not get UNIX_FD from dbus message");
+
+   eldbus_message_unref(reply);
+
+err:
+   eldbus_proxy_unref(proxy);
+   return fd;
+}
+
+static void
+_logind_device_release(Elput_Manager *em, uint32_t major, uint32_t minor)
+{
+   Eldbus_Proxy *proxy;
+   Eldbus_Message *msg;
+
+   proxy =
+     eldbus_proxy_get(em->dbus.obj, "org.freedesktop.login1.Session");
+   if (!proxy)
+     {
+        ERR("Could not get proxy for session");
+        return;
+     }
+
+   msg = eldbus_proxy_method_call_new(proxy, "ReleaseDevice");
+   if (!msg)
+     {
+        ERR("Could not create method call for proxy");
+        goto end;
+     }
+
+   eldbus_message_arguments_append(msg, "uu", major, minor);
+
+   eldbus_proxy_send(proxy, msg, NULL, NULL, -1);
+
+end:
+   eldbus_proxy_unref(proxy);
+}
+
 static Eina_Bool
 _logind_activate(Elput_Manager *em)
 {
@@ -437,12 +509,58 @@ _logind_disconnect(Elput_Manager *em)
    free(em);
 }
 
+static int
+_logind_open(Elput_Manager *em, const char *path, int flags)
+{
+   struct stat st;
+   int ret, fd = -1;
+   int fl;
+
+   ret = stat(path, &st);
+   if (ret < 0) return -1;
+
+   if (!S_ISCHR(st.st_mode)) return -1;
+
+   fd = _logind_device_take(em, major(st.st_rdev), minor(st.st_rdev));
+   if (fd < 0) return fd;
+
+   fl = fcntl(fd, F_GETFL);
+   if (fl < 0) goto err;
+
+   if (flags & O_NONBLOCK)
+     fl |= O_NONBLOCK;
+
+   ret = fcntl(fd, F_SETFL, fl);
+   if (ret < 0) goto err;
+
+   return fd;
+
+err:
+   close(fd);
+   _logind_device_release(em, major(st.st_rdev), minor(st.st_rdev));
+   return -1;
+}
+
+static void
+_logind_close(Elput_Manager *em, int fd)
+{
+   struct stat st;
+   int ret;
+
+   ret = fstat(fd, &st);
+   if (ret < 0) return;
+
+   if (!S_ISCHR(st.st_mode)) return;
+
+   _logind_device_release(em, major(st.st_rdev), minor(st.st_rdev));
+}
+
 Elput_Interface _logind_interface =
 {
    _logind_connect,
    _logind_disconnect,
-   NULL,
-   NULL,
+   _logind_open,
+   _logind_close,
    NULL,
    NULL,
 };
diff --git a/src/lib/elput/elput_manager.c b/src/lib/elput/elput_manager.c
index 2073ff7..3dc67d9 100644
--- a/src/lib/elput/elput_manager.c
+++ b/src/lib/elput/elput_manager.c
@@ -37,3 +37,28 @@ elput_manager_disconnect(Elput_Manager *manager)
    if (manager->interface->disconnect)
      manager->interface->disconnect(manager);
 }
+
+EAPI int
+elput_manager_open(Elput_Manager *manager, const char *path, int flags)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(manager, -1);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(manager->interface, -1);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(path, -1);
+
+   if (flags < 0) flags = O_RDWR;
+
+   if (manager->interface->open)
+     return manager->interface->open(manager, path, flags);
+
+   return -1;
+}
+
+EAPI void
+elput_manager_close(Elput_Manager *manager, int fd)
+{
+   EINA_SAFETY_ON_NULL_RETURN(manager);
+   EINA_SAFETY_ON_NULL_RETURN(manager->interface);
+
+   if (manager->interface->close)
+     manager->interface->close(manager, fd);
+}
diff --git a/src/lib/elput/elput_private.h b/src/lib/elput/elput_private.h
index 07e147b..74532d5 100644
--- a/src/lib/elput/elput_private.h
+++ b/src/lib/elput/elput_private.h
@@ -12,6 +12,7 @@
 # include "Eldbus.h"
 # include <Elput.h>
 
+# include <fcntl.h>
 # include <unistd.h>
 # include <linux/vt.h>
 # include <linux/kd.h>

-- 


Reply via email to