From: Ray Strode Date: Mon, 4 May 2009 00:55:16 +0000 (-0400) Subject: [daemon] Tell splash to become idle before quitting X-Git-Tag: 0.7.0~169 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3df0f12602ebff6f1f7c67a8a39735883dd8dc49;p=thirdparty%2Fplymouth.git [daemon] Tell splash to become idle before quitting This allows it to, e.g., finish up its current round of animations or fade out the progress bar or whatever. --- diff --git a/src/main.c b/src/main.c index 440ac11e..ee3ffd6e 100644 --- a/src/main.c +++ b/src/main.c @@ -91,6 +91,8 @@ typedef struct ply_command_parser_t *command_parser; ply_mode_t mode; + ply_trigger_t *quit_trigger; + char kernel_command_line[PLY_MAX_COMMAND_LINE_SIZE]; uint32_t no_boot_log : 1; uint32_t showing_details : 1; @@ -98,6 +100,7 @@ typedef struct uint32_t is_redirected : 1; uint32_t is_attached : 1; uint32_t should_be_attached : 1; + uint32_t should_retain_splash : 1; char *console; @@ -663,32 +666,65 @@ tell_gdm_to_transition (void) #endif static void -on_quit (state_t *state, - bool retain_splash) +quit_program (state_t *state) { - ply_trace ("time to quit, closing log"); - if (state->session != NULL) - ply_terminal_session_close_log (state->session); - ply_trace ("unloading splash"); - if (state->boot_splash != NULL) - { - if (!retain_splash) - { - if (state->boot_splash != NULL) - ply_boot_splash_hide (state->boot_splash); - } - - quit_splash (state); - } ply_trace ("exiting event loop"); ply_event_loop_exit (state->loop, 0); #ifdef PLY_ENABLE_GDM_TRANSITION - if (retain_splash) + if (state->should_retain_splash) { tell_gdm_to_transition (); } #endif + + if (state->quit_trigger != NULL) + { + ply_trigger_pull (state->quit_trigger, NULL); + state->quit_trigger = NULL; + } +} + +static void +on_boot_splash_idle (state_t *state) +{ + ply_trace ("boot splash idle"); + if (!state->should_retain_splash) + { + ply_trace ("hiding splash"); + if (state->boot_splash != NULL) + ply_boot_splash_hide (state->boot_splash); + } + + ply_trace ("quitting splash"); + quit_splash (state); + ply_trace ("quitting program"); + quit_program (state); +} + +static void +on_quit (state_t *state, + bool retain_splash, + ply_trigger_t *quit_trigger) +{ + ply_trace ("time to quit, closing log"); + if (state->session != NULL) + ply_terminal_session_close_log (state->session); + ply_trace ("unloading splash"); + + state->should_retain_splash = retain_splash; + + state->quit_trigger = quit_trigger; + + if (state->boot_splash != NULL) + { + ply_boot_splash_become_idle (state->boot_splash, + (ply_boot_splash_on_idle_handler_t) + on_boot_splash_idle, + state); + } + else + quit_program (state); } static ply_boot_server_t * diff --git a/src/ply-boot-server.c b/src/ply-boot-server.c index c135617f..96fad90e 100644 --- a/src/ply-boot-server.c +++ b/src/ply-boot-server.c @@ -271,6 +271,16 @@ ply_boot_connection_on_password_answer (ply_boot_connection_t *connection, } +static void +ply_boot_connection_on_quit_complete (ply_boot_connection_t *connection) +{ + if (!ply_write (connection->fd, + PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK, + strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK))) + { + ply_error ("could not write bytes: %m"); + } +} static void ply_boot_connection_on_question_answer (ply_boot_connection_t *connection, @@ -345,11 +355,22 @@ ply_boot_connection_on_request (ply_boot_connection_t *connection) else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_QUIT) == 0) { bool retain_splash; + ply_trigger_t *quit_trigger; retain_splash = (bool) argument[0]; + quit_trigger = ply_trigger_new (NULL); + + ply_trigger_add_handler (quit_trigger, + (ply_trigger_handler_t) + ply_boot_connection_on_quit_complete, + connection); + if (server->quit_handler != NULL) - server->quit_handler (server->user_data, retain_splash, server); + server->quit_handler (server->user_data, retain_splash, quit_trigger, server); + + free(command); + return; } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PASSWORD) == 0) { diff --git a/src/ply-boot-server.h b/src/ply-boot-server.h index 99ee2a5c..ad145ca2 100644 --- a/src/ply-boot-server.h +++ b/src/ply-boot-server.h @@ -82,6 +82,7 @@ typedef void (* ply_boot_server_error_handler_t) (void *user_data, ply_boot_server_t *server); typedef void (* ply_boot_server_quit_handler_t) (void *user_data, bool retain_splash, + ply_trigger_t *quit_trigger, ply_boot_server_t *server); #ifndef PLY_HIDE_FUNCTION_DECLARATIONS diff --git a/src/ply-boot-splash.c b/src/ply-boot-splash.c index c92ae1a5..8a0128e3 100644 --- a/src/ply-boot-splash.c +++ b/src/ply-boot-splash.c @@ -61,6 +61,8 @@ struct _ply_boot_splash char *status; ply_progress_t *progress; + ply_boot_splash_on_idle_handler_t idle_handler; + void *idle_handler_user_data; uint32_t is_loaded : 1; uint32_t is_shown : 1; @@ -69,6 +71,9 @@ struct _ply_boot_splash typedef const ply_boot_splash_plugin_interface_t * (* get_plugin_interface_function_t) (void); +static void ply_boot_splash_update_progress (ply_boot_splash_t *splash); +static void ply_boot_splash_detach_from_event_loop (ply_boot_splash_t *splash); + ply_boot_splash_t * ply_boot_splash_new (const char *theme_path, const char *plugin_dir, @@ -194,12 +199,30 @@ ply_boot_splash_unload (ply_boot_splash_t *splash) void ply_boot_splash_free (ply_boot_splash_t *splash) { + ply_trace ("freeing splash"); if (splash == NULL) return; + if (splash->loop != NULL) + { + if (splash->plugin_interface->on_boot_progress != NULL) + { + ply_event_loop_stop_watching_for_timeout (splash->loop, + (ply_event_loop_timeout_handler_t) + ply_boot_splash_update_progress, splash); + } + + ply_event_loop_stop_watching_for_exit (splash->loop, (ply_event_loop_exit_handler_t) + ply_boot_splash_detach_from_event_loop, + splash); + } + if (splash->module_handle != NULL) ply_boot_splash_unload (splash); + if (splash->idle_trigger != NULL) + ply_trigger_free (splash->idle_trigger); + free (splash->theme_path); free (splash->plugin_dir); free (splash); @@ -403,6 +426,19 @@ ply_boot_splash_attach_to_event_loop (ply_boot_splash_t *splash, splash); } +static void +on_idle (ply_boot_splash_t *splash) +{ + + ply_trace ("splash now idle"); + ply_event_loop_watch_for_timeout (splash->loop, 0.01, + (ply_event_loop_timeout_handler_t) + splash->idle_handler, + splash->idle_handler_user_data); + splash->idle_handler = NULL; + splash->idle_handler_user_data = NULL; +} + void ply_boot_splash_become_idle (ply_boot_splash_t *splash, ply_boot_splash_on_idle_handler_t idle_handler, @@ -410,16 +446,24 @@ ply_boot_splash_become_idle (ply_boot_splash_t *splash, { assert (splash->idle_trigger == NULL); + ply_trace ("telling splash to become idle"); if (splash->plugin_interface->become_idle == NULL) { - idle_handler (user_data); + ply_event_loop_watch_for_timeout (splash->loop, 0.01, + (ply_event_loop_timeout_handler_t) + idle_handler, + user_data); + return; } + splash->idle_handler = idle_handler; + splash->idle_handler_user_data = user_data; + splash->idle_trigger = ply_trigger_new (&splash->idle_trigger); ply_trigger_add_handler (splash->idle_trigger, - (ply_trigger_handler_t) idle_handler, - user_data); + (ply_trigger_handler_t) on_idle, + splash); splash->plugin_interface->become_idle (splash->plugin, splash->idle_trigger); }