summaryrefslogtreecommitdiff
path: root/src/lib/elput
diff options
context:
space:
mode:
authorMike Blumenkrantz <zmike@osg.samsung.com>2016-05-24 16:11:20 -0400
committerMike Blumenkrantz <zmike@osg.samsung.com>2016-05-25 12:57:27 -0400
commit5f088b026d8f39aafc6b6e70fe3b04dff79b179e (patch)
tree06909671c2b23b105009d19608f7a7d7e108cf2a /src/lib/elput
parent33a5d44dcf36557b13aeba1088461504bae97373 (diff)
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
Diffstat (limited to 'src/lib/elput')
-rw-r--r--src/lib/elput/Elput.h3
-rw-r--r--src/lib/elput/elput_input.c191
-rw-r--r--src/lib/elput/elput_logind.c226
-rw-r--r--src/lib/elput/elput_manager.c8
-rw-r--r--src/lib/elput/elput_private.h16
5 files changed, 299 insertions, 145 deletions
diff --git a/src/lib/elput/Elput.h b/src/lib/elput/Elput.h
index 07ebfa2f97..2f311608a4 100644
--- a/src/lib/elput/Elput.h
+++ b/src/lib/elput/Elput.h
@@ -240,14 +240,13 @@ EAPI const Eina_List *elput_manager_seats_get(Elput_Manager *manager);
240 * Initialize input 240 * Initialize input
241 * 241 *
242 * @param manager 242 * @param manager
243 * @param seat
244 * 243 *
245 * @return EINA_TRUE on success, EINA_FALSE on failure 244 * @return EINA_TRUE on success, EINA_FALSE on failure
246 * 245 *
247 * @ingroup Elput_Input_Group 246 * @ingroup Elput_Input_Group
248 * @since 1.18 247 * @since 1.18
249 */ 248 */
250EAPI Eina_Bool elput_input_init(Elput_Manager *manager, const char *seat); 249EAPI Eina_Bool elput_input_init(Elput_Manager *manager);
251 250
252/** 251/**
253 * Shutdown input 252 * Shutdown input
diff --git a/src/lib/elput/elput_input.c b/src/lib/elput/elput_input.c
index d49a2d0236..8431c290b5 100644
--- a/src/lib/elput/elput_input.c
+++ b/src/lib/elput/elput_input.c
@@ -1,12 +1,82 @@
1#include "elput_private.h" 1#include "elput_private.h"
2#include <libudev.h>
3
4void
5_elput_input_window_update(Elput_Manager *manager)
6{
7 Eina_List *l, *ll;
8 Elput_Seat *seat;
9 Elput_Device *device;
10
11 if (manager->input.thread) return;
12 EINA_LIST_FOREACH(manager->input.seats, l, seat)
13 EINA_LIST_FOREACH(seat->devices, ll, device)
14 device->window = manager->window;
15}
16
17void
18_elput_input_pointer_max_update(Elput_Manager *manager)
19{
20 Eina_List *l;
21 Elput_Seat *eseat;
22
23 if (manager->input.thread) return;
24 EINA_LIST_FOREACH(manager->input.seats, l, eseat)
25 {
26 if (!eseat->ptr) continue;
27
28 eseat->ptr->maxw = manager->input.pointer_w;
29 eseat->ptr->maxh = manager->input.pointer_h;
30 }
31}
2 32
3static int 33static int
4_cb_open_restricted(const char *path, int flags, void *data) 34_cb_open_restricted(const char *path, int flags, void *data)
5{ 35{
6 Elput_Manager *em; 36 Elput_Manager *em = data;
7 37 int ret = -1;
8 em = data; 38 Elput_Async_Open *ao;
9 return elput_manager_open(em, path, flags); 39 int p[2];
40
41 if (!em->input.thread)
42 return em->interface->open(em, path, flags);
43 if (!em->interface->open_async) return ret;
44 ao = calloc(1, sizeof(Elput_Async_Open));
45 if (!ao) return ret;
46 if (pipe2(p, O_CLOEXEC) < 0)
47 {
48 free(ao);
49 return ret;
50 }
51 ao->manager = em;
52 ao->path = strdup(path);
53 ao->flags = flags;
54 em->input.pipe = p[1];
55 ecore_thread_feedback(em->input.thread, ao);
56 while (!ecore_thread_check(em->input.thread))
57 {
58 int avail, fd;
59 fd_set rfds, wfds, exfds;
60 struct timeval tv, *t;
61
62 FD_ZERO(&rfds);
63 FD_ZERO(&wfds);
64 FD_ZERO(&exfds);
65 FD_SET(p[0], &rfds);
66 tv.tv_sec = 0;
67 tv.tv_usec = 300;
68 t = &tv;
69 avail = select(p[0] + 1, &rfds, &wfds, &exfds, t);
70 if (avail > 0)
71 {
72 read(p[0], &fd, sizeof(int));
73 ret = fd;
74 break;
75 }
76 if (avail < 0) break;
77 }
78 close(p[0]);
79 return ret;
10} 80}
11 81
12static void 82static void
@@ -209,52 +279,91 @@ _cb_input_dispatch(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
209 return EINA_TRUE; 279 return EINA_TRUE;
210} 280}
211 281
212EAPI Eina_Bool 282static void
213elput_input_init(Elput_Manager *manager, const char *seat) 283_elput_input_init_cancel(void *data, Ecore_Thread *eth EINA_UNUSED)
214{ 284{
215 int fd; 285 Elput_Manager *manager = data;
216
217 EINA_SAFETY_ON_NULL_RETURN_VAL(manager, EINA_FALSE);
218 286
219 memset(&manager->input, 0, sizeof(Elput_Input)); 287 manager->input.thread = NULL;
220 288 if (manager->input.current_pending)
221 manager->input.lib =
222 libinput_udev_create_context(&_input_interface, manager, eeze_udev_get());
223 if (!manager->input.lib)
224 { 289 {
225 ERR("libinput could not create udev context"); 290 eldbus_pending_cancel(manager->input.current_pending);
226 goto udev_err; 291 if (manager->input.pipe >= 0)
292 close(manager->input.pipe);
227 } 293 }
294 if (manager->del)
295 elput_manager_disconnect(manager);
296}
228 297
229 /* if not seat name is passed in, just use default seat name */ 298static void
230 if (!seat) seat = "seat0"; 299_elput_input_init_end(void *data, Ecore_Thread *eth EINA_UNUSED)
300{
301 Elput_Manager *manager = data;
231 302
232 if (libinput_udev_assign_seat(manager->input.lib, seat) != 0) 303 manager->input.thread = NULL;
304 if (!manager->input.lib) return;
305 manager->input.hdlr =
306 ecore_main_fd_handler_add(libinput_get_fd(manager->input.lib), ECORE_FD_READ,
307 _cb_input_dispatch, &manager->input, NULL, NULL);
308
309 if (manager->input.hdlr)
233 { 310 {
234 ERR("libinput could not assign udev seat"); 311 _process_events(&manager->input);
235 goto seat_err; 312 _elput_input_window_update(manager);
313 _elput_input_pointer_max_update(manager);
314 }
315 else
316 {
317 ERR("Could not create input fd handler");
318 libinput_unref(manager->input.lib);
319 manager->input.lib = NULL;
236 } 320 }
321}
237 322
238 _process_events(&manager->input); 323static void
324_elput_input_init_notify(void *data EINA_UNUSED, Ecore_Thread *eth EINA_UNUSED, void *msg_data)
325{
326 Elput_Async_Open *ao = msg_data;
239 327
240 fd = libinput_get_fd(manager->input.lib); 328 ao->manager->interface->open_async(ao->manager, ao->path, ao->flags);
329 free(ao->path);
330 free(ao);
331}
241 332
242 manager->input.hdlr = 333static void
243 ecore_main_fd_handler_add(fd, ECORE_FD_READ, _cb_input_dispatch, 334_elput_input_init_thread(void *data, Ecore_Thread *eth EINA_UNUSED)
244 &manager->input, NULL, NULL); 335{
245 if (!manager->input.hdlr) 336 Elput_Manager *manager = data;
337 struct udev *udev = udev_new();
338
339 manager->input.lib =
340 libinput_udev_create_context(&_input_interface, manager, udev);
341 if (!manager->input.lib)
246 { 342 {
247 ERR("Could not create input fd handler"); 343 ERR("libinput could not create udev context");
248 goto hdlr_err; 344 return;
249 } 345 }
346 udev_unref(udev);
250 347
251 return EINA_TRUE; 348 if (libinput_udev_assign_seat(manager->input.lib, manager->seat))
349 {
350 ERR("libinput could not assign udev seat");
351 libinput_unref(manager->input.lib);
352 manager->input.lib = NULL;
353 }
354}
355
356EAPI Eina_Bool
357elput_input_init(Elput_Manager *manager)
358{
359 EINA_SAFETY_ON_NULL_RETURN_VAL(manager, EINA_FALSE);
360 EINA_SAFETY_ON_TRUE_RETURN_VAL(!!manager->input.hdlr, EINA_TRUE);
252 361
253hdlr_err: 362 memset(&manager->input, 0, sizeof(Elput_Input));
254seat_err: 363 manager->input.thread =
255 libinput_unref(manager->input.lib); 364 ecore_thread_feedback_run(_elput_input_init_thread, _elput_input_init_notify,
256udev_err: 365 _elput_input_init_end, _elput_input_init_cancel, manager, 1);
257 return EINA_FALSE; 366 return !!manager->input.thread;
258} 367}
259 368
260EAPI void 369EAPI void
@@ -263,14 +372,18 @@ elput_input_shutdown(Elput_Manager *manager)
263 Elput_Seat *seat; 372 Elput_Seat *seat;
264 373
265 EINA_SAFETY_ON_NULL_RETURN(manager); 374 EINA_SAFETY_ON_NULL_RETURN(manager);
266 EINA_SAFETY_ON_NULL_RETURN(&manager->input);
267 375
268 if (manager->input.hdlr) ecore_main_fd_handler_del(manager->input.hdlr); 376 ecore_main_fd_handler_del(manager->input.hdlr);
269 377
270 EINA_LIST_FREE(manager->input.seats, seat) 378 EINA_LIST_FREE(manager->input.seats, seat)
271 _udev_seat_destroy(seat); 379 _udev_seat_destroy(seat);
272 380 if (manager->input.thread)
273 libinput_unref(manager->input.lib); 381 ecore_thread_cancel(manager->input.thread);
382 else
383 {
384 libinput_unref(manager->input.lib);
385 manager->input.lib = NULL;
386 }
274} 387}
275 388
276EAPI void 389EAPI void
diff --git a/src/lib/elput/elput_logind.c b/src/lib/elput/elput_logind.c
index 3beb8b4eae..8db4a113fa 100644
--- a/src/lib/elput/elput_logind.c
+++ b/src/lib/elput/elput_logind.c
@@ -30,31 +30,19 @@ _logind_session_active_send(Elput_Manager *em, Eina_Bool active)
30static void 30static void
31_logind_device_pause_complete(Elput_Manager *em, uint32_t major, uint32_t minor) 31_logind_device_pause_complete(Elput_Manager *em, uint32_t major, uint32_t minor)
32{ 32{
33 Eldbus_Proxy *proxy;
34 Eldbus_Message *msg; 33 Eldbus_Message *msg;
35 34
36 proxy = 35 msg = eldbus_proxy_method_call_new(em->dbus.session, "PauseDeviceComplete");
37 eldbus_proxy_get(em->dbus.obj, "org.freedesktop.login1.Session");
38 if (!proxy)
39 {
40 ERR("Could not get proxy for session");
41 return;
42 }
43
44 msg = eldbus_proxy_method_call_new(proxy, "PauseDeviceComplete");
45 if (!msg) 36 if (!msg)
46 { 37 {
47 ERR("Could not create method call for proxy"); 38 ERR("Could not create method call for proxy");
48 goto end; 39 eldbus_message_unref(msg);
40 return;
49 } 41 }
50 42
51 eldbus_message_arguments_append(msg, "uu", major, minor); 43 eldbus_message_arguments_append(msg, "uu", major, minor);
52 44
53 eldbus_proxy_send(proxy, msg, NULL, NULL, -1); 45 eldbus_proxy_send(em->dbus.session, msg, NULL, NULL, -1);
54
55end:
56 eldbus_message_unref(msg);
57 eldbus_proxy_unref(proxy);
58} 46}
59 47
60static void 48static void
@@ -194,10 +182,10 @@ _logind_dbus_setup(Elput_Manager *em)
194 ERR("Could not get dbus proxy"); 182 ERR("Could not get dbus proxy");
195 goto proxy_err; 183 goto proxy_err;
196 } 184 }
185 em->dbus.manager = proxy;
197 186
198 eldbus_proxy_signal_handler_add(proxy, "SessionRemoved", 187 eldbus_proxy_signal_handler_add(proxy, "SessionRemoved",
199 _cb_session_removed, em); 188 _cb_session_removed, em);
200 eldbus_proxy_unref(proxy);
201 189
202 proxy = 190 proxy =
203 eldbus_proxy_get(em->dbus.obj, "org.freedesktop.login1.Session"); 191 eldbus_proxy_get(em->dbus.obj, "org.freedesktop.login1.Session");
@@ -206,13 +194,12 @@ _logind_dbus_setup(Elput_Manager *em)
206 ERR("Could not get dbus proxy"); 194 ERR("Could not get dbus proxy");
207 goto proxy_err; 195 goto proxy_err;
208 } 196 }
197 em->dbus.session = proxy;
209 198
210 eldbus_proxy_signal_handler_add(proxy, "PauseDevice", 199 eldbus_proxy_signal_handler_add(proxy, "PauseDevice",
211 _cb_device_paused, em); 200 _cb_device_paused, em);
212 eldbus_proxy_signal_handler_add(proxy, "ResumeDevice", 201 eldbus_proxy_signal_handler_add(proxy, "ResumeDevice",
213 _cb_device_resumed, em); 202 _cb_device_resumed, em);
214 eldbus_proxy_unref(proxy);
215
216 proxy = 203 proxy =
217 eldbus_proxy_get(em->dbus.obj, "org.freedesktop.DBus.Properties"); 204 eldbus_proxy_get(em->dbus.obj, "org.freedesktop.DBus.Properties");
218 if (!proxy) 205 if (!proxy)
@@ -235,173 +222,189 @@ obj_err:
235static Eina_Bool 222static Eina_Bool
236_logind_control_take(Elput_Manager *em) 223_logind_control_take(Elput_Manager *em)
237{ 224{
238 Eldbus_Proxy *proxy;
239 Eldbus_Message *msg, *reply; 225 Eldbus_Message *msg, *reply;
240 const char *errname, *errmsg; 226 const char *errname, *errmsg;
241 227
242 proxy = 228 msg = eldbus_proxy_method_call_new(em->dbus.session, "TakeControl");
243 eldbus_proxy_get(em->dbus.obj, "org.freedesktop.login1.Session");
244 if (!proxy)
245 {
246 ERR("Could not get proxy for session");
247 return EINA_FALSE;
248 }
249
250 msg = eldbus_proxy_method_call_new(proxy, "TakeControl");
251 if (!msg) 229 if (!msg)
252 { 230 {
253 ERR("Could not create method call for proxy"); 231 ERR("Could not create method call for proxy");
254 goto msg_err; 232 return EINA_FALSE;
255 } 233 }
256 234
257 eldbus_message_arguments_append(msg, "b", EINA_FALSE); 235 eldbus_message_arguments_append(msg, "b", EINA_FALSE);
258 236
259 reply = eldbus_proxy_send_and_block(proxy, msg, -1); 237 reply = eldbus_proxy_send_and_block(em->dbus.session, msg, -1);
260 if (eldbus_message_error_get(reply, &errname, &errmsg)) 238 if (eldbus_message_error_get(reply, &errname, &errmsg))
261 { 239 {
262 ERR("Eldbus Message Error: %s %s", errname, errmsg); 240 ERR("Eldbus Message Error: %s %s", errname, errmsg);
263 goto msg_err; 241 return EINA_FALSE;
264 } 242 }
265 243
266 eldbus_message_unref(reply); 244 eldbus_message_unref(reply);
267 eldbus_proxy_unref(proxy);
268 245
269 return EINA_TRUE; 246 return EINA_TRUE;
270
271msg_err:
272 eldbus_proxy_unref(proxy);
273 return EINA_FALSE;
274} 247}
275 248
276static void 249static void
277_logind_control_release(Elput_Manager *em) 250_logind_control_release(Elput_Manager *em)
278{ 251{
279 Eldbus_Proxy *proxy;
280 Eldbus_Message *msg; 252 Eldbus_Message *msg;
281 253
282 proxy = 254 msg = eldbus_proxy_method_call_new(em->dbus.session, "ReleaseControl");
283 eldbus_proxy_get(em->dbus.obj, "org.freedesktop.login1.Session"); 255 if (!msg)
284 if (!proxy)
285 { 256 {
286 ERR("Could not get proxy for session"); 257 ERR("Could not create method call for proxy");
287 return; 258 return;
288 } 259 }
289 260
290 msg = eldbus_proxy_method_call_new(proxy, "ReleaseControl"); 261 eldbus_proxy_send(em->dbus.session, msg, NULL, NULL, -1);
262}
263
264static void
265_logind_device_release(Elput_Manager *em, uint32_t major, uint32_t minor)
266{
267 Eldbus_Message *msg;
268
269 msg = eldbus_proxy_method_call_new(em->dbus.session, "ReleaseDevice");
291 if (!msg) 270 if (!msg)
292 { 271 {
293 ERR("Could not create method call for proxy"); 272 ERR("Could not create method call for proxy");
294 goto end; 273 return;
295 } 274 }
296 275
297 eldbus_proxy_send(proxy, msg, NULL, NULL, -1); 276 eldbus_message_arguments_append(msg, "uu", major, minor);
298 277
299end: 278 eldbus_proxy_send(em->dbus.session, msg, NULL, NULL, -1);
300 eldbus_proxy_unref(proxy);
301} 279}
302 280
303static int 281static void
304_logind_device_take(Elput_Manager *em, uint32_t major, uint32_t minor) 282_logind_pipe_write_fd(Elput_Manager *em, int fd)
283{
284 write(em->input.pipe, &fd, sizeof(int));
285 close(em->input.pipe);
286 em->input.pipe = -1;
287}
288
289static void
290_logind_device_take_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
305{ 291{
306 Eldbus_Proxy *proxy;
307 Eldbus_Message *msg, *reply;
308 Eina_Bool p = EINA_FALSE; 292 Eina_Bool p = EINA_FALSE;
309 const char *errname, *errmsg; 293 const char *errname, *errmsg;
310 int fd = -1; 294 int ret, fd = -1;
311 295 int fl, flags;
312 proxy = 296 Elput_Manager *em = data;
313 eldbus_proxy_get(em->dbus.obj, "org.freedesktop.login1.Session");
314 if (!proxy)
315 {
316 ERR("Could not get dbus proxy");
317 return -1;
318 }
319
320 msg = eldbus_proxy_method_call_new(proxy, "TakeDevice");
321 if (!msg)
322 {
323 ERR("Could not create method call for proxy");
324 goto err;
325 }
326 297
327 eldbus_message_arguments_append(msg, "uu", major, minor); 298 if (em->input.current_pending == pending)
299 em->input.current_pending = NULL;
328 300
329 reply = eldbus_proxy_send_and_block(proxy, msg, -1); 301 if (eldbus_message_error_get(msg, &errname, &errmsg))
330 if (eldbus_message_error_get(reply, &errname, &errmsg))
331 { 302 {
332 ERR("Eldbus Message Error: %s %s", errname, errmsg); 303 ERR("Eldbus Message Error: %s %s", errname, errmsg);
333 goto err; 304 goto err;
334 } 305 }
335 306
336 if (!eldbus_message_arguments_get(reply, "hb", &fd, &p)) 307 if (!eldbus_message_arguments_get(msg, "hb", &fd, &p))
337 ERR("Could not get UNIX_FD from dbus message"); 308 ERR("Could not get UNIX_FD from dbus message");
338 309
339 eldbus_message_unref(reply); 310 if (fd < 0) goto err;
311
312 fl = fcntl(fd, F_GETFL);
313 if (fl < 0) goto err;
314
315 flags = (intptr_t)eldbus_pending_data_get(pending, "flags");
316
317 if (flags & O_NONBLOCK)
318 fl |= O_NONBLOCK;
319
320 ret = fcntl(fd, F_SETFL, fl);
321 if (ret < 0) goto err;
322
323 _logind_pipe_write_fd(em, fd);
324 return;
340 325
341err: 326err:
342 eldbus_proxy_unref(proxy); 327 if (fd >= 0)
343 return fd; 328 {
329 uintptr_t majo, mino;
330
331 close(fd);
332 majo = (uintptr_t)eldbus_pending_data_get(pending, "major");
333 mino = (uintptr_t)eldbus_pending_data_get(pending, "minor");
334 _logind_device_release(em, majo, mino);
335 }
336 fd = -1;
337 _logind_pipe_write_fd(em, fd);
344} 338}
345 339
346static void 340static void
347_logind_device_release(Elput_Manager *em, uint32_t major, uint32_t minor) 341_logind_device_take_async(Elput_Manager *em, int flags, uint32_t major, uint32_t minor)
348{ 342{
349 Eldbus_Proxy *proxy;
350 Eldbus_Message *msg; 343 Eldbus_Message *msg;
344 intptr_t fd = -1;
351 345
352 proxy = 346 msg = eldbus_proxy_method_call_new(em->dbus.session, "TakeDevice");
353 eldbus_proxy_get(em->dbus.obj, "org.freedesktop.login1.Session"); 347 if (!msg)
354 if (!proxy)
355 { 348 {
356 ERR("Could not get proxy for session"); 349 ERR("Could not create method call for proxy");
350 _logind_pipe_write_fd(em, fd);
357 return; 351 return;
358 } 352 }
359 353
360 msg = eldbus_proxy_method_call_new(proxy, "ReleaseDevice"); 354 eldbus_message_arguments_append(msg, "uu", major, minor);
355
356 em->input.current_pending = eldbus_proxy_send(em->dbus.session, msg, _logind_device_take_cb, em, -1);
357 if (!em->input.current_pending) CRIT("FAIL!");
358 eldbus_pending_data_set(em->input.current_pending, "major", (uintptr_t*)(uintptr_t)major);
359 eldbus_pending_data_set(em->input.current_pending, "minor", (uintptr_t*)(uintptr_t)minor);
360 eldbus_pending_data_set(em->input.current_pending, "flags", (intptr_t*)(intptr_t)flags);
361}
362
363static int
364_logind_device_take(Elput_Manager *em, uint32_t major, uint32_t minor)
365{
366 Eldbus_Message *msg, *reply;
367 Eina_Bool p = EINA_FALSE;
368 const char *errname, *errmsg;
369 int fd = -1;
370
371 msg = eldbus_proxy_method_call_new(em->dbus.session, "TakeDevice");
361 if (!msg) 372 if (!msg)
362 { 373 {
363 ERR("Could not create method call for proxy"); 374 ERR("Could not create method call for proxy");
364 goto end; 375 return -1;
365 } 376 }
366 377
367 eldbus_message_arguments_append(msg, "uu", major, minor); 378 eldbus_message_arguments_append(msg, "uu", major, minor);
368 379
369 eldbus_proxy_send(proxy, msg, NULL, NULL, -1); 380 reply = eldbus_proxy_send_and_block(em->dbus.session, msg, -1);
381 if (eldbus_message_error_get(reply, &errname, &errmsg))
382 {
383 ERR("Eldbus Message Error: %s %s", errname, errmsg);
384 return -1;
385 }
370 386
371end: 387 if (!eldbus_message_arguments_get(reply, "hb", &fd, &p))
372 eldbus_proxy_unref(proxy); 388 ERR("Could not get UNIX_FD from dbus message");
389
390 eldbus_message_unref(reply);
391 return fd;
373} 392}
374 393
375static Eina_Bool 394static Eina_Bool
376_logind_activate(Elput_Manager *em) 395_logind_activate(Elput_Manager *em)
377{ 396{
378 Eldbus_Proxy *proxy;
379 Eldbus_Message *msg; 397 Eldbus_Message *msg;
380 398
381 proxy = 399 msg = eldbus_proxy_method_call_new(em->dbus.session, "Activate");
382 eldbus_proxy_get(em->dbus.obj, "org.freedesktop.login1.Session");
383 if (!proxy)
384 {
385 ERR("Could not get proxy for session");
386 return EINA_FALSE;
387 }
388
389 msg = eldbus_proxy_method_call_new(proxy, "Activate");
390 if (!msg) 400 if (!msg)
391 { 401 {
392 ERR("Could not create method call for proxy"); 402 ERR("Could not create method call for proxy");
393 goto msg_err; 403 return EINA_FALSE;
394 } 404 }
395 405
396 eldbus_proxy_send(proxy, msg, NULL, NULL, -1); 406 eldbus_proxy_send(em->dbus.session, msg, NULL, NULL, -1);
397
398 eldbus_proxy_unref(proxy);
399
400 return EINA_TRUE; 407 return EINA_TRUE;
401
402msg_err:
403 eldbus_proxy_unref(proxy);
404 return EINA_FALSE;
405} 408}
406 409
407static Eina_Bool 410static Eina_Bool
@@ -498,6 +501,8 @@ static void
498_logind_disconnect(Elput_Manager *em) 501_logind_disconnect(Elput_Manager *em)
499{ 502{
500 _logind_control_release(em); 503 _logind_control_release(em);
504 eldbus_proxy_unref(em->dbus.manager);
505 eldbus_proxy_unref(em->dbus.session);
501 eldbus_object_unref(em->dbus.obj); 506 eldbus_object_unref(em->dbus.obj);
502 free(em->dbus.path); 507 free(em->dbus.path);
503 _logind_dbus_close(em->dbus.conn); 508 _logind_dbus_close(em->dbus.conn);
@@ -506,6 +511,18 @@ _logind_disconnect(Elput_Manager *em)
506 free(em); 511 free(em);
507} 512}
508 513
514static void
515_logind_open_async(Elput_Manager *em, const char *path, int flags)
516{
517 struct stat st;
518 intptr_t fd = -1;
519
520 if ((stat(path, &st) < 0) || (!S_ISCHR(st.st_mode)))
521 _logind_pipe_write_fd(em, fd);
522 else
523 _logind_device_take_async(em, flags, major(st.st_rdev), minor(st.st_rdev));
524}
525
509static int 526static int
510_logind_open(Elput_Manager *em, const char *path, int flags) 527_logind_open(Elput_Manager *em, const char *path, int flags)
511{ 528{
@@ -606,6 +623,7 @@ Elput_Interface _logind_interface =
606 _logind_connect, 623 _logind_connect,
607 _logind_disconnect, 624 _logind_disconnect,
608 _logind_open, 625 _logind_open,
626 _logind_open_async,
609 _logind_close, 627 _logind_close,
610 _logind_vt_set, 628 _logind_vt_set,
611}; 629};
diff --git a/src/lib/elput/elput_manager.c b/src/lib/elput/elput_manager.c
index b1378f55b0..3b127afdc7 100644
--- a/src/lib/elput/elput_manager.c
+++ b/src/lib/elput/elput_manager.c
@@ -58,6 +58,14 @@ elput_manager_disconnect(Elput_Manager *manager)
58 EINA_SAFETY_ON_NULL_RETURN(manager); 58 EINA_SAFETY_ON_NULL_RETURN(manager);
59 EINA_SAFETY_ON_NULL_RETURN(manager->interface); 59 EINA_SAFETY_ON_NULL_RETURN(manager->interface);
60 60
61
62 if (manager->input.thread)
63 {
64 ecore_thread_cancel(manager->input.thread);
65 manager->del = 1;
66 return;
67 }
68
61 if (manager->interface->disconnect) 69 if (manager->interface->disconnect)
62 manager->interface->disconnect(manager); 70 manager->interface->disconnect(manager);
63} 71}
diff --git a/src/lib/elput/elput_private.h b/src/lib/elput/elput_private.h
index c2f4b007ea..a934bf1d23 100644
--- a/src/lib/elput/elput_private.h
+++ b/src/lib/elput/elput_private.h
@@ -71,6 +71,7 @@ typedef struct _Elput_Interface
71 Eina_Bool (*connect)(Elput_Manager **manager, const char *seat, unsigned int tty); 71 Eina_Bool (*connect)(Elput_Manager **manager, const char *seat, unsigned int tty);
72 void (*disconnect)(Elput_Manager *manager); 72 void (*disconnect)(Elput_Manager *manager);
73 int (*open)(Elput_Manager *manager, const char *path, int flags); 73 int (*open)(Elput_Manager *manager, const char *path, int flags);
74 void (*open_async)(Elput_Manager *manager, const char *path, int flags);
74 void (*close)(Elput_Manager *manager, int fd); 75 void (*close)(Elput_Manager *manager, int fd);
75 Eina_Bool (*vt_set)(Elput_Manager *manager, int vt); 76 Eina_Bool (*vt_set)(Elput_Manager *manager, int vt);
76} Elput_Interface; 77} Elput_Interface;
@@ -82,6 +83,9 @@ typedef struct _Elput_Input
82 Ecore_Fd_Handler *hdlr; 83 Ecore_Fd_Handler *hdlr;
83 84
84 Eina_List *seats; 85 Eina_List *seats;
86 Ecore_Thread *thread;
87 Eldbus_Pending *current_pending;
88 int pipe;
85 89
86 Eina_Bool suspended : 1; 90 Eina_Bool suspended : 1;
87} Elput_Input; 91} Elput_Input;
@@ -224,18 +228,30 @@ struct _Elput_Manager
224 char *sid; 228 char *sid;
225 const char *seat; 229 const char *seat;
226 unsigned int vt_num; 230 unsigned int vt_num;
231 int vt_fd;
227 Ecore_Event_Handler *vt_hdlr; 232 Ecore_Event_Handler *vt_hdlr;
233 uint32_t window;
228 234
229 struct 235 struct
230 { 236 {
231 char *path; 237 char *path;
232 Eldbus_Object *obj; 238 Eldbus_Object *obj;
233 Eldbus_Connection *conn; 239 Eldbus_Connection *conn;
240 Eldbus_Proxy *session;
241 Eldbus_Proxy *manager;
234 } dbus; 242 } dbus;
235 243
236 Elput_Input input; 244 Elput_Input input;
245 Eina_Bool del : 1;
237}; 246};
238 247
248typedef struct _Elput_Async_Open
249{
250 Elput_Manager *manager;
251 char *path;
252 int flags;
253} Elput_Async_Open;
254
239int _evdev_event_process(struct libinput_event *event); 255int _evdev_event_process(struct libinput_event *event);
240Elput_Device *_evdev_device_create(Elput_Seat *seat, struct libinput_device *device); 256Elput_Device *_evdev_device_create(Elput_Seat *seat, struct libinput_device *device);
241void _evdev_device_destroy(Elput_Device *edev); 257void _evdev_device_destroy(Elput_Device *edev);