summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Michael <cp.michael@samsung.com>2013-06-26 11:52:58 +0100
committerChris Michael <cp.michael@samsung.com>2013-06-26 11:57:49 +0100
commit3230114ff9ae67cd25fbdc3d403c93c423601696 (patch)
tree6be3da360dbc2b8ddbc16c8b0b140a2dab1bb207
parent6445fea318f29fd6b1de0bc6fbe1b66bcc5673ba (diff)
feature: Add support for global_remove in the display listener.
bugfix T151: Catch fatal error from wayland displays and signal apps to exit. Signed-off-by: Chris Michael <cp.michael@samsung.com>
-rw-r--r--src/lib/ecore_wayland/ecore_wl.c88
1 files changed, 76 insertions, 12 deletions
diff --git a/src/lib/ecore_wayland/ecore_wl.c b/src/lib/ecore_wayland/ecore_wl.c
index 879314665a..9578c197d5 100644
--- a/src/lib/ecore_wayland/ecore_wl.c
+++ b/src/lib/ecore_wayland/ecore_wl.c
@@ -10,6 +10,7 @@ static Eina_Bool _ecore_wl_shutdown(Eina_Bool close);
10static Eina_Bool _ecore_wl_cb_idle_enterer(void *data); 10static Eina_Bool _ecore_wl_cb_idle_enterer(void *data);
11static Eina_Bool _ecore_wl_cb_handle_data(void *data, Ecore_Fd_Handler *hdl); 11static Eina_Bool _ecore_wl_cb_handle_data(void *data, Ecore_Fd_Handler *hdl);
12static void _ecore_wl_cb_handle_global(void *data, struct wl_registry *registry, unsigned int id, const char *interface, unsigned int version EINA_UNUSED); 12static void _ecore_wl_cb_handle_global(void *data, struct wl_registry *registry, unsigned int id, const char *interface, unsigned int version EINA_UNUSED);
13static void _ecore_wl_cb_handle_global_remove(void *data, struct wl_registry *registry EINA_UNUSED, unsigned int id);
13static Eina_Bool _ecore_wl_xkb_init(Ecore_Wl_Display *ewd); 14static Eina_Bool _ecore_wl_xkb_init(Ecore_Wl_Display *ewd);
14static Eina_Bool _ecore_wl_xkb_shutdown(Ecore_Wl_Display *ewd); 15static Eina_Bool _ecore_wl_xkb_shutdown(Ecore_Wl_Display *ewd);
15static void _ecore_wl_sync_wait(Ecore_Wl_Display *ewd); 16static void _ecore_wl_sync_wait(Ecore_Wl_Display *ewd);
@@ -18,15 +19,18 @@ static void _ecore_wl_animator_tick_cb_begin(void *data EINA_UNUSED);
18static void _ecore_wl_animator_tick_cb_end(void *data EINA_UNUSED); 19static void _ecore_wl_animator_tick_cb_end(void *data EINA_UNUSED);
19static void _ecore_wl_animator_callback(void *data, struct wl_callback *callback, uint32_t serial EINA_UNUSED); 20static void _ecore_wl_animator_callback(void *data, struct wl_callback *callback, uint32_t serial EINA_UNUSED);
20static Eina_Bool _ecore_wl_animator_window_add(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata EINA_UNUSED); 21static Eina_Bool _ecore_wl_animator_window_add(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata EINA_UNUSED);
22static void _ecore_wl_signal_exit(void);
23static void _ecore_wl_signal_exit_free(void *data EINA_UNUSED, void *event);
21 24
22/* local variables */ 25/* local variables */
23static int _ecore_wl_init_count = 0; 26static int _ecore_wl_init_count = 0;
24static Eina_Bool _ecore_wl_animator_busy = EINA_FALSE; 27static Eina_Bool _ecore_wl_animator_busy = EINA_FALSE;
28static Eina_Bool _ecore_wl_fatal_error = EINA_FALSE;
25 29
26static const struct wl_registry_listener _ecore_wl_registry_listener = 30static const struct wl_registry_listener _ecore_wl_registry_listener =
27{ 31{
28 _ecore_wl_cb_handle_global, 32 _ecore_wl_cb_handle_global,
29 NULL // handle_global_remove 33 _ecore_wl_cb_handle_global_remove
30}; 34};
31 35
32static const struct wl_callback_listener _ecore_wl_sync_listener = 36static const struct wl_callback_listener _ecore_wl_sync_listener =
@@ -160,6 +164,8 @@ ecore_wl_init(const char *name)
160 wl_registry_add_listener(_ecore_wl_disp->wl.registry, 164 wl_registry_add_listener(_ecore_wl_disp->wl.registry,
161 &_ecore_wl_registry_listener, _ecore_wl_disp); 165 &_ecore_wl_registry_listener, _ecore_wl_disp);
162 166
167 /* NB: Hmmm, should we display_dispatch here ?? */
168
163 if (!_ecore_wl_xkb_init(_ecore_wl_disp)) 169 if (!_ecore_wl_xkb_init(_ecore_wl_disp))
164 { 170 {
165 ERR("Could not initialize XKB"); 171 ERR("Could not initialize XKB");
@@ -348,7 +354,7 @@ _ecore_wl_shutdown(Eina_Bool close)
348 if (_ecore_wl_disp->idle_enterer) 354 if (_ecore_wl_disp->idle_enterer)
349 ecore_idle_enterer_del(_ecore_wl_disp->idle_enterer); 355 ecore_idle_enterer_del(_ecore_wl_disp->idle_enterer);
350 356
351 if (close) 357 if ((close) && (!_ecore_wl_fatal_error))
352 { 358 {
353 Ecore_Wl_Output *out, *tout; 359 Ecore_Wl_Output *out, *tout;
354 Ecore_Wl_Input *in, *tin; 360 Ecore_Wl_Input *in, *tin;
@@ -399,17 +405,32 @@ static Eina_Bool
399_ecore_wl_cb_idle_enterer(void *data) 405_ecore_wl_cb_idle_enterer(void *data)
400{ 406{
401 Ecore_Wl_Display *ewd; 407 Ecore_Wl_Display *ewd;
402 int ret; 408 int ret = 0;
409
410 if (_ecore_wl_fatal_error) return ECORE_CALLBACK_CANCEL;
403 411
404 if (!(ewd = data)) return ECORE_CALLBACK_RENEW; 412 if (!(ewd = data)) return ECORE_CALLBACK_RENEW;
405 413
414 ret = wl_display_get_error(ewd->wl.display);
415 if (ret < 0) goto err;
416
417 ret = wl_display_dispatch_pending(ewd->wl.display);
418 if (ret < 0) goto err;
419
406 ret = wl_display_flush(ewd->wl.display); 420 ret = wl_display_flush(ewd->wl.display);
407 if ((ret < 0) && (errno == EAGAIN)) 421 if ((ret < 0) && (errno == EAGAIN))
408 ecore_main_fd_handler_active_set(ewd->fd_hdl, 422 ecore_main_fd_handler_active_set(ewd->fd_hdl,
409 (ECORE_FD_READ | ECORE_FD_WRITE)); 423 (ECORE_FD_READ | ECORE_FD_WRITE));
410 else if (ret < 0) 424
425 return ECORE_CALLBACK_RENEW;
426
427err:
428 if ((ret < 0) && ((errno != EAGAIN) && (errno != EINVAL)))
411 { 429 {
412 /* FIXME: need do error processing? */ 430 _ecore_wl_fatal_error = EINA_TRUE;
431
432 /* raise exit signal */
433 _ecore_wl_signal_exit();
413 } 434 }
414 435
415 return ECORE_CALLBACK_RENEW; 436 return ECORE_CALLBACK_RENEW;
@@ -419,9 +440,12 @@ static Eina_Bool
419_ecore_wl_cb_handle_data(void *data, Ecore_Fd_Handler *hdl) 440_ecore_wl_cb_handle_data(void *data, Ecore_Fd_Handler *hdl)
420{ 441{
421 Ecore_Wl_Display *ewd; 442 Ecore_Wl_Display *ewd;
443 int ret = 0;
422 444
423 /* LOGFN(__FILE__, __LINE__, __FUNCTION__); */ 445 /* LOGFN(__FILE__, __LINE__, __FUNCTION__); */
424 446
447 if (_ecore_wl_fatal_error) return ECORE_CALLBACK_CANCEL;
448
425 if (!(ewd = data)) return ECORE_CALLBACK_RENEW; 449 if (!(ewd = data)) return ECORE_CALLBACK_RENEW;
426 450
427 /* FIXME: This should also catch ECORE_FD_ERROR and exit */ 451 /* FIXME: This should also catch ECORE_FD_ERROR and exit */
@@ -429,18 +453,20 @@ _ecore_wl_cb_handle_data(void *data, Ecore_Fd_Handler *hdl)
429 /* wl_display_dispatch_pending(ewd->wl.display); */ 453 /* wl_display_dispatch_pending(ewd->wl.display); */
430 454
431 if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_READ)) 455 if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_READ))
432 wl_display_dispatch(ewd->wl.display); 456 ret = wl_display_dispatch(ewd->wl.display);
433 else if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_WRITE)) 457 else if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_WRITE))
434 { 458 {
435 int ret = 0;
436
437 ret = wl_display_flush(ewd->wl.display); 459 ret = wl_display_flush(ewd->wl.display);
438 if (ret == 0) 460 if (ret == 0)
439 ecore_main_fd_handler_active_set(hdl, ECORE_FD_READ); 461 ecore_main_fd_handler_active_set(hdl, ECORE_FD_READ);
440 else if ((ret == -1) && (errno != EAGAIN)) 462 }
441 { 463
442 /* FIXME: need do error processing? */ 464 if ((ret < 0) && ((errno != EAGAIN) && (errno != EINVAL)))
443 } 465 {
466 _ecore_wl_fatal_error = EINA_TRUE;
467
468 /* raise exit signal */
469 _ecore_wl_signal_exit();
444 } 470 }
445 471
446 return ECORE_CALLBACK_RENEW; 472 return ECORE_CALLBACK_RENEW;
@@ -508,6 +534,25 @@ _ecore_wl_cb_handle_global(void *data, struct wl_registry *registry, unsigned in
508 } 534 }
509} 535}
510 536
537static void
538_ecore_wl_cb_handle_global_remove(void *data, struct wl_registry *registry EINA_UNUSED, unsigned int id)
539{
540 Ecore_Wl_Display *ewd;
541 Ecore_Wl_Global *global, *tmp;
542
543 LOGFN(__FILE__, __LINE__, __FUNCTION__);
544
545 ewd = data;
546
547 wl_list_for_each_safe(global, tmp, &ewd->globals, link)
548 {
549 if (global->id != id) continue;
550 wl_list_remove(&global->link);
551 free(global->interface);
552 free(global);
553 }
554}
555
511static Eina_Bool 556static Eina_Bool
512_ecore_wl_xkb_init(Ecore_Wl_Display *ewd) 557_ecore_wl_xkb_init(Ecore_Wl_Display *ewd)
513{ 558{
@@ -601,3 +646,22 @@ _ecore_wl_animator_window_add(const Eina_Hash *hash EINA_UNUSED, const void *key
601 646
602 return EINA_TRUE; 647 return EINA_TRUE;
603} 648}
649
650static void
651_ecore_wl_signal_exit(void)
652{
653 Ecore_Event_Signal_Exit *ev;
654
655 if (!(ev = calloc(1, sizeof(Ecore_Event_Signal_Exit))))
656 return;
657
658 ev->quit = 1;
659 ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, ev,
660 _ecore_wl_signal_exit_free, NULL);
661}
662
663static void
664_ecore_wl_signal_exit_free(void *data EINA_UNUSED, void *event)
665{
666 free(event);
667}