summaryrefslogtreecommitdiff
path: root/src/lib/elput/elput_logind.c
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/elput_logind.c
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/elput_logind.c')
-rw-r--r--src/lib/elput/elput_logind.c226
1 files changed, 122 insertions, 104 deletions
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};