forked from enlightenment/efl
elput: define and implement an async device opening interface for libinput
this adds an overly-complex method of removing blocking dbus calls from libinput's synchronous device initialization architecture. libinput was clearly never meant to be used in this way, but we're doing it anyway because we're efl. #SamsungFeatures
This commit is contained in:
parent
33a5d44dcf
commit
5f088b026d
|
@ -240,14 +240,13 @@ EAPI const Eina_List *elput_manager_seats_get(Elput_Manager *manager);
|
|||
* Initialize input
|
||||
*
|
||||
* @param manager
|
||||
* @param seat
|
||||
*
|
||||
* @return EINA_TRUE on success, EINA_FALSE on failure
|
||||
*
|
||||
* @ingroup Elput_Input_Group
|
||||
* @since 1.18
|
||||
*/
|
||||
EAPI Eina_Bool elput_input_init(Elput_Manager *manager, const char *seat);
|
||||
EAPI Eina_Bool elput_input_init(Elput_Manager *manager);
|
||||
|
||||
/**
|
||||
* Shutdown input
|
||||
|
|
|
@ -1,12 +1,82 @@
|
|||
#include "elput_private.h"
|
||||
#include <libudev.h>
|
||||
|
||||
void
|
||||
_elput_input_window_update(Elput_Manager *manager)
|
||||
{
|
||||
Eina_List *l, *ll;
|
||||
Elput_Seat *seat;
|
||||
Elput_Device *device;
|
||||
|
||||
if (manager->input.thread) return;
|
||||
EINA_LIST_FOREACH(manager->input.seats, l, seat)
|
||||
EINA_LIST_FOREACH(seat->devices, ll, device)
|
||||
device->window = manager->window;
|
||||
}
|
||||
|
||||
void
|
||||
_elput_input_pointer_max_update(Elput_Manager *manager)
|
||||
{
|
||||
Eina_List *l;
|
||||
Elput_Seat *eseat;
|
||||
|
||||
if (manager->input.thread) return;
|
||||
EINA_LIST_FOREACH(manager->input.seats, l, eseat)
|
||||
{
|
||||
if (!eseat->ptr) continue;
|
||||
|
||||
eseat->ptr->maxw = manager->input.pointer_w;
|
||||
eseat->ptr->maxh = manager->input.pointer_h;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
_cb_open_restricted(const char *path, int flags, void *data)
|
||||
{
|
||||
Elput_Manager *em;
|
||||
Elput_Manager *em = data;
|
||||
int ret = -1;
|
||||
Elput_Async_Open *ao;
|
||||
int p[2];
|
||||
|
||||
em = data;
|
||||
return elput_manager_open(em, path, flags);
|
||||
if (!em->input.thread)
|
||||
return em->interface->open(em, path, flags);
|
||||
if (!em->interface->open_async) return ret;
|
||||
ao = calloc(1, sizeof(Elput_Async_Open));
|
||||
if (!ao) return ret;
|
||||
if (pipe2(p, O_CLOEXEC) < 0)
|
||||
{
|
||||
free(ao);
|
||||
return ret;
|
||||
}
|
||||
ao->manager = em;
|
||||
ao->path = strdup(path);
|
||||
ao->flags = flags;
|
||||
em->input.pipe = p[1];
|
||||
ecore_thread_feedback(em->input.thread, ao);
|
||||
while (!ecore_thread_check(em->input.thread))
|
||||
{
|
||||
int avail, fd;
|
||||
fd_set rfds, wfds, exfds;
|
||||
struct timeval tv, *t;
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_ZERO(&wfds);
|
||||
FD_ZERO(&exfds);
|
||||
FD_SET(p[0], &rfds);
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 300;
|
||||
t = &tv;
|
||||
avail = select(p[0] + 1, &rfds, &wfds, &exfds, t);
|
||||
if (avail > 0)
|
||||
{
|
||||
read(p[0], &fd, sizeof(int));
|
||||
ret = fd;
|
||||
break;
|
||||
}
|
||||
if (avail < 0) break;
|
||||
}
|
||||
close(p[0]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -209,52 +279,91 @@ _cb_input_dispatch(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
|
|||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
elput_input_init(Elput_Manager *manager, const char *seat)
|
||||
static void
|
||||
_elput_input_init_cancel(void *data, Ecore_Thread *eth EINA_UNUSED)
|
||||
{
|
||||
int fd;
|
||||
Elput_Manager *manager = data;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(manager, EINA_FALSE);
|
||||
manager->input.thread = NULL;
|
||||
if (manager->input.current_pending)
|
||||
{
|
||||
eldbus_pending_cancel(manager->input.current_pending);
|
||||
if (manager->input.pipe >= 0)
|
||||
close(manager->input.pipe);
|
||||
}
|
||||
if (manager->del)
|
||||
elput_manager_disconnect(manager);
|
||||
}
|
||||
|
||||
memset(&manager->input, 0, sizeof(Elput_Input));
|
||||
static void
|
||||
_elput_input_init_end(void *data, Ecore_Thread *eth EINA_UNUSED)
|
||||
{
|
||||
Elput_Manager *manager = data;
|
||||
|
||||
manager->input.thread = NULL;
|
||||
if (!manager->input.lib) return;
|
||||
manager->input.hdlr =
|
||||
ecore_main_fd_handler_add(libinput_get_fd(manager->input.lib), ECORE_FD_READ,
|
||||
_cb_input_dispatch, &manager->input, NULL, NULL);
|
||||
|
||||
if (manager->input.hdlr)
|
||||
{
|
||||
_process_events(&manager->input);
|
||||
_elput_input_window_update(manager);
|
||||
_elput_input_pointer_max_update(manager);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("Could not create input fd handler");
|
||||
libinput_unref(manager->input.lib);
|
||||
manager->input.lib = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_elput_input_init_notify(void *data EINA_UNUSED, Ecore_Thread *eth EINA_UNUSED, void *msg_data)
|
||||
{
|
||||
Elput_Async_Open *ao = msg_data;
|
||||
|
||||
ao->manager->interface->open_async(ao->manager, ao->path, ao->flags);
|
||||
free(ao->path);
|
||||
free(ao);
|
||||
}
|
||||
|
||||
static void
|
||||
_elput_input_init_thread(void *data, Ecore_Thread *eth EINA_UNUSED)
|
||||
{
|
||||
Elput_Manager *manager = data;
|
||||
struct udev *udev = udev_new();
|
||||
|
||||
manager->input.lib =
|
||||
libinput_udev_create_context(&_input_interface, manager, eeze_udev_get());
|
||||
libinput_udev_create_context(&_input_interface, manager, udev);
|
||||
if (!manager->input.lib)
|
||||
{
|
||||
ERR("libinput could not create udev context");
|
||||
goto udev_err;
|
||||
return;
|
||||
}
|
||||
udev_unref(udev);
|
||||
|
||||
/* if not seat name is passed in, just use default seat name */
|
||||
if (!seat) seat = "seat0";
|
||||
|
||||
if (libinput_udev_assign_seat(manager->input.lib, seat) != 0)
|
||||
if (libinput_udev_assign_seat(manager->input.lib, manager->seat))
|
||||
{
|
||||
ERR("libinput could not assign udev seat");
|
||||
goto seat_err;
|
||||
libinput_unref(manager->input.lib);
|
||||
manager->input.lib = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
_process_events(&manager->input);
|
||||
EAPI Eina_Bool
|
||||
elput_input_init(Elput_Manager *manager)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(manager, EINA_FALSE);
|
||||
EINA_SAFETY_ON_TRUE_RETURN_VAL(!!manager->input.hdlr, EINA_TRUE);
|
||||
|
||||
fd = libinput_get_fd(manager->input.lib);
|
||||
|
||||
manager->input.hdlr =
|
||||
ecore_main_fd_handler_add(fd, ECORE_FD_READ, _cb_input_dispatch,
|
||||
&manager->input, NULL, NULL);
|
||||
if (!manager->input.hdlr)
|
||||
{
|
||||
ERR("Could not create input fd handler");
|
||||
goto hdlr_err;
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
|
||||
hdlr_err:
|
||||
seat_err:
|
||||
libinput_unref(manager->input.lib);
|
||||
udev_err:
|
||||
return EINA_FALSE;
|
||||
memset(&manager->input, 0, sizeof(Elput_Input));
|
||||
manager->input.thread =
|
||||
ecore_thread_feedback_run(_elput_input_init_thread, _elput_input_init_notify,
|
||||
_elput_input_init_end, _elput_input_init_cancel, manager, 1);
|
||||
return !!manager->input.thread;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
@ -263,14 +372,18 @@ elput_input_shutdown(Elput_Manager *manager)
|
|||
Elput_Seat *seat;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(manager);
|
||||
EINA_SAFETY_ON_NULL_RETURN(&manager->input);
|
||||
|
||||
if (manager->input.hdlr) ecore_main_fd_handler_del(manager->input.hdlr);
|
||||
ecore_main_fd_handler_del(manager->input.hdlr);
|
||||
|
||||
EINA_LIST_FREE(manager->input.seats, seat)
|
||||
_udev_seat_destroy(seat);
|
||||
|
||||
libinput_unref(manager->input.lib);
|
||||
if (manager->input.thread)
|
||||
ecore_thread_cancel(manager->input.thread);
|
||||
else
|
||||
{
|
||||
libinput_unref(manager->input.lib);
|
||||
manager->input.lib = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
|
|
@ -30,31 +30,19 @@ _logind_session_active_send(Elput_Manager *em, Eina_Bool active)
|
|||
static void
|
||||
_logind_device_pause_complete(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, "PauseDeviceComplete");
|
||||
msg = eldbus_proxy_method_call_new(em->dbus.session, "PauseDeviceComplete");
|
||||
if (!msg)
|
||||
{
|
||||
ERR("Could not create method call for proxy");
|
||||
goto end;
|
||||
eldbus_message_unref(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
eldbus_message_arguments_append(msg, "uu", major, minor);
|
||||
|
||||
eldbus_proxy_send(proxy, msg, NULL, NULL, -1);
|
||||
|
||||
end:
|
||||
eldbus_message_unref(msg);
|
||||
eldbus_proxy_unref(proxy);
|
||||
eldbus_proxy_send(em->dbus.session, msg, NULL, NULL, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -194,10 +182,10 @@ _logind_dbus_setup(Elput_Manager *em)
|
|||
ERR("Could not get dbus proxy");
|
||||
goto proxy_err;
|
||||
}
|
||||
em->dbus.manager = proxy;
|
||||
|
||||
eldbus_proxy_signal_handler_add(proxy, "SessionRemoved",
|
||||
_cb_session_removed, em);
|
||||
eldbus_proxy_unref(proxy);
|
||||
|
||||
proxy =
|
||||
eldbus_proxy_get(em->dbus.obj, "org.freedesktop.login1.Session");
|
||||
|
@ -206,13 +194,12 @@ _logind_dbus_setup(Elput_Manager *em)
|
|||
ERR("Could not get dbus proxy");
|
||||
goto proxy_err;
|
||||
}
|
||||
em->dbus.session = proxy;
|
||||
|
||||
eldbus_proxy_signal_handler_add(proxy, "PauseDevice",
|
||||
_cb_device_paused, em);
|
||||
eldbus_proxy_signal_handler_add(proxy, "ResumeDevice",
|
||||
_cb_device_resumed, em);
|
||||
eldbus_proxy_unref(proxy);
|
||||
|
||||
proxy =
|
||||
eldbus_proxy_get(em->dbus.obj, "org.freedesktop.DBus.Properties");
|
||||
if (!proxy)
|
||||
|
@ -235,173 +222,189 @@ obj_err:
|
|||
static Eina_Bool
|
||||
_logind_control_take(Elput_Manager *em)
|
||||
{
|
||||
Eldbus_Proxy *proxy;
|
||||
Eldbus_Message *msg, *reply;
|
||||
const char *errname, *errmsg;
|
||||
|
||||
proxy =
|
||||
eldbus_proxy_get(em->dbus.obj, "org.freedesktop.login1.Session");
|
||||
if (!proxy)
|
||||
{
|
||||
ERR("Could not get proxy for session");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
msg = eldbus_proxy_method_call_new(proxy, "TakeControl");
|
||||
msg = eldbus_proxy_method_call_new(em->dbus.session, "TakeControl");
|
||||
if (!msg)
|
||||
{
|
||||
ERR("Could not create method call for proxy");
|
||||
goto msg_err;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
eldbus_message_arguments_append(msg, "b", EINA_FALSE);
|
||||
|
||||
reply = eldbus_proxy_send_and_block(proxy, msg, -1);
|
||||
reply = eldbus_proxy_send_and_block(em->dbus.session, msg, -1);
|
||||
if (eldbus_message_error_get(reply, &errname, &errmsg))
|
||||
{
|
||||
ERR("Eldbus Message Error: %s %s", errname, errmsg);
|
||||
goto msg_err;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
eldbus_message_unref(reply);
|
||||
eldbus_proxy_unref(proxy);
|
||||
|
||||
return EINA_TRUE;
|
||||
|
||||
msg_err:
|
||||
eldbus_proxy_unref(proxy);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_logind_control_release(Elput_Manager *em)
|
||||
{
|
||||
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, "ReleaseControl");
|
||||
msg = eldbus_proxy_method_call_new(em->dbus.session, "ReleaseControl");
|
||||
if (!msg)
|
||||
{
|
||||
ERR("Could not create method call for proxy");
|
||||
goto end;
|
||||
return;
|
||||
}
|
||||
|
||||
eldbus_proxy_send(proxy, msg, NULL, NULL, -1);
|
||||
eldbus_proxy_send(em->dbus.session, msg, NULL, NULL, -1);
|
||||
}
|
||||
|
||||
end:
|
||||
eldbus_proxy_unref(proxy);
|
||||
static void
|
||||
_logind_device_release(Elput_Manager *em, uint32_t major, uint32_t minor)
|
||||
{
|
||||
Eldbus_Message *msg;
|
||||
|
||||
msg = eldbus_proxy_method_call_new(em->dbus.session, "ReleaseDevice");
|
||||
if (!msg)
|
||||
{
|
||||
ERR("Could not create method call for proxy");
|
||||
return;
|
||||
}
|
||||
|
||||
eldbus_message_arguments_append(msg, "uu", major, minor);
|
||||
|
||||
eldbus_proxy_send(em->dbus.session, msg, NULL, NULL, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
_logind_pipe_write_fd(Elput_Manager *em, int fd)
|
||||
{
|
||||
write(em->input.pipe, &fd, sizeof(int));
|
||||
close(em->input.pipe);
|
||||
em->input.pipe = -1;
|
||||
}
|
||||
|
||||
static void
|
||||
_logind_device_take_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
|
||||
{
|
||||
Eina_Bool p = EINA_FALSE;
|
||||
const char *errname, *errmsg;
|
||||
int ret, fd = -1;
|
||||
int fl, flags;
|
||||
Elput_Manager *em = data;
|
||||
|
||||
if (em->input.current_pending == pending)
|
||||
em->input.current_pending = NULL;
|
||||
|
||||
if (eldbus_message_error_get(msg, &errname, &errmsg))
|
||||
{
|
||||
ERR("Eldbus Message Error: %s %s", errname, errmsg);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!eldbus_message_arguments_get(msg, "hb", &fd, &p))
|
||||
ERR("Could not get UNIX_FD from dbus message");
|
||||
|
||||
if (fd < 0) goto err;
|
||||
|
||||
fl = fcntl(fd, F_GETFL);
|
||||
if (fl < 0) goto err;
|
||||
|
||||
flags = (intptr_t)eldbus_pending_data_get(pending, "flags");
|
||||
|
||||
if (flags & O_NONBLOCK)
|
||||
fl |= O_NONBLOCK;
|
||||
|
||||
ret = fcntl(fd, F_SETFL, fl);
|
||||
if (ret < 0) goto err;
|
||||
|
||||
_logind_pipe_write_fd(em, fd);
|
||||
return;
|
||||
|
||||
err:
|
||||
if (fd >= 0)
|
||||
{
|
||||
uintptr_t majo, mino;
|
||||
|
||||
close(fd);
|
||||
majo = (uintptr_t)eldbus_pending_data_get(pending, "major");
|
||||
mino = (uintptr_t)eldbus_pending_data_get(pending, "minor");
|
||||
_logind_device_release(em, majo, mino);
|
||||
}
|
||||
fd = -1;
|
||||
_logind_pipe_write_fd(em, fd);
|
||||
}
|
||||
|
||||
static void
|
||||
_logind_device_take_async(Elput_Manager *em, int flags, uint32_t major, uint32_t minor)
|
||||
{
|
||||
Eldbus_Message *msg;
|
||||
intptr_t fd = -1;
|
||||
|
||||
msg = eldbus_proxy_method_call_new(em->dbus.session, "TakeDevice");
|
||||
if (!msg)
|
||||
{
|
||||
ERR("Could not create method call for proxy");
|
||||
_logind_pipe_write_fd(em, fd);
|
||||
return;
|
||||
}
|
||||
|
||||
eldbus_message_arguments_append(msg, "uu", major, minor);
|
||||
|
||||
em->input.current_pending = eldbus_proxy_send(em->dbus.session, msg, _logind_device_take_cb, em, -1);
|
||||
if (!em->input.current_pending) CRIT("FAIL!");
|
||||
eldbus_pending_data_set(em->input.current_pending, "major", (uintptr_t*)(uintptr_t)major);
|
||||
eldbus_pending_data_set(em->input.current_pending, "minor", (uintptr_t*)(uintptr_t)minor);
|
||||
eldbus_pending_data_set(em->input.current_pending, "flags", (intptr_t*)(intptr_t)flags);
|
||||
}
|
||||
|
||||
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");
|
||||
msg = eldbus_proxy_method_call_new(em->dbus.session, "TakeDevice");
|
||||
if (!msg)
|
||||
{
|
||||
ERR("Could not create method call for proxy");
|
||||
goto err;
|
||||
return -1;
|
||||
}
|
||||
|
||||
eldbus_message_arguments_append(msg, "uu", major, minor);
|
||||
|
||||
reply = eldbus_proxy_send_and_block(proxy, msg, -1);
|
||||
reply = eldbus_proxy_send_and_block(em->dbus.session, msg, -1);
|
||||
if (eldbus_message_error_get(reply, &errname, &errmsg))
|
||||
{
|
||||
ERR("Eldbus Message Error: %s %s", errname, errmsg);
|
||||
goto err;
|
||||
return -1;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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 EINA_FALSE;
|
||||
}
|
||||
|
||||
msg = eldbus_proxy_method_call_new(proxy, "Activate");
|
||||
msg = eldbus_proxy_method_call_new(em->dbus.session, "Activate");
|
||||
if (!msg)
|
||||
{
|
||||
ERR("Could not create method call for proxy");
|
||||
goto msg_err;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
eldbus_proxy_send(proxy, msg, NULL, NULL, -1);
|
||||
|
||||
eldbus_proxy_unref(proxy);
|
||||
|
||||
eldbus_proxy_send(em->dbus.session, msg, NULL, NULL, -1);
|
||||
return EINA_TRUE;
|
||||
|
||||
msg_err:
|
||||
eldbus_proxy_unref(proxy);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
|
@ -498,6 +501,8 @@ static void
|
|||
_logind_disconnect(Elput_Manager *em)
|
||||
{
|
||||
_logind_control_release(em);
|
||||
eldbus_proxy_unref(em->dbus.manager);
|
||||
eldbus_proxy_unref(em->dbus.session);
|
||||
eldbus_object_unref(em->dbus.obj);
|
||||
free(em->dbus.path);
|
||||
_logind_dbus_close(em->dbus.conn);
|
||||
|
@ -506,6 +511,18 @@ _logind_disconnect(Elput_Manager *em)
|
|||
free(em);
|
||||
}
|
||||
|
||||
static void
|
||||
_logind_open_async(Elput_Manager *em, const char *path, int flags)
|
||||
{
|
||||
struct stat st;
|
||||
intptr_t fd = -1;
|
||||
|
||||
if ((stat(path, &st) < 0) || (!S_ISCHR(st.st_mode)))
|
||||
_logind_pipe_write_fd(em, fd);
|
||||
else
|
||||
_logind_device_take_async(em, flags, major(st.st_rdev), minor(st.st_rdev));
|
||||
}
|
||||
|
||||
static int
|
||||
_logind_open(Elput_Manager *em, const char *path, int flags)
|
||||
{
|
||||
|
@ -606,6 +623,7 @@ Elput_Interface _logind_interface =
|
|||
_logind_connect,
|
||||
_logind_disconnect,
|
||||
_logind_open,
|
||||
_logind_open_async,
|
||||
_logind_close,
|
||||
_logind_vt_set,
|
||||
};
|
||||
|
|
|
@ -58,6 +58,14 @@ elput_manager_disconnect(Elput_Manager *manager)
|
|||
EINA_SAFETY_ON_NULL_RETURN(manager);
|
||||
EINA_SAFETY_ON_NULL_RETURN(manager->interface);
|
||||
|
||||
|
||||
if (manager->input.thread)
|
||||
{
|
||||
ecore_thread_cancel(manager->input.thread);
|
||||
manager->del = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (manager->interface->disconnect)
|
||||
manager->interface->disconnect(manager);
|
||||
}
|
||||
|
|
|
@ -71,6 +71,7 @@ typedef struct _Elput_Interface
|
|||
Eina_Bool (*connect)(Elput_Manager **manager, const char *seat, unsigned int tty);
|
||||
void (*disconnect)(Elput_Manager *manager);
|
||||
int (*open)(Elput_Manager *manager, const char *path, int flags);
|
||||
void (*open_async)(Elput_Manager *manager, const char *path, int flags);
|
||||
void (*close)(Elput_Manager *manager, int fd);
|
||||
Eina_Bool (*vt_set)(Elput_Manager *manager, int vt);
|
||||
} Elput_Interface;
|
||||
|
@ -82,6 +83,9 @@ typedef struct _Elput_Input
|
|||
Ecore_Fd_Handler *hdlr;
|
||||
|
||||
Eina_List *seats;
|
||||
Ecore_Thread *thread;
|
||||
Eldbus_Pending *current_pending;
|
||||
int pipe;
|
||||
|
||||
Eina_Bool suspended : 1;
|
||||
} Elput_Input;
|
||||
|
@ -224,18 +228,30 @@ struct _Elput_Manager
|
|||
char *sid;
|
||||
const char *seat;
|
||||
unsigned int vt_num;
|
||||
int vt_fd;
|
||||
Ecore_Event_Handler *vt_hdlr;
|
||||
uint32_t window;
|
||||
|
||||
struct
|
||||
{
|
||||
char *path;
|
||||
Eldbus_Object *obj;
|
||||
Eldbus_Connection *conn;
|
||||
Eldbus_Proxy *session;
|
||||
Eldbus_Proxy *manager;
|
||||
} dbus;
|
||||
|
||||
Elput_Input input;
|
||||
Eina_Bool del : 1;
|
||||
};
|
||||
|
||||
typedef struct _Elput_Async_Open
|
||||
{
|
||||
Elput_Manager *manager;
|
||||
char *path;
|
||||
int flags;
|
||||
} Elput_Async_Open;
|
||||
|
||||
int _evdev_event_process(struct libinput_event *event);
|
||||
Elput_Device *_evdev_device_create(Elput_Seat *seat, struct libinput_device *device);
|
||||
void _evdev_device_destroy(Elput_Device *edev);
|
||||
|
|
Loading…
Reference in New Issue