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;
uint32_t is_redirected : 1;
uint32_t is_attached : 1;
uint32_t should_be_attached : 1;
+ uint32_t should_retain_splash : 1;
char *console;
#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 *
}
+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,
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)
{
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
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;
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,
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);
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,
{
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);
}