#define BAR_HEIGHT 16
#endif
-#ifndef DEFAULT_BOOT_DURATION
-#define DEFAULT_BOOT_DURATION 45.0
-#endif
-
-#define BOOTTIME_FILE PLYMOUTH_TIME_DIR "/boot-time"
-
struct _ply_boot_splash_plugin
{
ply_event_loop_t *loop;
ply_label_t *label;
ply_progress_bar_t *progress_bar;
- double boot_duration;
- double start_time;
- double wait_time;
-
ply_trigger_t *pending_password_answer;
ply_trigger_t *idle_trigger;
ply_boot_splash_plugin_t *
create_plugin (void)
{
- FILE *fh;
ply_boot_splash_plugin_t *plugin;
srand ((int) ply_get_timestamp ());
plugin->label = ply_label_new ();
plugin->progress_bar = ply_progress_bar_new ();
- plugin->start_time = ply_get_timestamp ();
- plugin->boot_duration = DEFAULT_BOOT_DURATION;
- /* We should be reading from the initrd at this point */
- fh = fopen(BOOTTIME_FILE,"r");
- if (fh != NULL) {
- int r;
- r = fscanf (fh,"%lf",&plugin->boot_duration);
- /* Don't need to check the return value - if this failed we still have
- * the default BOOTTIME value, which was set above */
- fclose (fh);
- }
-
return plugin;
}
void
destroy_plugin (ply_boot_splash_plugin_t *plugin)
{
- FILE *boot_duration;
if (plugin == NULL)
return;
-
if (plugin->loop != NULL)
{
ply_event_loop_stop_watching_for_exit (plugin->loop, (ply_event_loop_exit_handler_t)
ply_label_free (plugin->label);
ply_progress_bar_free (plugin->progress_bar);
- ply_trace ("writing boot_duration");
- /* At this point we should have a real rootfs */
- boot_duration = fopen (BOOTTIME_FILE,"w");
- if (boot_duration != NULL) {
- fprintf (boot_duration,"%.1f\n", (ply_get_timestamp () - plugin->start_time));
- fclose (boot_duration);
- }
-
#ifdef PLY_ENABLE_GDM_TRANSITION
if (plugin->is_visible)
tell_gdm_to_transition ();
ply_frame_buffer_unpause_updates (plugin->frame_buffer);
}
-static void
-animate_bar (ply_boot_splash_plugin_t *plugin)
-{
- double duration;
- double percent_done;
-
- assert (plugin != NULL);
- assert (plugin->loop != NULL);
-
- duration = ply_get_timestamp () - plugin->start_time;
-
- /* Fun made-up smoothing function to make the growth asymptotic:
- * fraction(time,estimate)=1-2^(-(time^1.45)/estimate) */
- percent_done = 1.0 - pow (2.0, -pow (duration, 1.45) / plugin->boot_duration);
-
- ply_progress_bar_set_percent_done (plugin->progress_bar, percent_done);
- ply_progress_bar_draw (plugin->progress_bar);
-
- ply_event_loop_watch_for_timeout(plugin->loop,
- 1.0 / FRAMES_PER_SECOND,
- (ply_event_loop_timeout_handler_t)
- animate_bar, plugin);
-}
-
static void
start_animation (ply_boot_splash_plugin_t *plugin)
{
ply_progress_bar_show (plugin->progress_bar,
plugin->window,
0, area.height - ply_progress_bar_get_height (plugin->progress_bar));
- animate_bar (plugin);
}
static void
assert (plugin->loop != NULL);
ply_throbber_stop (plugin->throbber, trigger);
- ply_event_loop_stop_watching_for_timeout(plugin->loop,
- (ply_event_loop_timeout_handler_t)
- animate_bar, plugin);
#ifdef ENABLE_FADE_OUT
for (i = 0; i < 10; i++)
ply_entry_hide (plugin->entry);
ply_entry_remove_all_bullets (plugin->entry);
- plugin->start_time += (ply_get_timestamp() - plugin->wait_time);
start_animation (plugin);
}
assert (plugin != NULL);
}
+void
+on_boot_progress (ply_boot_splash_plugin_t *plugin,
+ double duration,
+ double percent_done)
+{
+ double total_duration;
+
+ total_duration = duration / percent_done;
+
+ /* Fun made-up smoothing function to make the growth asymptotic:
+ * fraction(time,estimate)=1-2^(-(time^1.45)/estimate) */
+ percent_done = 1.0 - pow (2.0, -pow (duration, 1.45) / total_duration);
+
+ ply_progress_bar_set_percent_done (plugin->progress_bar, percent_done);
+ ply_progress_bar_draw (plugin->progress_bar);
+}
+
void
hide_splash_screen (ply_boot_splash_plugin_t *plugin,
ply_event_loop_t *loop)
ply_trigger_t *answer)
{
plugin->pending_password_answer = answer;
- plugin->wait_time = ply_get_timestamp ();
if (ply_entry_is_hidden (plugin->entry))
{
.remove_window = remove_window,
.show_splash_screen = show_splash_screen,
.update_status = update_status,
+ .on_boot_progress = on_boot_progress,
.hide_splash_screen = hide_splash_screen,
.ask_for_password = ask_for_password,
.on_root_mounted = on_root_mounted,
- .become_idle = become_idle
+ .become_idle = become_idle,
};
return &plugin_interface;
#include "ply-trigger.h"
#include "ply-utils.h"
+#ifndef UPDATES_PER_SECOND
+#define UPDATES_PER_SECOND 30
+#endif
+
+#ifndef DEFAULT_BOOT_DURATION
+#define DEFAULT_BOOT_DURATION 45.0
+#endif
+
+#define BOOT_DURATION_FILE PLYMOUTH_TIME_DIRECTORY "/boot-duration"
+
struct _ply_boot_splash
{
ply_event_loop_t *loop;
char *module_name;
char *status;
+ double boot_duration;
+ double start_time;
+ double wait_time;
+
uint32_t is_shown : 1;
};
return true;
}
+static void
+load_boot_duration (ply_boot_splash_t *splash)
+{
+ FILE *fp;
+ int items_matched;
+
+ fp = fopen (BOOT_DURATION_FILE,"r");
+
+ if (fp == NULL)
+ return;
+
+ items_matched = fscanf (fp, "%lf", &splash->boot_duration);
+
+ fclose (fp);
+
+ if (items_matched != 1)
+ splash->boot_duration = DEFAULT_BOOT_DURATION;
+}
+
+static void
+save_boot_duration (ply_boot_splash_t *splash)
+{
+ FILE *fp;
+
+ fp = fopen (BOOT_DURATION_FILE,"w");
+
+ if (fp != NULL)
+ {
+ fprintf (fp, "%.1f\n", (ply_get_timestamp () - splash->start_time));
+ fclose (fp);
+ }
+}
+
static void
ply_boot_splash_unload_plugin (ply_boot_splash_t *splash)
{
ply_close_module (splash->module_handle);
splash->plugin_interface = NULL;
splash->module_handle = NULL;
+
+ save_boot_duration (splash);
}
void
free (splash);
}
+static void
+ply_boot_splash_update_progress (ply_boot_splash_t *splash)
+{
+ double time_in_seconds;
+
+ assert (splash != NULL);
+
+ time_in_seconds = ply_get_timestamp () - splash->start_time;
+
+ if (splash->plugin_interface->on_boot_progress != NULL)
+ splash->plugin_interface->on_boot_progress (splash->plugin,
+ time_in_seconds,
+ time_in_seconds / splash->boot_duration);
+
+ ply_event_loop_watch_for_timeout (splash->loop,
+ 1.0 / UPDATES_PER_SECOND,
+ (ply_event_loop_timeout_handler_t)
+ ply_boot_splash_update_progress, splash);
+}
+
bool
ply_boot_splash_show (ply_boot_splash_t *splash)
{
if (splash->is_shown)
return true;
+ splash->start_time = ply_get_timestamp ();
+ splash->boot_duration = DEFAULT_BOOT_DURATION;
+
ply_trace ("trying to load %s", splash->module_name);
if (!ply_boot_splash_load_plugin (splash))
{
return false;
}
+ if (splash->plugin_interface->on_boot_progress != NULL)
+ {
+ ply_event_loop_watch_for_timeout (splash->loop,
+ 1.0 / UPDATES_PER_SECOND,
+ (ply_event_loop_timeout_handler_t)
+ ply_boot_splash_update_progress, splash);
+ }
+
splash->is_shown = true;
return true;
}
if (splash->plugin_interface->on_root_mounted != NULL)
splash->plugin_interface->on_root_mounted (splash->plugin);
+
+ if (splash->plugin_interface->on_boot_progress != NULL)
+ load_boot_duration (splash);
+}
+
+static void
+on_password_answered (ply_boot_splash_t *splash)
+{
+ splash->start_time += (ply_get_timestamp () - splash->wait_time);
}
void
return;
}
+ splash->wait_time = ply_get_timestamp ();
+ ply_trigger_add_handler (trigger,
+ (ply_trigger_handler_t)
+ on_password_answered, splash);
+
splash->plugin_interface->ask_for_password (splash->plugin,
prompt,
trigger);
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);