forked from enlightenment/efl
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:
parent
ed3a1f3958
commit
1ce6cd4382
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
# include "Eldbus.h"
|
||||
# include <Elput.h>
|
||||
|
||||
# include <fcntl.h>
|
||||
# include <unistd.h>
|
||||
# include <linux/vt.h>
|
||||
# include <linux/kd.h>
|
||||
|
|
Loading…
Reference in New Issue