]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
[daemon] Tell splash to become idle before quitting
authorRay Strode <rstrode@redhat.com>
Mon, 4 May 2009 00:55:16 +0000 (20:55 -0400)
committerRay Strode <rstrode@redhat.com>
Wed, 20 May 2009 21:27:53 +0000 (17:27 -0400)
This allows it to, e.g., finish up its current round of animations or
fade out the progress bar or whatever.

src/main.c
src/ply-boot-server.c
src/ply-boot-server.h
src/ply-boot-splash.c

index 440ac11e45a26bbc8f77ab42c0d7a3cc6fe72eb7..ee3ffd6e521b4af895ac7cda577880d54f1bc9c1 100644 (file)
@@ -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 *
index c135617fe022bca034f244fed7370ff9e1cb999e..96fad90e90933a0acc324f29a4f0b6e9509b2e69 100644 (file)
@@ -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)
     {
index 99ee2a5c1189940aeac81064acdc380e772e25d1..ad145ca20a627574ffbc6cb2485a781bf6cf7a9f 100644 (file)
@@ -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
index c92ae1a57067f1dc71add5ca8d3951285e0c3615..8a0128e3cbf629abf6093608d77c12fad4985dc9 100644 (file)
@@ -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);
 }