From: Ray Strode Date: Mon, 19 May 2008 21:46:10 +0000 (-0400) Subject: Create window at layer above boot splash and reuse when changing boot splashes X-Git-Tag: 0.1.0~108 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fe6a3b007aeb392fdcd41c69c2833319ea29b398;p=thirdparty%2Fplymouth.git Create window at layer above boot splash and reuse when changing boot splashes This requires keyboard handling to be changed, so that each plugin can hook in their own keyboard hooks when switching between them, and also handling escape completely above the boot splash plugin level. --- diff --git a/src/main.c b/src/main.c index f6c02852..45912111 100644 --- a/src/main.c +++ b/src/main.c @@ -46,11 +46,15 @@ typedef struct { ply_event_loop_t *loop; ply_boot_server_t *boot_server; + ply_window_t *window; ply_boot_splash_t *boot_splash; ply_terminal_session_t *session; int original_root_dir_fd; } state_t; +static ply_boot_splash_t *start_boot_splash (state_t *state, + const char *module_path); + static void on_session_start (state_t *state) { @@ -142,6 +146,44 @@ start_boot_server (state_t *state) return server; } +static void +on_escape_pressed (state_t *state) +{ + ply_boot_splash_hide (state->boot_splash); + ply_boot_splash_free (state->boot_splash); + + state->boot_splash = start_boot_splash (state, PLYMOUTH_PLUGIN_PATH "text.so"); +} + +static ply_window_t * +create_window (state_t *state, + const char *tty) +{ + ply_window_t *window; + + ply_trace ("creating window for %s", tty); + window = ply_window_new (tty); + + ply_trace ("attaching window to event loop"); + ply_window_attach_to_event_loop (window, state->loop); + + ply_trace ("opening window"); + if (!ply_window_open (window)) + { + ply_save_errno (); + ply_trace ("could not open window: %m"); + ply_window_free (window); + ply_restore_errno (); + return NULL; + } + + ply_trace ("listening for escape key"); + ply_window_set_escape_handler (window, (ply_window_escape_handler_t) + on_escape_pressed, state); + + return window; +} + static ply_boot_splash_t * start_boot_splash (state_t *state, const char *module_path) @@ -150,7 +192,7 @@ start_boot_splash (state_t *state, ply_trace ("Loading boot splash plugin '%s'", module_path); - splash = ply_boot_splash_new (module_path, NULL, NULL); + splash = ply_boot_splash_new (module_path, state->window); ply_trace ("attaching plugin to event loop"); ply_boot_splash_attach_to_event_loop (splash, state->loop); @@ -429,6 +471,8 @@ main (int argc, return EX_UNAVAILABLE; } + state.window = create_window (&state, "/dev/tty1"); + state.boot_splash = start_boot_splash (&state, PLYMOUTH_PLUGIN_PATH "fedora-fade-in.so"); @@ -451,6 +495,9 @@ main (int argc, ply_boot_splash_free (state.boot_splash); state.boot_splash = NULL; + ply_window_free (state.window); + state.window = NULL; + ply_boot_server_free (state.boot_server); state.boot_server = NULL; diff --git a/src/ply-boot-splash.c b/src/ply-boot-splash.c index 51e78880..59091d79 100644 --- a/src/ply-boot-splash.c +++ b/src/ply-boot-splash.c @@ -38,8 +38,6 @@ #include "ply-logger.h" #include "ply-utils.h" -#define KEY_ESCAPE '\033' - struct _ply_boot_splash { ply_event_loop_t *loop; @@ -48,9 +46,6 @@ struct _ply_boot_splash ply_boot_splash_plugin_t *plugin; ply_window_t *window; - ply_boot_splash_escape_handler_t escape_handler; - void *escape_handler_user_data; - char *module_name; char *status; @@ -61,9 +56,8 @@ typedef const ply_boot_splash_plugin_interface_t * (* get_plugin_interface_function_t) (void); ply_boot_splash_t * -ply_boot_splash_new (const char *module_name, - ply_boot_splash_escape_handler_t escape_handler, - void *user_data) +ply_boot_splash_new (const char *module_name, + ply_window_t *window) { ply_boot_splash_t *splash; @@ -75,8 +69,7 @@ ply_boot_splash_new (const char *module_name, splash->module_handle = NULL; splash->is_shown = false; - splash->escape_handler = escape_handler; - splash->escape_handler_user_data = user_data; + splash->window = window; return splash; } @@ -154,59 +147,14 @@ ply_boot_splash_unload_plugin (ply_boot_splash_t *splash) splash->module_handle = NULL; } -static bool -ply_boot_splash_process_keyboard_input (ply_boot_splash_t *splash, - const char *keyboard_input) -{ - wchar_t key; - - if (mbrtowc (&key, keyboard_input, 1, NULL) > 0) - { - if (key == KEY_ESCAPE) - { - if (splash->escape_handler != NULL) - splash->escape_handler (splash->escape_handler_user_data); - - return true; - } - } - - return false; -} - static void on_keyboard_input (ply_boot_splash_t *splash, const char *keyboard_input) { - - if (ply_boot_splash_process_keyboard_input (splash, keyboard_input)) - return; - if (splash->plugin_interface->on_keyboard_input != NULL) splash->plugin_interface->on_keyboard_input (splash->plugin, keyboard_input); } -static bool -ply_boot_splash_create_window (ply_boot_splash_t *splash) -{ - splash->window = ply_window_new ("/dev/tty1", - (ply_window_keyboard_input_handler_t) - on_keyboard_input, splash); - - ply_window_attach_to_event_loop (splash->window, splash->loop); - - if (!ply_window_open (splash->window)) - { - ply_save_errno (); - ply_window_free (splash->window); - splash->window = NULL; - ply_restore_errno (); - return false; - } - - return true; -} - bool ply_boot_splash_show (ply_boot_splash_t *splash) { @@ -231,11 +179,13 @@ ply_boot_splash_show (ply_boot_splash_t *splash) splash->plugin_interface->attach_to_event_loop (splash->plugin, splash->loop); - if (!ply_boot_splash_create_window (splash)) - return false; - assert (splash->window != NULL); + ply_window_set_keyboard_input_handler (splash->window, + (ply_window_keyboard_input_handler_t) + on_keyboard_input, splash); + + ply_trace ("showing splash screen\n"); if (!splash->plugin_interface->show_splash_screen (splash->plugin, splash->window)) { @@ -277,6 +227,13 @@ ply_boot_splash_ask_for_password (ply_boot_splash_t *splash) return splash->plugin_interface->ask_for_password (splash->plugin); } +static void +ply_boot_splash_detach_from_event_loop (ply_boot_splash_t *splash) +{ + assert (splash != NULL); + splash->loop = NULL; +} + void ply_boot_splash_hide (ply_boot_splash_t *splash) { @@ -288,15 +245,17 @@ ply_boot_splash_hide (ply_boot_splash_t *splash) splash->plugin_interface->hide_splash_screen (splash->plugin, splash->window); + ply_window_set_keyboard_input_handler (splash->window, NULL, NULL); + ply_boot_splash_unload_plugin (splash); splash->is_shown = false; -} -static void -ply_boot_splash_detach_from_event_loop (ply_boot_splash_t *splash) -{ - assert (splash != NULL); - splash->loop = NULL; + if (splash->loop != NULL) + { + ply_event_loop_stop_watching_for_exit (splash->loop, (ply_event_loop_exit_handler_t) + ply_boot_splash_detach_from_event_loop, + splash); + } } void @@ -332,12 +291,19 @@ on_timeout (ply_boot_splash_t *splash) splash); } +static void +on_quit (ply_event_loop_t *loop) +{ + ply_event_loop_exit (loop, 0); +} + int main (int argc, char **argv) { ply_event_loop_t *loop; ply_boot_splash_t *splash; + ply_window_t *window; int exit_code; const char *module_name; @@ -350,7 +316,18 @@ main (int argc, else module_name = "../splash-plugins/fedora-fade-in/.libs/fedora-fade-in.so"; - splash = ply_boot_splash_new (module_name, NULL, NULL); + window = ply_window_new (ttyname (0)); + + if (!ply_window_open (window)) + { + perror ("could not open terminal"); + return errno; + } + + ply_window_attach_to_event_loop (window, loop); + ply_window_set_escape_handler (window, (ply_window_escape_handler_t)on_quit, loop); + + splash = ply_boot_splash_new (module_name, window); ply_boot_splash_attach_to_event_loop (splash, loop); if (!ply_boot_splash_show (splash)) diff --git a/src/ply-boot-splash.h b/src/ply-boot-splash.h index c89636d5..6689beb6 100644 --- a/src/ply-boot-splash.h +++ b/src/ply-boot-splash.h @@ -27,16 +27,13 @@ #include #include "ply-event-loop.h" +#include "ply-window.h" typedef struct _ply_boot_splash ply_boot_splash_t; -typedef void (* ply_boot_splash_escape_handler_t) (void *user_data); - - #ifndef PLY_HIDE_FUNCTION_DECLARATIONS ply_boot_splash_t *ply_boot_splash_new (const char *module_name, - ply_boot_splash_escape_handler_t escape_handler, - void *user_data); + ply_window_t *window); void ply_boot_splash_free (ply_boot_splash_t *splash); bool ply_boot_splash_show (ply_boot_splash_t *splash); void ply_boot_splash_update_status (ply_boot_splash_t *splash, diff --git a/src/ply-window.c b/src/ply-window.c index 69fa94f8..79517fd7 100644 --- a/src/ply-window.c +++ b/src/ply-window.c @@ -43,6 +43,8 @@ #include "ply-logger.h" #include "ply-utils.h" +#define KEY_ESCAPE '\033' + struct _ply_window { ply_event_loop_t *loop; @@ -56,13 +58,15 @@ struct _ply_window ply_window_keyboard_input_handler_t keyboard_input_handler; void *keyboard_input_handler_user_data; + + ply_window_escape_handler_t escape_handler; + void *escape_handler_user_data; }; +static void ply_window_detach_from_event_loop (ply_window_t *window); ply_window_t * -ply_window_new (const char *tty_name, - ply_window_keyboard_input_handler_t input_handler, - void *user_data) +ply_window_new (const char *tty_name) { ply_window_t *window; @@ -73,12 +77,34 @@ ply_window_new (const char *tty_name, window->loop = NULL; window->tty_name = strdup (tty_name); window->tty_fd = -1; - window->keyboard_input_handler = input_handler; - window->keyboard_input_handler_user_data = user_data; return window; } +static void +process_keyboard_input (ply_window_t *window, + const char *keyboard_input) +{ + wchar_t key; + + if (mbrtowc (&key, keyboard_input, 1, NULL) > 0) + { + if (key == KEY_ESCAPE) + { + ply_trace ("escape key!"); + if (window->escape_handler != NULL) + window->escape_handler (window->escape_handler_user_data); + ply_trace ("end escape key handler"); + + return; + } + } + + if (window->keyboard_input_handler != NULL) + window->keyboard_input_handler (window->keyboard_input_handler_user_data, + keyboard_input); +} + static void check_buffer_for_key_events (ply_window_t *window) { @@ -92,23 +118,24 @@ check_buffer_for_key_events (ply_window_t *window) while (i < size) { ssize_t character_size; - char *key; + char *keyboard_input; character_size = (ssize_t) mbrlen (bytes + i, size - i, NULL); if (character_size < 0) break; - key = strndup (bytes + i, character_size); - if (window->keyboard_input_handler != NULL) - window->keyboard_input_handler (window->keyboard_input_handler_user_data, - key); - free (key); + keyboard_input = strndup (bytes + i, character_size); + + process_keyboard_input (window, keyboard_input); + + free (keyboard_input); i += character_size; } - ply_buffer_remove_bytes (window->buffer, i); + if (i > 0) + ply_buffer_remove_bytes (window->buffer, i); } static void @@ -220,6 +247,28 @@ ply_window_free (ply_window_t *window) free (window); } +void +ply_window_set_keyboard_input_handler (ply_window_t *window, + ply_window_keyboard_input_handler_t input_handler, + void *user_data) +{ + assert (window != NULL); + + window->keyboard_input_handler = input_handler; + window->keyboard_input_handler_user_data = user_data; +} + +void +ply_window_set_escape_handler (ply_window_t *window, + ply_window_escape_handler_t escape_handler, + void *user_data) +{ + assert (window != NULL); + + window->escape_handler = escape_handler; + window->escape_handler_user_data = user_data; +} + static void ply_window_detach_from_event_loop (ply_window_t *window) { @@ -289,10 +338,11 @@ main (int argc, else tty_name = "/dev/tty1"; - window = ply_window_new (tty_name, - (ply_window_keyboard_input_handler_t) - on_keypress, window); + window = ply_window_new (tty_name); ply_window_attach_to_event_loop (window, loop); + ply_window_set_keyboard_input_handler (window, + (ply_window_keyboard_input_handler_t) + on_keypress, window); if (!ply_window_open (window)) { diff --git a/src/ply-window.h b/src/ply-window.h index 8c9db255..0996b904 100644 --- a/src/ply-window.h +++ b/src/ply-window.h @@ -33,6 +33,8 @@ typedef struct _ply_window ply_window_t; typedef void (* ply_window_keyboard_input_handler_t) (void *user_data, const char *keyboard_input); +typedef void (* ply_window_escape_handler_t) (void *user_data); + typedef enum { PLY_WINDOW_MODE_TEXT, @@ -40,11 +42,16 @@ typedef enum } ply_window_mode_t; #ifndef PLY_HIDE_FUNCTION_DECLARATIONS -ply_window_t *ply_window_new (const char *tty_name, - ply_window_keyboard_input_handler_t input_handler, - void *user_data); +ply_window_t *ply_window_new (const char *tty_name); void ply_window_free (ply_window_t *window); +void ply_window_set_keyboard_input_handler (ply_window_t *window, + ply_window_keyboard_input_handler_t input_handler, + void *user_data); +void ply_window_set_escape_handler (ply_window_t *window, + ply_window_escape_handler_t escape_handler, + void *user_data); + bool ply_window_open (ply_window_t *window); void ply_window_close (ply_window_t *window); bool ply_window_set_mode (ply_window_t *window,