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 <cpmichael@osg.samsung.com>
This commit is contained in:
Chris Michael 2016-04-01 09:12:36 -04:00
parent ed3a1f3958
commit 1ce6cd4382
4 changed files with 171 additions and 2 deletions

View File

@ -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

View File

@ -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,
};

View File

@ -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);
}

View File

@ -12,6 +12,7 @@
# include "Eldbus.h"
# include <Elput.h>
# include <fcntl.h>
# include <unistd.h>
# include <linux/vt.h>
# include <linux/kd.h>