From: Charlie Brej Date: Fri, 19 Dec 2008 14:16:33 +0000 (+0000) Subject: Rework of the input methods X-Git-Tag: 0.7.0~236 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b65d7dcf3e66772b78140fcf27178f9530f39ddb;p=thirdparty%2Fplymouth.git Rework of the input methods Previously the splash plugins would deal with password entry, which would mean that code was repeated and upon splash unload the password entry would be lost. Now the keyboard strokes are processed with outside the splash, and the plugins only deal with showing an appropriate user interface. As well as password entry, the system can ask questions with non hidden text entry and sensing of keystrokes. --- diff --git a/src/client/ply-boot-client.c b/src/client/ply-boot-client.c index cb9546bb..ddca4331 100644 --- a/src/client/ply-boot-client.c +++ b/src/client/ply-boot-client.c @@ -569,6 +569,48 @@ ply_boot_client_ask_daemon_for_cached_passwords (ply_boot_client_t handler, failed_handler, user_data); } +void +ply_boot_client_ask_daemon_question (ply_boot_client_t *client, + const char *prompt, + ply_boot_client_answer_handler_t handler, + ply_boot_client_response_handler_t failed_handler, + void *user_data) +{ + assert (client != NULL); + + ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_QUESTION, + prompt, (ply_boot_client_response_handler_t) + handler, failed_handler, user_data); +} + +void +ply_boot_client_ask_daemon_to_watch_for_keystroke (ply_boot_client_t *client, + const char *keys, + ply_boot_client_answer_handler_t handler, + ply_boot_client_response_handler_t failed_handler, + void *user_data) +{ + assert (client != NULL); + + ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_KEYSTROKE, + keys, (ply_boot_client_response_handler_t) + handler, failed_handler, user_data); +} + +void +ply_boot_client_ask_daemon_to_ignore_keystroke (ply_boot_client_t *client, + const char *keys, + ply_boot_client_answer_handler_t handler, + ply_boot_client_response_handler_t failed_handler, + void *user_data) +{ + assert (client != NULL); + + ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_KEYSTROKE_REMOVE, + keys, (ply_boot_client_response_handler_t) + handler, failed_handler, user_data); +} + void ply_boot_client_tell_daemon_to_show_splash (ply_boot_client_t *client, ply_boot_client_response_handler_t handler, diff --git a/src/client/ply-boot-client.h b/src/client/ply-boot-client.h index a4fc432e..cf16c86d 100644 --- a/src/client/ply-boot-client.h +++ b/src/client/ply-boot-client.h @@ -64,15 +64,29 @@ void ply_boot_client_tell_daemon_to_change_root (ply_boot_client_t ply_boot_client_response_handler_t failed_handler, void *user_data); void ply_boot_client_ask_daemon_for_password (ply_boot_client_t *client, - const char *prompt, + const char *prompt, ply_boot_client_answer_handler_t handler, ply_boot_client_response_handler_t failed_handler, void *user_data); - void ply_boot_client_ask_daemon_for_cached_passwords (ply_boot_client_t *client, ply_boot_client_multiple_answers_handler_t handler, ply_boot_client_response_handler_t failed_handler, void *user_data); +void ply_boot_client_ask_daemon_question (ply_boot_client_t *client, + const char *prompt, + ply_boot_client_answer_handler_t handler, + ply_boot_client_response_handler_t failed_handler, + void *user_data); +void ply_boot_client_ask_daemon_to_watch_for_keystroke (ply_boot_client_t *client, + const char *keys, + ply_boot_client_answer_handler_t handler, + ply_boot_client_response_handler_t failed_handler, + void *user_data); +void ply_boot_client_ask_daemon_to_ignore_keystroke (ply_boot_client_t *client, + const char *keys, + ply_boot_client_answer_handler_t handler, + ply_boot_client_response_handler_t failed_handler, + void *user_data); void ply_boot_client_tell_daemon_system_is_initialized (ply_boot_client_t *client, ply_boot_client_response_handler_t handler, ply_boot_client_response_handler_t failed_handler, diff --git a/src/client/plymouth.c b/src/client/plymouth.c index 6ad90eaf..e8e23a25 100644 --- a/src/client/plymouth.c +++ b/src/client/plymouth.c @@ -50,7 +50,21 @@ typedef struct char *command; char *prompt; int number_of_tries_left; -} answer_state_t; +} password_answer_state_t; + +typedef struct +{ + state_t *state; + char *command; + char *prompt; +} question_answer_state_t; + +typedef struct +{ + state_t *state; + char *command; + char *keys; +} key_answer_state_t; static char ** split_string (const char *command, @@ -96,7 +110,7 @@ split_string (const char *command, } static bool -answer_via_command (answer_state_t *answer_state, +answer_via_command (char *command, const char *answer, int *exit_status) { @@ -123,7 +137,7 @@ answer_via_command (answer_state_t *answer_state, if (pid == 0) { char **args; - args = split_string (answer_state->command, ' '); + args = split_string (command, ' '); if (answer != NULL) { close (command_input_sender_fd); @@ -153,14 +167,14 @@ out: } static void -on_answer_failure (answer_state_t *answer_state) +on_password_answer_failure (password_answer_state_t *answer_state, ply_boot_client_t *client) { ply_event_loop_exit (answer_state->state->loop, 1); } static void -on_answer (answer_state_t *answer_state, - const char *answer) +on_password_answer (password_answer_state_t *answer_state, + const char *answer) { int exit_status; @@ -170,7 +184,7 @@ on_answer (answer_state_t *answer_state, bool command_started = false; exit_status = 127; - command_started = answer_via_command (answer_state, answer, + command_started = answer_via_command (answer_state->command, answer, &exit_status); if (command_started && (!WIFEXITED (exit_status) || @@ -183,9 +197,9 @@ on_answer (answer_state_t *answer_state, ply_boot_client_ask_daemon_for_password (answer_state->state->client, answer_state->prompt, (ply_boot_client_answer_handler_t) - on_answer, + on_password_answer, (ply_boot_client_response_handler_t) - on_answer_failure, answer_state); + on_password_answer_failure, answer_state); return; } } @@ -200,8 +214,47 @@ on_answer (answer_state_t *answer_state, } static void -on_multiple_answers (answer_state_t *answer_state, - const char * const *answers) +on_question_answer (question_answer_state_t *answer_state, + const char *answer, + ply_boot_client_t *client) +{ + if (answer_state->command != NULL) + { + answer_via_command (answer_state->command, answer, NULL); + } + else + { + if (answer) + write (STDOUT_FILENO, answer, strlen (answer)); + } + + if (answer) + ply_event_loop_exit (answer_state->state->loop, 0); + ply_event_loop_exit (answer_state->state->loop, 1); +} + +static void +on_key_answer (key_answer_state_t *answer_state, + const char *answer, + ply_boot_client_t *client) +{ + if (answer_state->command != NULL) + { + answer_via_command (answer_state->command, answer, NULL); + } + else + { + if (answer) + write (STDOUT_FILENO, answer, strlen (answer)); + } + + if (answer) ply_event_loop_exit (answer_state->state->loop, 0); + ply_event_loop_exit (answer_state->state->loop, 1); +} + +static void +on_multiple_answers (password_answer_state_t *answer_state, + const char * const *answers) { bool need_to_ask_user; int i; @@ -216,7 +269,7 @@ on_multiple_answers (answer_state_t *answer_state, { bool command_started; exit_status = 127; - command_started = answer_via_command (answer_state, answers[i], + command_started = answer_via_command (answer_state->command, answers[i], &exit_status); if (command_started && WIFEXITED (exit_status) && WEXITSTATUS (exit_status) == 0) @@ -231,9 +284,9 @@ on_multiple_answers (answer_state_t *answer_state, ply_boot_client_ask_daemon_for_password (answer_state->state->client, answer_state->prompt, (ply_boot_client_answer_handler_t) - on_answer, + on_password_answer, (ply_boot_client_response_handler_t) - on_answer_failure, answer_state); + on_password_answer_failure, answer_state); return; } @@ -279,7 +332,7 @@ on_password_request (state_t *state, char *prompt; char *program; int number_of_tries; - answer_state_t *answer_state; + password_answer_state_t *password_answer_state; prompt = NULL; program = NULL; @@ -294,32 +347,92 @@ on_password_request (state_t *state, if (number_of_tries <= 0) number_of_tries = 3; - answer_state = calloc (1, sizeof (answer_state_t)); - answer_state->state = state; - answer_state->command = program; - answer_state->prompt = prompt; - answer_state->number_of_tries_left = number_of_tries; + password_answer_state = calloc (1, sizeof (password_answer_state_t)); + password_answer_state->state = state; + password_answer_state->command = program; + password_answer_state->prompt = prompt; + password_answer_state->number_of_tries_left = number_of_tries; - if (answer_state->command != NULL) + if (password_answer_state->command != NULL) { ply_boot_client_ask_daemon_for_cached_passwords (state->client, (ply_boot_client_multiple_answers_handler_t) on_multiple_answers, (ply_boot_client_response_handler_t) - on_answer_failure, answer_state); - + on_password_answer_failure, password_answer_state); } else { ply_boot_client_ask_daemon_for_password (state->client, - answer_state->prompt, + password_answer_state->prompt, (ply_boot_client_answer_handler_t) - on_answer, + on_password_answer, (ply_boot_client_response_handler_t) - on_answer_failure, answer_state); + on_password_answer_failure, password_answer_state); } } +static void +on_question_request (state_t *state, + const char *command) +{ + char *prompt; + char *program; + int number_of_tries; + question_answer_state_t *question_answer_state; + + prompt = NULL; + program = NULL; + number_of_tries = 0; + ply_command_parser_get_command_options (state->command_parser, + command, + "command", &program, + "prompt", &prompt, + NULL); + + question_answer_state = calloc (1, sizeof (question_answer_state_t)); + question_answer_state->state = state; + question_answer_state->command = program; + question_answer_state->prompt = prompt; + + ply_boot_client_ask_daemon_question (state->client, + question_answer_state->prompt, + (ply_boot_client_answer_handler_t) + on_question_answer, + (ply_boot_client_response_handler_t) + on_failure, question_answer_state); +} + +static void +on_keystroke_request (state_t *state, + const char *command) +{ + char *keys; + char *program; + bool remove; + + keys = NULL; + program = NULL; + remove = false; + + ply_command_parser_get_command_options (state->command_parser, + command, + "command", &program, + "keys", &keys, + NULL); + key_answer_state_t *key_answer_state; + key_answer_state = calloc (1, sizeof (key_answer_state_t)); + key_answer_state->state = state; + key_answer_state->keys = keys; + key_answer_state->command = program; + ply_boot_client_ask_daemon_to_watch_for_keystroke (state->client, + keys, + (ply_boot_client_answer_handler_t) + on_key_answer, + (ply_boot_client_response_handler_t) + on_failure, key_answer_state); +} + static void on_report_error_request (state_t *state, const char *command) @@ -358,7 +471,7 @@ main (int argc, { state_t state = { 0 }; bool should_help, should_quit, should_ping, should_sysinit, should_ask_for_password, should_show_splash, should_hide_splash, should_wait, should_be_verbose, report_error; - char *status, *chroot_dir; + char *status, *chroot_dir, *ignore_keystroke; int exit_code; exit_code = 0; @@ -379,6 +492,7 @@ main (int argc, "show-splash", "Show splash screen", PLY_COMMAND_OPTION_TYPE_FLAG, "hide-splash", "Hide splash screen", PLY_COMMAND_OPTION_TYPE_FLAG, "ask-for-password", "Ask user for password", PLY_COMMAND_OPTION_TYPE_FLAG, + "ignore-keystroke", "Remove sensitivity to a keystroke", PLY_COMMAND_OPTION_TYPE_STRING, "update", "Tell boot daemon an update about boot progress", PLY_COMMAND_OPTION_TYPE_STRING, "details", "Tell boot daemon there were errors during boot", PLY_COMMAND_OPTION_TYPE_FLAG, "wait", "Wait for boot daemon to quit", PLY_COMMAND_OPTION_TYPE_FLAG, @@ -396,6 +510,27 @@ main (int argc, PLY_COMMAND_OPTION_TYPE_INTEGER, NULL); + ply_command_parser_add_command (state.command_parser, + "ask-question", "Ask user a question", + (ply_command_handler_t) + on_question_request, &state, + "command", "Command to send the answer to via standard input", + PLY_COMMAND_OPTION_TYPE_STRING, + "prompt", "Message to display when asking the question", + PLY_COMMAND_OPTION_TYPE_STRING, + NULL); + + + ply_command_parser_add_command (state.command_parser, + "watch-keystroke", "Become sensitive to a keystroke", + (ply_command_handler_t) + on_keystroke_request, &state, + "command", "Command to send keystroke to via standard input", + PLY_COMMAND_OPTION_TYPE_STRING, + "keys", "Keys to become sensitive to", + PLY_COMMAND_OPTION_TYPE_STRING, + NULL); + ply_command_parser_add_command (state.command_parser, "report-error", "Tell boot daemon there were errors during boot", (ply_command_handler_t) @@ -431,6 +566,7 @@ main (int argc, "show-splash", &should_show_splash, "hide-splash", &should_hide_splash, "ask-for-password", &should_ask_for_password, + "ignore-keystroke", &ignore_keystroke, "update", &status, "wait", &should_wait, "details", &report_error, @@ -509,16 +645,25 @@ main (int argc, on_failure, &state); else if (should_ask_for_password) { - answer_state_t answer_state = { 0 }; + password_answer_state_t answer_state = { 0 }; answer_state.state = &state; answer_state.number_of_tries_left = 1; ply_boot_client_ask_daemon_for_password (state.client, NULL, (ply_boot_client_answer_handler_t) - on_answer, + on_password_answer, (ply_boot_client_response_handler_t) - on_answer_failure, &answer_state); + on_password_answer_failure, &answer_state); + } + else if (ignore_keystroke) + { + ply_boot_client_ask_daemon_to_ignore_keystroke (state.client, + ignore_keystroke, + (ply_boot_client_answer_handler_t) + on_success, + (ply_boot_client_response_handler_t) + on_failure, &state); } else if (should_sysinit) ply_boot_client_tell_daemon_system_is_initialized (state.client, diff --git a/src/libplybootsplash/ply-boot-splash-plugin.h b/src/libplybootsplash/ply-boot-splash-plugin.h index cf16f688..9361955b 100644 --- a/src/libplybootsplash/ply-boot-splash-plugin.h +++ b/src/libplybootsplash/ply-boot-splash-plugin.h @@ -33,8 +33,6 @@ typedef struct _ply_boot_splash_plugin ply_boot_splash_plugin_t; -typedef void (* ply_boot_splash_password_answer_handler_t) (void *answer_data, const char *password); - typedef struct { ply_boot_splash_plugin_t * (* create_plugin) (void); @@ -59,10 +57,13 @@ typedef struct void (* on_root_mounted) (ply_boot_splash_plugin_t *plugin); void (* hide_splash_screen) (ply_boot_splash_plugin_t *plugin, ply_event_loop_t *loop); - - void (* ask_for_password) (ply_boot_splash_plugin_t *plugin, + void (* display_normal) (ply_boot_splash_plugin_t *plugin); + void (* display_password) (ply_boot_splash_plugin_t *plugin, + const char *prompt, + int bullets); + void (* display_question) (ply_boot_splash_plugin_t *plugin, const char *prompt, - ply_trigger_t *answer); + const char *entry_text); void (* become_idle) (ply_boot_splash_plugin_t *plugin, ply_trigger_t *idle_trigger); } ply_boot_splash_plugin_interface_t; diff --git a/src/libplybootsplash/ply-entry.c b/src/libplybootsplash/ply-entry.c index 0a424161..623492d9 100644 --- a/src/libplybootsplash/ply-entry.c +++ b/src/libplybootsplash/ply-entry.c @@ -43,6 +43,7 @@ #include "ply-entry.h" #include "ply-event-loop.h" #include "ply-array.h" +#include "ply-label.h" #include "ply-logger.h" #include "ply-frame-buffer.h" #include "ply-image.h" @@ -64,11 +65,14 @@ struct _ply_entry ply_frame_buffer_area_t area; ply_image_t *text_field_image; ply_image_t *bullet_image; + ply_label_t *label; + char* text; int number_of_bullets; int max_number_of_visible_bullets; uint32_t is_hidden : 1; + uint32_t is_password : 1; }; ply_entry_t * @@ -90,8 +94,13 @@ ply_entry_new (const char *image_dir) asprintf (&image_path, "%s/bullet.png", image_dir); entry->bullet_image = ply_image_new (image_path); free (image_path); + entry->label = ply_label_new (); + entry->number_of_bullets = 0; + entry->text = strdup(""); + entry->is_hidden = true; + entry->is_password = true; return entry; } @@ -103,6 +112,8 @@ ply_entry_free (ply_entry_t *entry) return; ply_image_free (entry->text_field_image); ply_image_free (entry->bullet_image); + ply_label_free (entry->label); + free (entry); } @@ -162,59 +173,95 @@ ply_entry_draw (ply_entry_t *entry) ply_frame_buffer_fill_with_argb32_data (entry->frame_buffer, &entry->area, 0, 0, text_field_data); - - bullet_data = ply_image_get_data (entry->bullet_image); - bullet_area.width = ply_image_get_width (entry->bullet_image); - bullet_area.height = ply_image_get_height (entry->bullet_image); - - if (entry->number_of_bullets < entry->max_number_of_visible_bullets) - number_of_visible_bullets = entry->number_of_bullets; + + if (entry->is_password) + { + bullet_data = ply_image_get_data (entry->bullet_image); + bullet_area.width = ply_image_get_width (entry->bullet_image); + bullet_area.height = ply_image_get_height (entry->bullet_image); + + if (entry->number_of_bullets < entry->max_number_of_visible_bullets) + number_of_visible_bullets = entry->number_of_bullets; + else + { + number_of_visible_bullets = entry->max_number_of_visible_bullets; + + /* We've got more bullets than we can show in the available space, so + * draw a little half bullet to indicate some bullets are offscreen + */ + bullet_area.x = entry->area.x; + bullet_area.y = entry->area.y + entry->area.height / 2.0 - bullet_area.height / 2.0; + + ply_frame_buffer_fill_with_argb32_data (entry->frame_buffer, + &bullet_area, bullet_area.width / 2.0, 0, + bullet_data); + } + + for (i = 0; i < number_of_visible_bullets; i++) + { + bullet_area.x = entry->area.x + i * bullet_area.width + bullet_area.width / 2.0; + bullet_area.y = entry->area.y + entry->area.height / 2.0 - bullet_area.height / 2.0; + + ply_frame_buffer_fill_with_argb32_data (entry->frame_buffer, + &bullet_area, 0, 0, + bullet_data); + } + } else { - number_of_visible_bullets = entry->max_number_of_visible_bullets; - - /* We've got more bullets than we can show in the available space, so - * draw a little half bullet to indicate some bullets are offscreen - */ - bullet_area.x = entry->area.x; - bullet_area.y = entry->area.y + entry->area.height / 2.0 - bullet_area.height / 2.0; - - ply_frame_buffer_fill_with_argb32_data (entry->frame_buffer, - &bullet_area, bullet_area.width / 2.0, 0, - bullet_data); + ply_label_set_text (entry->label, entry->text); + ply_label_show (entry->label, entry->window, entry->area.x, entry->area.y); + } + ply_frame_buffer_unpause_updates (entry->frame_buffer); +} - for (i = 0; i < number_of_visible_bullets; i++) +void +ply_entry_set_bullet_count (ply_entry_t *entry, int count) +{ + count = MAX(0, count); + if (!entry->is_password || entry->number_of_bullets != count) { - bullet_area.x = entry->area.x + i * bullet_area.width + bullet_area.width / 2.0; - bullet_area.y = entry->area.y + entry->area.height / 2.0 - bullet_area.height / 2.0; - - ply_frame_buffer_fill_with_argb32_data (entry->frame_buffer, - &bullet_area, 0, 0, - bullet_data); + entry->is_password = true; + entry->number_of_bullets = count; + ply_entry_draw (entry); } - ply_frame_buffer_unpause_updates (entry->frame_buffer); +} + +int +ply_entry_get_bullet_count (ply_entry_t *entry) +{ + return entry->number_of_bullets; } void ply_entry_add_bullet (ply_entry_t *entry) { - entry->number_of_bullets++; - ply_entry_draw (entry); + ply_entry_set_bullet_count (entry, ply_entry_get_bullet_count (entry)+1); } void ply_entry_remove_bullet (ply_entry_t *entry) { - entry->number_of_bullets--; - ply_entry_draw (entry); + ply_entry_set_bullet_count (entry, ply_entry_get_bullet_count (entry)-1); } void ply_entry_remove_all_bullets (ply_entry_t *entry) { - entry->number_of_bullets = 0; - ply_entry_draw (entry); + ply_entry_set_bullet_count (entry, 0); +} + +void +ply_entry_set_text (ply_entry_t *entry, const char* text) +{ + if (entry->is_password || strcmp(entry->text, text) != 0) + { + entry->is_password = false; + free(entry->text); + entry->text = strdup(text); + ply_entry_draw (entry); + } } void diff --git a/src/libplybootsplash/ply-entry.h b/src/libplybootsplash/ply-entry.h index ac34a4c5..76bf2adb 100644 --- a/src/libplybootsplash/ply-entry.h +++ b/src/libplybootsplash/ply-entry.h @@ -49,9 +49,13 @@ bool ply_entry_is_hidden (ply_entry_t *entry); long ply_entry_get_width (ply_entry_t *entry); long ply_entry_get_height (ply_entry_t *entry); +void ply_entry_set_bullet_count (ply_entry_t *entry, int count); +int ply_entry_get_bullet_count (ply_entry_t *entry); void ply_entry_add_bullet (ply_entry_t *entry); void ply_entry_remove_bullet (ply_entry_t *entry); void ply_entry_remove_all_bullets (ply_entry_t *entry); +void ply_entry_set_text (ply_entry_t *entry, const char* text); + #endif #endif /* PLY_ENTRY_H */ diff --git a/src/libplybootsplash/ply-window.c b/src/libplybootsplash/ply-window.c index d3c9e790..fabe0911 100644 --- a/src/libplybootsplash/ply-window.c +++ b/src/libplybootsplash/ply-window.c @@ -42,6 +42,7 @@ #include "ply-buffer.h" #include "ply-event-loop.h" #include "ply-frame-buffer.h" +#include "ply-list.h" #include "ply-logger.h" #include "ply-utils.h" @@ -95,6 +96,14 @@ #define TEXT_PALETTE_SIZE 48 #endif +typedef void (* ply_window_handler_t) (void *); + +typedef struct +{ + ply_window_handler_t *function; + void *user_data; +} ply_window_closure_t; + struct _ply_window { ply_event_loop_t *loop; @@ -125,17 +134,10 @@ struct _ply_window uint32_t supports_text_color : 1; uint32_t is_open : 1; - ply_window_keyboard_input_handler_t keyboard_input_handler; - void *keyboard_input_handler_user_data; - - ply_window_backspace_handler_t backspace_handler; - void *backspace_handler_user_data; - - ply_window_escape_handler_t escape_handler; - void *escape_handler_user_data; - - ply_window_enter_handler_t enter_handler; - void *enter_handler_user_data; + ply_list_t *keyboard_input_handler_list; + ply_list_t *backspace_handler_list; + ply_list_t *escape_handler_list; + ply_list_t *enter_handler_list; ply_window_draw_handler_t draw_handler; void *draw_handler_user_data; @@ -153,6 +155,11 @@ ply_window_new (const char *tty_name) window->keyboard_input_buffer = ply_buffer_new (); window->line_buffer = ply_buffer_new (); window->frame_buffer = ply_frame_buffer_new (NULL); + window->keyboard_input_handler_list = ply_list_new(); + window->backspace_handler_list = ply_list_new(); + window->escape_handler_list = ply_list_new(); + window->enter_handler_list = ply_list_new(); + window->loop = NULL; if (tty_name != NULL) { @@ -224,11 +231,12 @@ process_backspace (ply_window_t *window) ssize_t previous_character_size; const char *bytes; size_t size; + ply_list_node_t *node; bytes = ply_buffer_get_bytes (window->line_buffer); size = ply_buffer_get_size (window->line_buffer); - bytes_to_remove = MB_CUR_MAX; + bytes_to_remove = MIN(size, MB_CUR_MAX); while ((previous_character_size = mbrlen (bytes + size - bytes_to_remove, bytes_to_remove, NULL)) < bytes_to_remove && previous_character_size > 0) bytes_to_remove -= previous_character_size; @@ -236,9 +244,15 @@ process_backspace (ply_window_t *window) if (bytes_to_remove <= size) { ply_buffer_remove_bytes_at_end (window->line_buffer, bytes_to_remove); + } - if (window->backspace_handler != NULL) - window->backspace_handler (window->backspace_handler_user_data); + for (node = ply_list_get_first_node(window->backspace_handler_list); + node; node = ply_list_get_next_node(window->backspace_handler_list, node)) + { + ply_window_closure_t *closure = ply_list_node_get_data (node); + ply_window_backspace_handler_t backspace_handler = + (ply_window_backspace_handler_t) closure->function; + backspace_handler (closure->user_data); } } @@ -257,8 +271,9 @@ process_keyboard_input (ply_window_t *window, size_t character_size) { wchar_t key; + ply_list_node_t *node; - if (mbrtowc (&key, keyboard_input, 1, NULL) > 0) + if ((ssize_t) mbrtowc (&key, keyboard_input, character_size, NULL) > 0) { switch (key) { @@ -302,8 +317,14 @@ process_keyboard_input (ply_window_t *window, case KEY_ESCAPE: ply_trace ("escape key!"); - if (window->escape_handler != NULL) - window->escape_handler (window->escape_handler_user_data); + for (node = ply_list_get_first_node(window->escape_handler_list); + node; node = ply_list_get_next_node(window->escape_handler_list, node)) + { + ply_window_closure_t *closure = ply_list_node_get_data (node); + ply_window_escape_handler_t escape_handler = (ply_window_escape_handler_t) closure->function; + escape_handler (closure->user_data); + } + ply_trace ("end escape key handler"); return; @@ -315,10 +336,13 @@ process_keyboard_input (ply_window_t *window, case KEY_RETURN: ply_trace ("return key!"); - if (window->enter_handler != NULL) - window->enter_handler (window->enter_handler_user_data, - ply_buffer_get_bytes (window->line_buffer)); - + for (node = ply_list_get_first_node(window->enter_handler_list); + node; node = ply_list_get_next_node(window->enter_handler_list, node)) + { + ply_window_closure_t *closure = ply_list_node_get_data (node); + ply_window_enter_handler_t enter_handler = (ply_window_enter_handler_t) closure->function; + enter_handler (closure->user_data, ply_buffer_get_bytes (window->line_buffer)); + } ply_buffer_clear (window->line_buffer); return; @@ -328,10 +352,16 @@ process_keyboard_input (ply_window_t *window, break; } } - - if (window->keyboard_input_handler != NULL) - window->keyboard_input_handler (window->keyboard_input_handler_user_data, - keyboard_input, character_size); + for (node = ply_list_get_first_node(window->keyboard_input_handler_list); + node; node = ply_list_get_next_node(window->keyboard_input_handler_list, node)) + { + ply_window_closure_t *closure = ply_list_node_get_data (node); + ply_window_keyboard_input_handler_t keyboard_input_handler = + (ply_window_keyboard_input_handler_t) closure->function; + + keyboard_input_handler (closure->user_data, + keyboard_input, character_size); + } } static void @@ -648,7 +678,8 @@ ply_window_set_text_cursor_position (ply_window_t *window, int row) { char *sequence; - + column = MAX(column, 0); + row = MAX(row, 0); sequence = NULL; asprintf (&sequence, MOVE_CURSOR_SEQUENCE, row, column); write (window->tty_fd, sequence, strlen (sequence)); @@ -836,48 +867,142 @@ ply_window_free (ply_window_t *window) free (window); } +static ply_window_closure_t * +ply_window_closure_new(void* function, void* user_data) +{ + ply_window_closure_t *closure = calloc (1, sizeof (ply_window_closure_t)); + closure->function = function; + closure->user_data = user_data; + return closure; +} + + +static void +ply_window_closure_free(ply_window_closure_t* closure) +{ + free(closure); +} + void -ply_window_set_keyboard_input_handler (ply_window_t *window, +ply_window_add_keyboard_input_handler (ply_window_t *window, ply_window_keyboard_input_handler_t input_handler, void *user_data) { assert (window != NULL); + ply_window_closure_t *closure = ply_window_closure_new(input_handler, user_data); + ply_list_append_data (window->keyboard_input_handler_list, closure); +} - window->keyboard_input_handler = input_handler; - window->keyboard_input_handler_user_data = user_data; + +void +ply_window_remove_keyboard_input_handler (ply_window_t *window, + ply_window_keyboard_input_handler_t input_handler) +{ + ply_list_node_t *node; + assert (window != NULL); + for (node = ply_list_get_first_node(window->keyboard_input_handler_list); + node; node = ply_list_get_next_node(window->keyboard_input_handler_list, node)) + { + ply_window_closure_t *closure = ply_list_node_get_data (node); + if ((ply_window_keyboard_input_handler_t) closure->function == input_handler) + { + ply_window_closure_free(closure); + ply_list_remove_node (window->keyboard_input_handler_list, node); + return; + } + } } void -ply_window_set_backspace_handler (ply_window_t *window, +ply_window_add_backspace_handler (ply_window_t *window, ply_window_backspace_handler_t backspace_handler, void *user_data) { assert (window != NULL); + ply_window_closure_t *closure = ply_window_closure_new(backspace_handler, user_data); + ply_list_append_data (window->backspace_handler_list, closure); +} + - window->backspace_handler = backspace_handler; - window->backspace_handler_user_data = user_data; +void +ply_window_remove_backspace_handler (ply_window_t *window, + ply_window_backspace_handler_t backspace_handler) +{ + ply_list_node_t *node; + assert (window != NULL); + for (node = ply_list_get_first_node(window->backspace_handler_list); + node; node = ply_list_get_next_node(window->backspace_handler_list, node)) + { + ply_window_closure_t *closure = ply_list_node_get_data (node); + if ((ply_window_backspace_handler_t) closure->function == backspace_handler) + { + ply_window_closure_free(closure); + ply_list_remove_node (window->backspace_handler_list, node); + return; + } + } } void -ply_window_set_escape_handler (ply_window_t *window, +ply_window_add_escape_handler (ply_window_t *window, ply_window_escape_handler_t escape_handler, void *user_data) { assert (window != NULL); + ply_window_closure_t *closure = ply_window_closure_new(escape_handler, user_data); + ply_list_append_data (window->escape_handler_list, closure); +} + - window->escape_handler = escape_handler; - window->escape_handler_user_data = user_data; +void +ply_window_remove_escape_handler (ply_window_t *window, + ply_window_escape_handler_t escape_handler) +{ + assert (window != NULL); + ply_list_node_t *node; + assert (window != NULL); + for (node = ply_list_get_first_node(window->escape_handler_list); + node; node = ply_list_get_next_node(window->escape_handler_list, node)) + { + ply_window_closure_t *closure = ply_list_node_get_data (node); + if ((ply_window_escape_handler_t) closure->function == escape_handler) + { + ply_window_closure_free(closure); + ply_list_remove_node (window->escape_handler_list, node); + return; + } + } } void -ply_window_set_enter_handler (ply_window_t *window, +ply_window_add_enter_handler (ply_window_t *window, ply_window_enter_handler_t enter_handler, void *user_data) { assert (window != NULL); + ply_window_closure_t *closure = ply_window_closure_new(enter_handler, user_data); + ply_list_append_data (window->enter_handler_list, closure); +} - window->enter_handler = enter_handler; - window->enter_handler_user_data = user_data; + +void +ply_window_remove_enter_handler (ply_window_t *window, + ply_window_enter_handler_t enter_handler) +{ + assert (window != NULL); + ply_list_node_t *node; + assert (window != NULL); + for (node = ply_list_get_first_node(window->enter_handler_list); + node; node = ply_list_get_next_node(window->enter_handler_list, node)) + { + ply_window_closure_t *closure = ply_list_node_get_data (node); + if ((ply_window_enter_handler_t) closure->function == enter_handler) + { + ply_window_closure_free(closure); + ply_list_remove_node (window->enter_handler_list, node); + return; + } + } } void @@ -965,7 +1090,7 @@ main (int argc, window = ply_window_new (tty_name); ply_window_attach_to_event_loop (window, loop); - ply_window_set_keyboard_input_handler (window, + ply_window_add_keyboard_input_handler (window, (ply_window_keyboard_input_handler_t) on_keypress, window); diff --git a/src/libplybootsplash/ply-window.h b/src/libplybootsplash/ply-window.h index a6b2caa5..9b8fee79 100644 --- a/src/libplybootsplash/ply-window.h +++ b/src/libplybootsplash/ply-window.h @@ -37,7 +37,6 @@ typedef void (* ply_window_keyboard_input_handler_t) (void *user_data, size_t character_size); typedef void (* ply_window_backspace_handler_t) (void *user_data); - typedef void (* ply_window_escape_handler_t) (void *user_data); typedef void (* ply_window_enter_handler_t) (void *user_data, const char *line); @@ -76,24 +75,36 @@ typedef enum ply_window_t *ply_window_new (const char *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_backspace_handler (ply_window_t *window, - ply_window_backspace_handler_t backspace_handler, - void *user_data); -void ply_window_set_escape_handler (ply_window_t *window, - ply_window_escape_handler_t escape_handler, - void *user_data); -void ply_window_set_enter_handler (ply_window_t *window, - ply_window_enter_handler_t enter_handler, - void *user_data); -void ply_window_set_draw_handler (ply_window_t *window, - ply_window_draw_handler_t draw_handler, - void *user_data); -void ply_window_set_erase_handler (ply_window_t *window, - ply_window_erase_handler_t erase_handler, - void *user_data); +void ply_window_add_keyboard_input_handler (ply_window_t *window, + ply_window_keyboard_input_handler_t input_handler, + void *user_data); +void ply_window_remove_keyboard_input_handler (ply_window_t *window, + ply_window_keyboard_input_handler_t input_handler); +void ply_window_add_backspace_handler (ply_window_t *window, + ply_window_backspace_handler_t backspace_handler, + void *user_data); +void ply_window_remove_backspace_handler (ply_window_t *window, + ply_window_backspace_handler_t backspace_handler); +void ply_window_add_escape_handler (ply_window_t *window, + ply_window_escape_handler_t escape_handler, + void *user_data); +void ply_window_remove_escape_handler (ply_window_t *window, + ply_window_escape_handler_t escape_handler); +void ply_window_add_enter_handler (ply_window_t *window, + ply_window_enter_handler_t enter_handler, + void *user_data); +void ply_window_remove_enter_handler (ply_window_t *window, + ply_window_enter_handler_t enter_handler); +void ply_window_add_draw_handler (ply_window_t *window, + ply_window_draw_handler_t draw_handler, + void *user_data); +void ply_window_remove_draw_handler (ply_window_t *window, + ply_window_draw_handler_t draw_handler); +void ply_window_add_erase_handler (ply_window_t *window, + ply_window_erase_handler_t erase_handler, + void *user_data); +void ply_window_remove_erase_handler (ply_window_t *window, + ply_window_erase_handler_t erase_handler); bool ply_window_open (ply_window_t *window); bool ply_window_is_open (ply_window_t *window); @@ -138,6 +149,12 @@ void ply_window_set_color_hex_value (ply_window_t *window, uint32_t hex_value); void ply_window_reset_colors (ply_window_t *window); +void ply_window_set_draw_handler (ply_window_t *window, + ply_window_draw_handler_t draw_handler, + void *user_data); +void ply_window_set_erase_handler (ply_window_t *window, + ply_window_erase_handler_t erase_handler, + void *user_data); void ply_window_attach_to_event_loop (ply_window_t *window, ply_event_loop_t *loop); ply_frame_buffer_t *ply_window_get_frame_buffer (ply_window_t *window); diff --git a/src/main.c b/src/main.c index 6afffc43..fbce3242 100644 --- a/src/main.c +++ b/src/main.c @@ -31,6 +31,7 @@ #include #include #include +#include #include @@ -48,6 +49,21 @@ #define PLY_MAX_COMMAND_LINE_SIZE 512 #endif +typedef struct +{ + const char *keys; + ply_trigger_t *trigger; +} ply_keystroke_watch_t; + +typedef struct +{ + enum {PLY_ENTRY_TRIGGER_TYPE_PASSWORD, + PLY_ENTRY_TRIGGER_TYPE_QUESTION} + type; + const char *prompt; + ply_trigger_t *trigger; +} ply_entry_trigger_t; + typedef struct { ply_event_loop_t *loop; @@ -57,6 +73,9 @@ typedef struct ply_terminal_session_t *session; ply_buffer_t *boot_buffer; ply_progress_t *progress; + ply_list_t *keystroke_triggers; + ply_list_t *entry_triggers; + ply_buffer_t *entry_buffer; long ptmx; char kernel_command_line[PLY_MAX_COMMAND_LINE_SIZE]; @@ -80,6 +99,7 @@ static ply_window_t *create_window (state_t *state, static bool attach_to_running_session (state_t *state); static void on_escape_pressed (state_t *state); static void dump_details_and_quit_splash (state_t *state); +static void update_display (state_t *state); static void on_session_output (state_t *state, @@ -148,18 +168,63 @@ on_ask_for_password (state_t *state, const char *prompt, ply_trigger_t *answer) { - if (state->boot_splash == NULL) + ply_entry_trigger_t *entry_trigger = + calloc (1, sizeof (ply_entry_trigger_t)); + entry_trigger->type = PLY_ENTRY_TRIGGER_TYPE_PASSWORD; + entry_trigger->prompt = prompt; + entry_trigger->trigger = answer; + ply_list_append_data (state->entry_triggers, entry_trigger); + update_display (state); +} + +static void +on_ask_question (state_t *state, + const char *prompt, + ply_trigger_t *answer) +{ + ply_entry_trigger_t *entry_trigger = + calloc (1, sizeof (ply_entry_trigger_t)); + entry_trigger->type = PLY_ENTRY_TRIGGER_TYPE_QUESTION; + entry_trigger->prompt = prompt; + entry_trigger->trigger = answer; + ply_list_append_data (state->entry_triggers, entry_trigger); + update_display (state); +} + +static void +on_watch_for_keystroke (state_t *state, + const char *keys, + ply_trigger_t *trigger) +{ + ply_keystroke_watch_t *keystroke_trigger = + calloc (1, sizeof (ply_keystroke_watch_t)); + keystroke_trigger->keys = keys; + keystroke_trigger->trigger = trigger; + ply_list_append_data (state->keystroke_triggers, keystroke_trigger); +} + + +static void +on_ignore_keystroke (state_t *state, + const char *keys) +{ + ply_list_node_t *node; + + for (node = ply_list_get_first_node (state->keystroke_triggers); node; + node = ply_list_get_next_node (state->keystroke_triggers, node)) { - show_detailed_splash (state); - if (state->boot_splash == NULL) - ply_trigger_pull (answer, ""); - return; + ply_keystroke_watch_t* keystroke_trigger = ply_list_node_get_data (node); + if ((!keystroke_trigger->keys && !keys) || + (keystroke_trigger->keys && keys && strcmp(keystroke_trigger->keys, keys)==0)) + { + ply_trigger_pull (keystroke_trigger->trigger, NULL); + ply_list_remove_node (state->keystroke_triggers, node); + return; + } } - - ply_boot_splash_ask_for_password (state->boot_splash, - prompt, answer); } + static void on_newroot (state_t *state, const char *root_dir) @@ -462,6 +527,9 @@ start_boot_server (state_t *state) server = ply_boot_server_new ((ply_boot_server_update_handler_t) on_update, (ply_boot_server_ask_for_password_handler_t) on_ask_for_password, + (ply_boot_server_ask_question_handler_t) on_ask_question, + (ply_boot_server_watch_for_keystroke_handler_t) on_watch_for_keystroke, + (ply_boot_server_ignore_keystroke_handler_t) on_ignore_keystroke, (ply_boot_server_show_splash_handler_t) on_show_splash, (ply_boot_server_hide_splash_handler_t) on_hide_splash, (ply_boot_server_newroot_handler_t) on_newroot, @@ -483,6 +551,42 @@ start_boot_server (state_t *state) return server; } + +static void +update_display (state_t *state) +{ + if (!state->boot_splash) return; + + ply_list_node_t *node; + node = ply_list_get_first_node (state->entry_triggers); + if (node) + { + ply_entry_trigger_t* entry_trigger = ply_list_node_get_data (node); + if (entry_trigger->type == PLY_ENTRY_TRIGGER_TYPE_PASSWORD) + { + int bullets = mbstowcs (NULL, ply_buffer_get_bytes (state->entry_buffer), 0); + bullets = MAX(0, bullets); + ply_boot_splash_display_password (state->boot_splash, + entry_trigger->prompt, + bullets); + } + else if (entry_trigger->type == PLY_ENTRY_TRIGGER_TYPE_QUESTION) + { + ply_boot_splash_display_question (state->boot_splash, + entry_trigger->prompt, + ply_buffer_get_bytes (state->entry_buffer)); + } + else { + ply_trace("unkown entry type"); + } + } + else + { + ply_boot_splash_display_normal (state->boot_splash); + } + +} + static void on_escape_pressed (state_t *state) { @@ -503,8 +607,79 @@ on_escape_pressed (state_t *state) show_default_splash (state); state->showing_details = false; } + update_display (state); } +static void +on_keyboard_input (state_t *state, + const char *keyboard_input, + size_t character_size) +{ + ply_list_node_t *node; + node = ply_list_get_first_node (state->entry_triggers); + if (node) + { + ply_buffer_append_bytes (state->entry_buffer, keyboard_input, character_size); + update_display (state); + } + else + { + for (node = ply_list_get_first_node (state->keystroke_triggers); node; + node = ply_list_get_next_node (state->keystroke_triggers, node)) + { + ply_keystroke_watch_t* keystroke_trigger = ply_list_node_get_data (node); + if (!keystroke_trigger->keys || strstr(keystroke_trigger->keys, keyboard_input)) /* assume strstr works on utf8 arrays */ + { + ply_trigger_pull (keystroke_trigger->trigger, keyboard_input); + ply_list_remove_node (state->keystroke_triggers, node); + free(keystroke_trigger); + return; + } + } + return; + } +} +void +on_backspace (state_t *state) +{ + ssize_t bytes_to_remove; + ssize_t previous_character_size; + const char *bytes; + size_t size; + ply_list_node_t *node = ply_list_get_first_node (state->entry_triggers); + if (!node) return; + + bytes = ply_buffer_get_bytes (state->entry_buffer); + size = ply_buffer_get_size (state->entry_buffer); + + bytes_to_remove = MIN(size, MB_CUR_MAX); + while ((previous_character_size = mbrlen (&bytes[size - bytes_to_remove], bytes_to_remove, NULL)) < bytes_to_remove && + previous_character_size > 0) + bytes_to_remove -= previous_character_size; + + ply_buffer_remove_bytes_at_end (state->entry_buffer, bytes_to_remove); + update_display (state); +} + +void +on_enter (state_t *state, + const char *line) +{ + ply_list_node_t *node; + node = ply_list_get_first_node (state->entry_triggers); + if (node) + { + ply_entry_trigger_t* entry_trigger = ply_list_node_get_data (node); + const char* reply_text = ply_buffer_get_bytes (state->entry_buffer); + ply_trigger_pull (entry_trigger->trigger, reply_text); + ply_buffer_clear (state->entry_buffer); + ply_list_remove_node (state->entry_triggers, node); + free(entry_trigger); + update_display (state); + } +} + + static ply_window_t * create_window (state_t *state, const char *tty_name) @@ -541,9 +716,6 @@ add_windows_to_boot_splash (state_t *state, { ply_trace ("adding window to boot splash"); ply_boot_splash_add_window (splash, window); - ply_trace ("listening for escape key"); - ply_window_set_escape_handler (window, (ply_window_escape_handler_t) - on_escape_pressed, state); } node = next_node; } @@ -576,7 +748,6 @@ start_boot_splash (state_t *state, ply_trace ("adding windows to boot splash"); add_windows_to_boot_splash (state, splash); - ply_trace ("showing plugin"); if (!ply_boot_splash_show (splash)) { @@ -586,6 +757,7 @@ start_boot_splash (state_t *state, return NULL; } + update_display (state); return splash; } @@ -780,6 +952,7 @@ static bool initialize_environment (state_t *state) { ply_trace ("initializing minimal work environment"); + ply_list_node_t *node; if (!get_kernel_command_line (state)) return false; @@ -788,13 +961,37 @@ initialize_environment (state_t *state) check_logging (state); state->windows = ply_list_new (); + state->keystroke_triggers = ply_list_new (); + state->entry_triggers = ply_list_new (); + state->entry_buffer = ply_buffer_new(); check_for_consoles (state); if (state->console != NULL) redirect_standard_io_to_device (state->console); else redirect_standard_io_to_device ("tty1"); - + + + for (node = ply_list_get_first_node (state->windows); node; + node = ply_list_get_next_node (state->windows, node)) + { + ply_window_t *window = ply_list_node_get_data (node); + + ply_trace ("listening for escape key"); + ply_window_add_escape_handler (window, (ply_window_escape_handler_t) + on_escape_pressed, state); + ply_trace ("listening for keystrokes"); + ply_window_add_keyboard_input_handler (window, + (ply_window_keyboard_input_handler_t) on_keyboard_input, state); + ply_trace ("listening for backspace"); + ply_window_add_backspace_handler (window, + (ply_window_backspace_handler_t) on_backspace, state); + ply_trace ("listening for enter"); + ply_window_add_enter_handler (window, + (ply_window_enter_handler_t) on_enter, state); + } + + ply_trace ("initialized minimal work environment"); return true; } diff --git a/src/plugins/splash/details/plugin.c b/src/plugins/splash/details/plugin.c index b4fc3e6d..c25b75ac 100644 --- a/src/plugins/splash/details/plugin.c +++ b/src/plugins/splash/details/plugin.c @@ -53,20 +53,24 @@ #include -void ask_for_password (ply_boot_splash_plugin_t *plugin, - const char *prompt, - ply_trigger_t *answer); +#define CLEAR_LINE_SEQUENCE "\033[2K\r" + +typedef enum { + PLY_BOOT_SPLASH_DISPLAY_NORMAL, + PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY, + PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY +} ply_boot_splash_display_type_t; + + typedef void (* ply_boot_splash_plugin_window_handler_t) (ply_window_t *window, ply_boot_splash_plugin_t *, void *user_data, void *other_user_data); ply_boot_splash_plugin_interface_t *ply_boot_splash_plugin_get_interface (void); struct _ply_boot_splash_plugin { ply_event_loop_t *loop; - - ply_trigger_t *pending_password_answer; ply_list_t *windows; + ply_boot_splash_display_type_t state; - uint32_t keyboard_input_is_hidden : 1; }; ply_boot_splash_plugin_t * @@ -78,7 +82,7 @@ create_plugin (void) plugin = calloc (1, sizeof (ply_boot_splash_plugin_t)); plugin->windows = ply_list_new (); - + plugin->state = PLY_BOOT_SPLASH_DISPLAY_NORMAL; return plugin; } @@ -103,12 +107,6 @@ detach_from_event_loop (ply_boot_splash_plugin_t *plugin) ply_trace ("detaching from event loop"); } - -static void -write_text_on_window (ply_window_t *window, - ply_boot_splash_plugin_t *plugin, - const char *text, - void *user_data); static void for_each_window (ply_boot_splash_plugin_t *plugin, ply_boot_splash_plugin_window_handler_t handler, @@ -149,45 +147,31 @@ write_text_on_window (ply_window_t *window, write (fd, text, size); } +static void +clear_line_on_window (ply_window_t *window, + ply_boot_splash_plugin_t *plugin, + void *user_data, + void *more_user_data) +{ + ply_window_clear_text_line (window); +} + void on_keyboard_input (ply_boot_splash_plugin_t *plugin, const char *keyboard_input, size_t character_size) { - if (plugin->keyboard_input_is_hidden) - for_each_window (plugin, - (ply_boot_splash_plugin_window_handler_t) - write_text_on_window, (void *) "*", - (void *) strlen ("*")); - else - for_each_window (plugin, - (ply_boot_splash_plugin_window_handler_t) - write_text_on_window, (void *) keyboard_input, - (void *) character_size); } void on_backspace (ply_boot_splash_plugin_t *plugin) { - for_each_window (plugin, - (ply_boot_splash_plugin_window_handler_t) - ply_window_clear_text_character, NULL, NULL); } void on_enter (ply_boot_splash_plugin_t *plugin, const char *line) { - if (plugin->pending_password_answer != NULL) - { - ply_trigger_pull (plugin->pending_password_answer, line); - plugin->keyboard_input_is_hidden = false; - plugin->pending_password_answer = NULL; - - for_each_window (plugin, - (ply_boot_splash_plugin_window_handler_t) - ply_window_clear_text_line, NULL, NULL); - } } void @@ -208,32 +192,26 @@ static void initialize_window (ply_window_t *window, ply_boot_splash_plugin_t *plugin) { - ply_boot_splash_plugin_interface_t *interface; - ply_window_set_mode (window, PLY_WINDOW_MODE_TEXT); - ply_window_set_keyboard_input_handler (window, + ply_window_add_keyboard_input_handler (window, (ply_window_keyboard_input_handler_t) on_keyboard_input, plugin); - ply_window_set_backspace_handler (window, + ply_window_add_backspace_handler (window, (ply_window_backspace_handler_t) on_backspace, plugin); - ply_window_set_enter_handler (window, + ply_window_add_enter_handler (window, (ply_window_enter_handler_t) on_enter, plugin); - - interface = ply_boot_splash_plugin_get_interface (); - - interface->ask_for_password = ask_for_password; } static void uninitialize_window (ply_window_t *window, ply_boot_splash_plugin_t *plugin) { - ply_window_set_keyboard_input_handler (window, NULL, NULL); - ply_window_set_backspace_handler (window, NULL, NULL); - ply_window_set_enter_handler (window, NULL, NULL); + ply_window_remove_keyboard_input_handler (window, (ply_window_keyboard_input_handler_t) on_keyboard_input); + ply_window_remove_backspace_handler (window, (ply_window_backspace_handler_t) on_backspace); + ply_window_remove_enter_handler (window, (ply_window_enter_handler_t) on_enter); } bool @@ -299,13 +277,6 @@ hide_splash_screen (ply_boot_splash_plugin_t *plugin, (ply_boot_splash_plugin_window_handler_t) uninitialize_window, NULL, NULL); - if (plugin->pending_password_answer != NULL) - { - ply_trigger_pull (plugin->pending_password_answer, ""); - plugin->pending_password_answer = NULL; - plugin->keyboard_input_is_hidden = false; - } - ply_event_loop_stop_watching_for_exit (plugin->loop, (ply_event_loop_exit_handler_t) detach_from_event_loop, @@ -313,37 +284,105 @@ hide_splash_screen (ply_boot_splash_plugin_t *plugin, detach_from_event_loop (plugin); } -static void -ask_for_password_on_window (ply_window_t *window, - ply_boot_splash_plugin_t *plugin, - const char *prompt) +void display_normal (ply_boot_splash_plugin_t *plugin) { - int fd; - - ply_window_set_mode (window, PLY_WINDOW_MODE_TEXT); + if (plugin->state != PLY_BOOT_SPLASH_DISPLAY_NORMAL) + { + for_each_window (plugin, + (ply_boot_splash_plugin_window_handler_t) + write_text_on_window, + (void *) "\r\n", (void *) strlen ("\r\n")); + } + plugin->state = PLY_BOOT_SPLASH_DISPLAY_NORMAL; +} - fd = ply_window_get_tty_fd (window); - if (prompt != NULL) +void +display_password (ply_boot_splash_plugin_t *plugin, + const char *prompt, + int bullets) +{ + int i; + if (plugin->state != PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY) + { + for_each_window (plugin, + (ply_boot_splash_plugin_window_handler_t) + write_text_on_window, + (void *) "\r\n", (void *) strlen ("\r\n")); + } + else { - write (fd, "\r\n", strlen ("\r\n")); - write (fd, prompt, strlen (prompt)); + for_each_window (plugin, + (ply_boot_splash_plugin_window_handler_t) + write_text_on_window, + (void *) CLEAR_LINE_SEQUENCE, + (void *) strlen (CLEAR_LINE_SEQUENCE)); } + plugin->state = PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY; + + if (prompt) + for_each_window (plugin, + (ply_boot_splash_plugin_window_handler_t) + write_text_on_window, + (void *) prompt, + (void *) strlen (prompt)); + else + for_each_window (plugin, + (ply_boot_splash_plugin_window_handler_t) + write_text_on_window, + (void *) "Password", + (void *) strlen ("Password")); - write (fd, "\r\nPassword: ", strlen ("\r\nPassword: ")); - plugin->keyboard_input_is_hidden = true; + for_each_window (plugin, + (ply_boot_splash_plugin_window_handler_t) + write_text_on_window, + (void *) ":", + (void *) strlen (":")); + for (i=0; ipending_password_answer = answer; - + if (plugin->state != PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY) + { + for_each_window (plugin, + (ply_boot_splash_plugin_window_handler_t) + write_text_on_window, + (void *) "\r\n", (void *) strlen ("\r\n")); + } + else + { + for_each_window (plugin, + (ply_boot_splash_plugin_window_handler_t) + write_text_on_window, + (void *) CLEAR_LINE_SEQUENCE, + (void *) strlen (CLEAR_LINE_SEQUENCE)); + } + plugin->state = PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY; + if (prompt) + for_each_window (plugin, + (ply_boot_splash_plugin_window_handler_t) + write_text_on_window, + (void *) prompt, + (void *) strlen (prompt)); for_each_window (plugin, - (ply_boot_splash_plugin_window_handler_t) - ask_for_password_on_window, (void *) prompt, NULL); + (ply_boot_splash_plugin_window_handler_t) + write_text_on_window, + (void *) ":", + (void *) strlen (":")); + for_each_window (plugin, + (ply_boot_splash_plugin_window_handler_t) + write_text_on_window, + (void *) entry_text, + (void *) strlen (entry_text)); } ply_boot_splash_plugin_interface_t * @@ -359,6 +398,9 @@ ply_boot_splash_plugin_get_interface (void) .update_status = update_status, .on_boot_output = on_boot_output, .hide_splash_screen = hide_splash_screen, + .display_normal = display_normal, + .display_password = display_password, + .display_question = display_question, }; return &plugin_interface; diff --git a/src/plugins/splash/fade-in/plugin.c b/src/plugins/splash/fade-in/plugin.c index e5101ad7..73318c54 100644 --- a/src/plugins/splash/fade-in/plugin.c +++ b/src/plugins/splash/fade-in/plugin.c @@ -57,6 +57,12 @@ #define FRAMES_PER_SECOND 30 #endif +typedef enum { + PLY_BOOT_SPLASH_DISPLAY_NORMAL, + PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY, + PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY +} ply_boot_splash_display_type_t; + typedef struct { int x; @@ -76,8 +82,7 @@ struct _ply_boot_splash_plugin ply_window_t *window; ply_entry_t *entry; - - ply_trigger_t *pending_password_answer; + ply_boot_splash_display_type_t state; double start_time; double now; @@ -98,6 +103,7 @@ create_plugin (void) plugin->star_image = ply_image_new (PLYMOUTH_IMAGE_DIR "fade-in/star.png"); plugin->lock_image = ply_image_new (PLYMOUTH_IMAGE_DIR "fade-in/lock.png"); plugin->entry = ply_entry_new (PLYMOUTH_IMAGE_DIR "fade-in"); + plugin->state = PLY_BOOT_SPLASH_DISPLAY_NORMAL; plugin->stars = ply_list_new (); return plugin; @@ -259,7 +265,6 @@ animate_at_time (ply_boot_splash_plugin_t *plugin, ply_frame_buffer_unpause_updates (plugin->frame_buffer); } -static void draw_password_entry (ply_boot_splash_plugin_t *plugin); static void on_timeout (ply_boot_splash_plugin_t *plugin) { @@ -381,31 +386,17 @@ on_keyboard_input (ply_boot_splash_plugin_t *plugin, const char *keyboard_input, size_t character_size) { - if (plugin->pending_password_answer == NULL) - return; - - ply_entry_add_bullet (plugin->entry); } void on_backspace (ply_boot_splash_plugin_t *plugin) { - ply_entry_remove_bullet (plugin->entry); } void on_enter (ply_boot_splash_plugin_t *plugin, const char *text) { - - if (plugin->pending_password_answer == NULL) - return; - - ply_trigger_pull (plugin->pending_password_answer, text); - plugin->pending_password_answer = NULL; - - ply_entry_hide (plugin->entry); - start_animation (plugin); } void @@ -424,10 +415,10 @@ on_draw (ply_boot_splash_plugin_t *plugin, draw_background (plugin, &area); - if (plugin->pending_password_answer != NULL) - ply_entry_draw (plugin->entry); - else + if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_NORMAL) animate_at_time (plugin, plugin->now); + else + ply_entry_draw (plugin->entry); } void @@ -470,13 +461,13 @@ show_splash_screen (ply_boot_splash_plugin_t *plugin, assert (plugin != NULL); assert (plugin->logo_image != NULL); - ply_window_set_keyboard_input_handler (plugin->window, + ply_window_add_keyboard_input_handler (plugin->window, (ply_window_keyboard_input_handler_t) on_keyboard_input, plugin); - ply_window_set_backspace_handler (plugin->window, + ply_window_add_backspace_handler (plugin->window, (ply_window_backspace_handler_t) on_backspace, plugin); - ply_window_set_enter_handler (plugin->window, + ply_window_add_enter_handler (plugin->window, (ply_window_enter_handler_t) on_enter, plugin); @@ -613,15 +604,11 @@ hide_splash_screen (ply_boot_splash_plugin_t *plugin, { assert (plugin != NULL); - if (plugin->pending_password_answer != NULL) - { - ply_trigger_pull (plugin->pending_password_answer, ""); - plugin->pending_password_answer = NULL; - } - - ply_window_set_keyboard_input_handler (plugin->window, NULL, NULL); - ply_window_set_backspace_handler (plugin->window, NULL, NULL); - ply_window_set_enter_handler (plugin->window, NULL, NULL); + ply_window_remove_keyboard_input_handler (plugin->window, (ply_window_keyboard_input_handler_t) on_keyboard_input); + ply_window_remove_backspace_handler (plugin->window, (ply_window_backspace_handler_t) on_backspace); + ply_window_remove_enter_handler (plugin->window, (ply_window_enter_handler_t) on_enter); + ply_window_set_draw_handler (plugin->window, NULL, NULL); + ply_window_set_erase_handler (plugin->window, NULL, NULL); if (plugin->loop != NULL) { @@ -660,20 +647,48 @@ show_password_entry (ply_boot_splash_plugin_t *plugin) x = area.width / 2.0 - (lock_width + entry_width) / 2.0 + lock_width; y = area.height / 2.0 - entry_height / 2.0; - draw_background (plugin, NULL); - ply_entry_show (plugin->entry, plugin->loop, plugin->window, x, y); } +void display_normal (ply_boot_splash_plugin_t *plugin) +{ + if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY || + plugin->state == PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY) + { + plugin->state = PLY_BOOT_SPLASH_DISPLAY_NORMAL; + ply_entry_hide (plugin->entry); + start_animation(plugin); + } +} + +void +display_password (ply_boot_splash_plugin_t *plugin, + const char *prompt, + int bullets) +{ + if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_NORMAL) + { + stop_animation (plugin); + } + plugin->state = PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY; + show_password_entry (plugin); + ply_entry_set_bullet_count (plugin->entry, bullets); +} + void -ask_for_password (ply_boot_splash_plugin_t *plugin, +display_question (ply_boot_splash_plugin_t *plugin, const char *prompt, - ply_trigger_t *answer) + const char *entry_text) { - plugin->pending_password_answer = answer; + if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_NORMAL) + { + stop_animation (plugin); + show_password_entry (plugin); + } - stop_animation (plugin); + plugin->state = PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY; show_password_entry (plugin); + ply_entry_set_text (plugin->entry, entry_text); } ply_boot_splash_plugin_interface_t * @@ -688,7 +703,9 @@ ply_boot_splash_plugin_get_interface (void) .show_splash_screen = show_splash_screen, .update_status = update_status, .hide_splash_screen = hide_splash_screen, - .ask_for_password = ask_for_password, + .display_normal = display_normal, + .display_password = display_password, + .display_question = display_question, }; return &plugin_interface; diff --git a/src/plugins/splash/pulser/plugin.c b/src/plugins/splash/pulser/plugin.c index d938cff1..82a25c18 100644 --- a/src/plugins/splash/pulser/plugin.c +++ b/src/plugins/splash/pulser/plugin.c @@ -61,7 +61,6 @@ struct _ply_boot_splash_plugin { ply_event_loop_t *loop; - ply_trigger_t *pending_password_answer; ply_window_t *window; ply_text_pulser_t *pulser; @@ -169,30 +168,17 @@ on_keyboard_input (ply_boot_splash_plugin_t *plugin, const char *keyboard_input, size_t character_size) { - if (plugin->keyboard_input_is_hidden) - write (STDOUT_FILENO, "•", strlen ("•")); - else - write (STDOUT_FILENO, keyboard_input, character_size); } void on_backspace (ply_boot_splash_plugin_t *plugin) { - write (STDOUT_FILENO, BACKSPACE, strlen (BACKSPACE)); } void on_enter (ply_boot_splash_plugin_t *plugin, const char *line) { - if (plugin->pending_password_answer != NULL) - { - ply_trigger_pull (plugin->pending_password_answer, line); - plugin->keyboard_input_is_hidden = false; - plugin->pending_password_answer = NULL; - - start_animation (plugin); - } } void @@ -240,13 +226,13 @@ show_splash_screen (ply_boot_splash_plugin_t *plugin, ply_show_new_kernel_messages (false); - ply_window_set_keyboard_input_handler (plugin->window, + ply_window_add_keyboard_input_handler (plugin->window, (ply_window_keyboard_input_handler_t) on_keyboard_input, plugin); - ply_window_set_backspace_handler (plugin->window, + ply_window_add_backspace_handler (plugin->window, (ply_window_backspace_handler_t) on_backspace, plugin); - ply_window_set_enter_handler (plugin->window, + ply_window_add_enter_handler (plugin->window, (ply_window_enter_handler_t) on_enter, plugin); ply_window_set_draw_handler (plugin->window, @@ -283,12 +269,6 @@ hide_splash_screen (ply_boot_splash_plugin_t *plugin, ply_trace ("hiding splash screen"); - if (plugin->pending_password_answer != NULL) - { - ply_trigger_pull (plugin->pending_password_answer, ""); - plugin->pending_password_answer = NULL; - } - if (plugin->loop != NULL) { stop_animation (plugin); @@ -302,9 +282,9 @@ hide_splash_screen (ply_boot_splash_plugin_t *plugin, if (plugin->window != NULL) { - ply_window_set_keyboard_input_handler (plugin->window, NULL, NULL); - ply_window_set_backspace_handler (plugin->window, NULL, NULL); - ply_window_set_enter_handler (plugin->window, NULL, NULL); + ply_window_remove_keyboard_input_handler (plugin->window, (ply_window_keyboard_input_handler_t) on_keyboard_input); + ply_window_remove_backspace_handler (plugin->window, (ply_window_backspace_handler_t) on_backspace); + ply_window_remove_enter_handler (plugin->window, (ply_window_enter_handler_t) on_enter); ply_window_set_draw_handler (plugin->window, NULL, NULL); ply_window_set_erase_handler (plugin->window, NULL, NULL); @@ -317,37 +297,82 @@ hide_splash_screen (ply_boot_splash_plugin_t *plugin, ply_show_new_kernel_messages (true); } +void display_normal (ply_boot_splash_plugin_t *plugin) +{ + start_animation(plugin); +} + void -ask_for_password (ply_boot_splash_plugin_t *plugin, +display_password (ply_boot_splash_plugin_t *plugin, const char *prompt, - ply_trigger_t *answer) + int bullets) { - int window_width, window_height; - - plugin->pending_password_answer = answer; + int window_width, window_height; + int i; + stop_animation (plugin); + ply_window_set_background_color (plugin->window, PLY_WINDOW_COLOR_DEFAULT); + ply_window_clear_screen (plugin->window); - stop_animation (plugin); - ply_window_set_background_color (plugin->window, PLY_WINDOW_COLOR_DEFAULT); - ply_window_clear_screen (plugin->window); + window_width = ply_window_get_number_of_text_columns (plugin->window); + window_height = ply_window_get_number_of_text_rows (plugin->window); + + if (!prompt) + prompt = "Password"; + + ply_window_set_text_cursor_position (plugin->window, 0, window_height / 2); + + for (i=0; i < window_width; i++) + { + write (STDOUT_FILENO, " ", strlen (" ")); + } + ply_window_set_text_cursor_position (plugin->window, + window_width / 2 - (strlen (prompt)), + window_height / 2); + write (STDOUT_FILENO, prompt, strlen (prompt)); + write (STDOUT_FILENO, ":", strlen (":")); + + for (i=0; i < bullets; i++) + { + write (STDOUT_FILENO, "•", strlen ("•")); + } + ply_window_show_text_cursor (plugin->window); +} - window_width = ply_window_get_number_of_text_columns (plugin->window); - window_height = ply_window_get_number_of_text_rows (plugin->window); +void +display_question (ply_boot_splash_plugin_t *plugin, + const char *prompt, + const char *entry_text) +{ + int window_width, window_height; + int i; + stop_animation (plugin); + ply_window_set_background_color (plugin->window, PLY_WINDOW_COLOR_DEFAULT); + ply_window_clear_screen (plugin->window); - if (prompt != NULL) - { + window_width = ply_window_get_number_of_text_columns (plugin->window); + window_height = ply_window_get_number_of_text_rows (plugin->window); + + if (!prompt) + prompt = ""; + ply_window_set_text_cursor_position (plugin->window, - window_width / 2 - strlen (prompt) / 2, - window_height / 2 - 1); + 0, window_height / 2); + + for (i=0; i < window_width; i++) + { + write (STDOUT_FILENO, " ", strlen (" ")); + } + ply_window_set_text_cursor_position (plugin->window, + window_width / 2 - (strlen (prompt)), + window_height / 2); write (STDOUT_FILENO, prompt, strlen (prompt)); - } - ply_window_set_text_cursor_position (plugin->window, - window_width / 2 - strlen ("Password: "), - window_height / 2); - write (STDOUT_FILENO, "Password: ", strlen ("Password: ")); - ply_window_show_text_cursor (plugin->window); - plugin->keyboard_input_is_hidden = true; + write (STDOUT_FILENO, ":", strlen (":")); + + write (STDOUT_FILENO, entry_text, strlen (entry_text)); + ply_window_show_text_cursor (plugin->window); } + ply_boot_splash_plugin_interface_t * ply_boot_splash_plugin_get_interface (void) { @@ -360,7 +385,9 @@ ply_boot_splash_plugin_get_interface (void) .show_splash_screen = show_splash_screen, .update_status = update_status, .hide_splash_screen = hide_splash_screen, - .ask_for_password = ask_for_password, + .display_normal = display_normal, + .display_password = display_password, + .display_question = display_question, }; return &plugin_interface; diff --git a/src/plugins/splash/solar/plugin.c b/src/plugins/splash/solar/plugin.c index 293ae78c..1c3b6a5d 100644 --- a/src/plugins/splash/solar/plugin.c +++ b/src/plugins/splash/solar/plugin.c @@ -73,6 +73,11 @@ #define SHOW_PROGRESS_BAR /*#define SHOW_LOGO_HALO */ +typedef enum { + PLY_BOOT_SPLASH_DISPLAY_NORMAL, + PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY, + PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY +} ply_boot_splash_display_type_t; typedef enum { @@ -179,8 +184,8 @@ struct _ply_boot_splash_plugin ply_entry_t *entry; ply_label_t *label; + ply_boot_splash_display_type_t state; - ply_trigger_t *pending_password_answer; ply_trigger_t *idle_trigger; ply_list_t *sprites; @@ -224,6 +229,7 @@ create_plugin (void) #endif plugin->entry = ply_entry_new (PLYMOUTH_IMAGE_DIR "solar"); plugin->label = ply_label_new (); + plugin->state = PLY_BOOT_SPLASH_DISPLAY_NORMAL; plugin->sprites = ply_list_new(); plugin->progress = 0; plugin->progress_target = -1; @@ -367,7 +373,6 @@ stretch_image(ply_image_t *scaled_image, ply_image_t *orig_image, int width) int stretched_width = ply_image_get_width (scaled_image); int stretched_height = ply_image_get_height (scaled_image); int orig_width = ply_image_get_width (orig_image); - int orig_height = ply_image_get_height (orig_image); uint32_t * scaled_image_data = ply_image_get_data (scaled_image); uint32_t * orig_image_data = ply_image_get_data (orig_image); @@ -523,7 +528,7 @@ satellite_move (ply_boot_splash_plugin_t *plugin, sprite_t* sprite, double time) if (satellite->type == SATELLITE_TYPE_PLANET) { - int x, y, z; + int x, y; uint32_t *image_data = ply_image_get_data (satellite->image); uint32_t *cresent_data = ply_image_get_data (satellite->image_altered); @@ -561,7 +566,7 @@ satellite_move (ply_boot_splash_plugin_t *plugin, sprite_t* sprite, double time) if (satellite->type == SATELLITE_TYPE_COMET) { - int x, y, z; + int x, y; uint32_t *image_data = ply_image_get_data (satellite->image); uint32_t *comet_data = ply_image_get_data (satellite->image_altered); @@ -661,8 +666,6 @@ flare_update (sprite_t* sprite, double time) int b; - static int start=1; - for (b=0; bwindow, PLY_WINDOW_MODE_GRAPHICS); if (plugin->progress_target>=0) @@ -825,7 +827,6 @@ animate_attime (ply_boot_splash_plugin_t *plugin, double time) sprite->z != sprite->oldz || sprite->refresh_me) { - ply_frame_buffer_area_t sprite_area; sprite->refresh_me=0; int width = ply_image_get_width (sprite->image); @@ -922,7 +923,6 @@ static void stop_animation (ply_boot_splash_plugin_t *plugin, ply_trigger_t *trigger) { - int i; ply_list_node_t *node; assert (plugin != NULL); @@ -971,31 +971,17 @@ on_keyboard_input (ply_boot_splash_plugin_t *plugin, const char *keyboard_input, size_t character_size) { - if (plugin->pending_password_answer == NULL) - return; - - ply_entry_add_bullet (plugin->entry); } void on_backspace (ply_boot_splash_plugin_t *plugin) { - ply_entry_remove_bullet (plugin->entry); } void on_enter (ply_boot_splash_plugin_t *plugin, const char *text) { - if (plugin->pending_password_answer == NULL) - return; - - ply_trigger_pull (plugin->pending_password_answer, text); - plugin->pending_password_answer = NULL; - - ply_entry_hide (plugin->entry); - ply_entry_remove_all_bullets (plugin->entry); - start_animation (plugin); } @@ -1021,7 +1007,8 @@ on_draw (ply_boot_splash_plugin_t *plugin, else ply_frame_buffer_pause_updates (plugin->frame_buffer); - if (plugin->pending_password_answer != NULL) + if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY || + plugin->state == PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY ) { draw_background (plugin, &clip_area); ply_entry_draw (plugin->entry); @@ -1351,13 +1338,13 @@ show_splash_screen (ply_boot_splash_plugin_t *plugin, assert (plugin != NULL); assert (plugin->logo_image != NULL); - ply_window_set_keyboard_input_handler (plugin->window, + ply_window_add_keyboard_input_handler (plugin->window, (ply_window_keyboard_input_handler_t) on_keyboard_input, plugin); - ply_window_set_backspace_handler (plugin->window, + ply_window_add_backspace_handler (plugin->window, (ply_window_backspace_handler_t) on_backspace, plugin); - ply_window_set_enter_handler (plugin->window, + ply_window_add_enter_handler (plugin->window, (ply_window_enter_handler_t) on_enter, plugin); @@ -1449,15 +1436,9 @@ hide_splash_screen (ply_boot_splash_plugin_t *plugin, { assert (plugin != NULL); - if (plugin->pending_password_answer != NULL) - { - ply_trigger_pull (plugin->pending_password_answer, ""); - plugin->pending_password_answer = NULL; - } - - ply_window_set_keyboard_input_handler (plugin->window, NULL, NULL); - ply_window_set_backspace_handler (plugin->window, NULL, NULL); - ply_window_set_enter_handler (plugin->window, NULL, NULL); + ply_window_remove_keyboard_input_handler (plugin->window, (ply_window_keyboard_input_handler_t) on_keyboard_input); + ply_window_remove_backspace_handler (plugin->window, (ply_window_backspace_handler_t) on_backspace); + ply_window_remove_enter_handler (plugin->window, (ply_window_enter_handler_t) on_enter); ply_window_set_draw_handler (plugin->window, NULL, NULL); ply_window_set_erase_handler (plugin->window, NULL, NULL); @@ -1489,38 +1470,44 @@ show_password_prompt (ply_boot_splash_plugin_t *plugin, assert (plugin != NULL); - draw_background (plugin, NULL); - - ply_frame_buffer_get_size (plugin->frame_buffer, &area); - plugin->box_area.width = ply_image_get_width (plugin->box_image); - plugin->box_area.height = ply_image_get_height (plugin->box_image); - plugin->box_area.x = area.width / 2.0 - plugin->box_area.width / 2.0; - plugin->box_area.y = area.height / 2.0 - plugin->box_area.height / 2.0; + if (ply_entry_is_hidden (plugin->entry)) + { + draw_background (plugin, NULL); - plugin->lock_area.width = ply_image_get_width (plugin->lock_image); - plugin->lock_area.height = ply_image_get_height (plugin->lock_image); + ply_frame_buffer_get_size (plugin->frame_buffer, &area); + plugin->box_area.width = ply_image_get_width (plugin->box_image); + plugin->box_area.height = ply_image_get_height (plugin->box_image); + plugin->box_area.x = area.width / 2.0 - plugin->box_area.width / 2.0; + plugin->box_area.y = area.height / 2.0 - plugin->box_area.height / 2.0; - entry_width = ply_entry_get_width (plugin->entry); - entry_height = ply_entry_get_height (plugin->entry); + plugin->lock_area.width = ply_image_get_width (plugin->lock_image); + plugin->lock_area.height = ply_image_get_height (plugin->lock_image); - x = area.width / 2.0 - (plugin->lock_area.width + entry_width) / 2.0 + plugin->lock_area.width; - y = area.height / 2.0 - entry_height / 2.0; + entry_width = ply_entry_get_width (plugin->entry); + entry_height = ply_entry_get_height (plugin->entry); - plugin->lock_area.x = area.width / 2.0 - (plugin->lock_area.width + entry_width) / 2.0; - plugin->lock_area.y = area.height / 2.0 - plugin->lock_area.height / 2.0; + x = area.width / 2.0 - (plugin->lock_area.width + entry_width) / 2.0 + plugin->lock_area.width; + y = area.height / 2.0 - entry_height / 2.0; - box_data = ply_image_get_data (plugin->box_image); - ply_frame_buffer_fill_with_argb32_data (plugin->frame_buffer, - &plugin->box_area, 0, 0, - box_data); + plugin->lock_area.x = area.width / 2.0 - (plugin->lock_area.width + entry_width) / 2.0; + plugin->lock_area.y = area.height / 2.0 - plugin->lock_area.height / 2.0; - ply_entry_show (plugin->entry, plugin->loop, plugin->window, x, y); + box_data = ply_image_get_data (plugin->box_image); + ply_frame_buffer_fill_with_argb32_data (plugin->frame_buffer, + &plugin->box_area, 0, 0, + box_data); - lock_data = ply_image_get_data (plugin->lock_image); - ply_frame_buffer_fill_with_argb32_data (plugin->frame_buffer, - &plugin->lock_area, 0, 0, - lock_data); + ply_entry_show (plugin->entry, plugin->loop, plugin->window, x, y); + lock_data = ply_image_get_data (plugin->lock_image); + ply_frame_buffer_fill_with_argb32_data (plugin->frame_buffer, + &plugin->lock_area, 0, 0, + lock_data); + } + else + { + ply_entry_draw (plugin->entry); + } if (prompt != NULL) { int label_width, label_height; @@ -1530,7 +1517,7 @@ show_password_prompt (ply_boot_splash_plugin_t *plugin, label_height = ply_label_get_height (plugin->label); x = plugin->box_area.x + plugin->lock_area.width / 2; - y = plugin->box_area.y + plugin->box_area.height + label_height; + y = plugin->box_area.y + plugin->box_area.height; ply_label_show (plugin->label, plugin->window, x, y); } @@ -1538,35 +1525,55 @@ show_password_prompt (ply_boot_splash_plugin_t *plugin, } void -ask_for_password (ply_boot_splash_plugin_t *plugin, - const char *prompt, - ply_trigger_t *answer) +on_root_mounted (ply_boot_splash_plugin_t *plugin) { - plugin->pending_password_answer = answer; + plugin->root_is_mounted = true; +} - if (ply_entry_is_hidden (plugin->entry)) - { - stop_animation (plugin, NULL); - show_password_prompt (plugin, prompt); - } - else +void +become_idle (ply_boot_splash_plugin_t *plugin, + ply_trigger_t *idle_trigger) +{ + stop_animation (plugin, idle_trigger); +} + +void display_normal (ply_boot_splash_plugin_t *plugin) +{ + if (plugin->state != PLY_BOOT_SPLASH_DISPLAY_NORMAL) { - ply_entry_draw (plugin->entry); - ply_label_draw (plugin->label); + plugin->state = PLY_BOOT_SPLASH_DISPLAY_NORMAL; + ply_entry_hide (plugin->entry); + start_animation(plugin); } } void -on_root_mounted (ply_boot_splash_plugin_t *plugin) +display_password (ply_boot_splash_plugin_t *plugin, + const char *prompt, + int bullets) { - plugin->root_is_mounted = true; + if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_NORMAL) + { + stop_animation (plugin, NULL); + } + plugin->state = PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY; + show_password_prompt (plugin, prompt); + ply_entry_set_bullet_count (plugin->entry, bullets); } void -become_idle (ply_boot_splash_plugin_t *plugin, - ply_trigger_t *idle_trigger) +display_question (ply_boot_splash_plugin_t *plugin, + const char *prompt, + const char *entry_text) { - stop_animation (plugin, idle_trigger); + if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_NORMAL) + { + stop_animation (plugin, NULL); + } + + plugin->state = PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY; + show_password_prompt (plugin, prompt); + ply_entry_set_text (plugin->entry, entry_text); } ply_boot_splash_plugin_interface_t * @@ -1582,9 +1589,11 @@ ply_boot_splash_plugin_get_interface (void) .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, + .display_normal = display_normal, + .display_password = display_password, + .display_question = display_question, }; return &plugin_interface; diff --git a/src/plugins/splash/spinfinity/plugin.c b/src/plugins/splash/spinfinity/plugin.c index b63e9b1a..ebf0bb73 100644 --- a/src/plugins/splash/spinfinity/plugin.c +++ b/src/plugins/splash/spinfinity/plugin.c @@ -66,6 +66,12 @@ #define BAR_HEIGHT 16 #endif +typedef enum { + PLY_BOOT_SPLASH_DISPLAY_NORMAL, + PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY, + PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY +} ply_boot_splash_display_type_t; + struct _ply_boot_splash_plugin { ply_event_loop_t *loop; @@ -80,8 +86,8 @@ struct _ply_boot_splash_plugin ply_throbber_t *throbber; ply_label_t *label; ply_progress_bar_t *progress_bar; + ply_boot_splash_display_type_t state; - ply_trigger_t *pending_password_answer; ply_trigger_t *idle_trigger; uint32_t root_is_mounted : 1; @@ -210,8 +216,6 @@ static void stop_animation (ply_boot_splash_plugin_t *plugin, ply_trigger_t *trigger) { - int i; - assert (plugin != NULL); assert (plugin->loop != NULL); @@ -264,10 +268,6 @@ on_keyboard_input (ply_boot_splash_plugin_t *plugin, const char *keyboard_input, size_t character_size) { - if (plugin->pending_password_answer == NULL) - return; - - ply_entry_add_bullet (plugin->entry); } void @@ -280,15 +280,6 @@ void on_enter (ply_boot_splash_plugin_t *plugin, const char *text) { - if (plugin->pending_password_answer == NULL) - return; - - ply_trigger_pull (plugin->pending_password_answer, text); - plugin->pending_password_answer = NULL; - - ply_entry_hide (plugin->entry); - ply_entry_remove_all_bullets (plugin->entry); - start_animation (plugin); } void @@ -308,7 +299,8 @@ on_draw (ply_boot_splash_plugin_t *plugin, ply_frame_buffer_pause_updates (plugin->frame_buffer); draw_background (plugin, &area); - if (plugin->pending_password_answer != NULL) + if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY || + plugin->state == PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY ) { ply_entry_draw (plugin->entry); ply_label_draw (plugin->label); @@ -362,13 +354,13 @@ show_splash_screen (ply_boot_splash_plugin_t *plugin, assert (plugin != NULL); assert (plugin->logo_image != NULL); - ply_window_set_keyboard_input_handler (plugin->window, + ply_window_add_keyboard_input_handler (plugin->window, (ply_window_keyboard_input_handler_t) on_keyboard_input, plugin); - ply_window_set_backspace_handler (plugin->window, + ply_window_add_backspace_handler (plugin->window, (ply_window_backspace_handler_t) on_backspace, plugin); - ply_window_set_enter_handler (plugin->window, + ply_window_add_enter_handler (plugin->window, (ply_window_enter_handler_t) on_enter, plugin); @@ -458,15 +450,10 @@ hide_splash_screen (ply_boot_splash_plugin_t *plugin, { assert (plugin != NULL); - if (plugin->pending_password_answer != NULL) - { - ply_trigger_pull (plugin->pending_password_answer, ""); - plugin->pending_password_answer = NULL; - } - ply_window_set_keyboard_input_handler (plugin->window, NULL, NULL); - ply_window_set_backspace_handler (plugin->window, NULL, NULL); - ply_window_set_enter_handler (plugin->window, NULL, NULL); + ply_window_remove_keyboard_input_handler (plugin->window, (ply_window_keyboard_input_handler_t) on_keyboard_input); + ply_window_remove_backspace_handler (plugin->window, (ply_window_backspace_handler_t) on_backspace); + ply_window_remove_enter_handler (plugin->window, (ply_window_enter_handler_t) on_enter); ply_window_set_draw_handler (plugin->window, NULL, NULL); ply_window_set_erase_handler (plugin->window, NULL, NULL); @@ -498,38 +485,44 @@ show_password_prompt (ply_boot_splash_plugin_t *plugin, assert (plugin != NULL); - draw_background (plugin, NULL); - - ply_frame_buffer_get_size (plugin->frame_buffer, &area); - plugin->box_area.width = ply_image_get_width (plugin->box_image); - plugin->box_area.height = ply_image_get_height (plugin->box_image); - plugin->box_area.x = area.width / 2.0 - plugin->box_area.width / 2.0; - plugin->box_area.y = area.height / 2.0 - plugin->box_area.height / 2.0; + if (ply_entry_is_hidden (plugin->entry)) + { + draw_background (plugin, NULL); - plugin->lock_area.width = ply_image_get_width (plugin->lock_image); - plugin->lock_area.height = ply_image_get_height (plugin->lock_image); + ply_frame_buffer_get_size (plugin->frame_buffer, &area); + plugin->box_area.width = ply_image_get_width (plugin->box_image); + plugin->box_area.height = ply_image_get_height (plugin->box_image); + plugin->box_area.x = area.width / 2.0 - plugin->box_area.width / 2.0; + plugin->box_area.y = area.height / 2.0 - plugin->box_area.height / 2.0; - entry_width = ply_entry_get_width (plugin->entry); - entry_height = ply_entry_get_height (plugin->entry); + plugin->lock_area.width = ply_image_get_width (plugin->lock_image); + plugin->lock_area.height = ply_image_get_height (plugin->lock_image); - x = area.width / 2.0 - (plugin->lock_area.width + entry_width) / 2.0 + plugin->lock_area.width; - y = area.height / 2.0 - entry_height / 2.0; + entry_width = ply_entry_get_width (plugin->entry); + entry_height = ply_entry_get_height (plugin->entry); - plugin->lock_area.x = area.width / 2.0 - (plugin->lock_area.width + entry_width) / 2.0; - plugin->lock_area.y = area.height / 2.0 - plugin->lock_area.height / 2.0; + x = area.width / 2.0 - (plugin->lock_area.width + entry_width) / 2.0 + plugin->lock_area.width; + y = area.height / 2.0 - entry_height / 2.0; - box_data = ply_image_get_data (plugin->box_image); - ply_frame_buffer_fill_with_argb32_data (plugin->frame_buffer, - &plugin->box_area, 0, 0, - box_data); + plugin->lock_area.x = area.width / 2.0 - (plugin->lock_area.width + entry_width) / 2.0; + plugin->lock_area.y = area.height / 2.0 - plugin->lock_area.height / 2.0; - ply_entry_show (plugin->entry, plugin->loop, plugin->window, x, y); + box_data = ply_image_get_data (plugin->box_image); + ply_frame_buffer_fill_with_argb32_data (plugin->frame_buffer, + &plugin->box_area, 0, 0, + box_data); - lock_data = ply_image_get_data (plugin->lock_image); - ply_frame_buffer_fill_with_argb32_data (plugin->frame_buffer, - &plugin->lock_area, 0, 0, - lock_data); + ply_entry_show (plugin->entry, plugin->loop, plugin->window, x, y); + lock_data = ply_image_get_data (plugin->lock_image); + ply_frame_buffer_fill_with_argb32_data (plugin->frame_buffer, + &plugin->lock_area, 0, 0, + lock_data); + } + else + { + ply_entry_draw (plugin->entry); + } if (prompt != NULL) { int label_width, label_height; @@ -539,7 +532,7 @@ show_password_prompt (ply_boot_splash_plugin_t *plugin, label_height = ply_label_get_height (plugin->label); x = plugin->box_area.x + plugin->lock_area.width / 2; - y = plugin->box_area.y + plugin->box_area.height + label_height; + y = plugin->box_area.y + plugin->box_area.height; ply_label_show (plugin->label, plugin->window, x, y); } @@ -547,35 +540,55 @@ show_password_prompt (ply_boot_splash_plugin_t *plugin, } void -ask_for_password (ply_boot_splash_plugin_t *plugin, - const char *prompt, - ply_trigger_t *answer) +on_root_mounted (ply_boot_splash_plugin_t *plugin) { - plugin->pending_password_answer = answer; + plugin->root_is_mounted = true; +} - if (ply_entry_is_hidden (plugin->entry)) - { - stop_animation (plugin, NULL); - show_password_prompt (plugin, prompt); - } - else +void +become_idle (ply_boot_splash_plugin_t *plugin, + ply_trigger_t *idle_trigger) +{ + stop_animation (plugin, idle_trigger); +} + +void display_normal (ply_boot_splash_plugin_t *plugin) +{ + if (plugin->state != PLY_BOOT_SPLASH_DISPLAY_NORMAL) { - ply_entry_draw (plugin->entry); - ply_label_draw (plugin->label); + plugin->state = PLY_BOOT_SPLASH_DISPLAY_NORMAL; + ply_entry_hide (plugin->entry); + start_animation(plugin); } } void -on_root_mounted (ply_boot_splash_plugin_t *plugin) +display_password (ply_boot_splash_plugin_t *plugin, + const char *prompt, + int bullets) { - plugin->root_is_mounted = true; + if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_NORMAL) + { + stop_animation (plugin, NULL); + } + plugin->state = PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY; + show_password_prompt (plugin, prompt); + ply_entry_set_bullet_count (plugin->entry, bullets); } void -become_idle (ply_boot_splash_plugin_t *plugin, - ply_trigger_t *idle_trigger) +display_question (ply_boot_splash_plugin_t *plugin, + const char *prompt, + const char *entry_text) { - stop_animation (plugin, idle_trigger); + if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_NORMAL) + { + stop_animation (plugin, NULL); + } + + plugin->state = PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY; + show_password_prompt (plugin, prompt); + ply_entry_set_text (plugin->entry, entry_text); } ply_boot_splash_plugin_interface_t * @@ -591,9 +604,11 @@ ply_boot_splash_plugin_get_interface (void) .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, + .display_normal = display_normal, + .display_password = display_password, + .display_question = display_question, }; return &plugin_interface; diff --git a/src/plugins/splash/text/plugin.c b/src/plugins/splash/text/plugin.c index f28fdebc..6a5b4b06 100644 --- a/src/plugins/splash/text/plugin.c +++ b/src/plugins/splash/text/plugin.c @@ -58,16 +58,15 @@ #define CLEAR_LINE_SEQUENCE "\033[2K\r\n" #define BACKSPACE "\b\033[0K" + struct _ply_boot_splash_plugin { ply_event_loop_t *loop; - ply_trigger_t *pending_password_answer; ply_window_t *window; ply_text_progress_bar_t *progress_bar; - uint32_t keyboard_input_is_hidden : 1; uint32_t is_animating : 1; }; void hide_splash_screen (ply_boot_splash_plugin_t *plugin, @@ -116,8 +115,6 @@ static void start_animation (ply_boot_splash_plugin_t *plugin) { - int window_width, window_height; - int width, height; assert (plugin != NULL); assert (plugin->loop != NULL); @@ -175,30 +172,17 @@ on_keyboard_input (ply_boot_splash_plugin_t *plugin, const char *keyboard_input, size_t character_size) { - if (plugin->keyboard_input_is_hidden) - write (STDOUT_FILENO, "•", strlen ("•")); - else - write (STDOUT_FILENO, keyboard_input, character_size); } void on_backspace (ply_boot_splash_plugin_t *plugin) { - write (STDOUT_FILENO, BACKSPACE, strlen (BACKSPACE)); } void on_enter (ply_boot_splash_plugin_t *plugin, const char *line) { - if (plugin->pending_password_answer != NULL) - { - ply_trigger_pull (plugin->pending_password_answer, line); - plugin->keyboard_input_is_hidden = false; - plugin->pending_password_answer = NULL; - - start_animation (plugin); - } } void @@ -244,13 +228,13 @@ show_splash_screen (ply_boot_splash_plugin_t *plugin, { assert (plugin != NULL); - ply_window_set_keyboard_input_handler (plugin->window, + ply_window_add_keyboard_input_handler (plugin->window, (ply_window_keyboard_input_handler_t) on_keyboard_input, plugin); - ply_window_set_backspace_handler (plugin->window, + ply_window_add_backspace_handler (plugin->window, (ply_window_backspace_handler_t) on_backspace, plugin); - ply_window_set_enter_handler (plugin->window, + ply_window_add_enter_handler (plugin->window, (ply_window_enter_handler_t) on_enter, plugin); ply_window_set_draw_handler (plugin->window, @@ -307,12 +291,6 @@ hide_splash_screen (ply_boot_splash_plugin_t *plugin, ply_trace ("hiding splash screen"); - if (plugin->pending_password_answer != NULL) - { - ply_trigger_pull (plugin->pending_password_answer, ""); - plugin->pending_password_answer = NULL; - } - if (plugin->loop != NULL) { stop_animation (plugin); @@ -326,9 +304,9 @@ hide_splash_screen (ply_boot_splash_plugin_t *plugin, if (plugin->window != NULL) { - ply_window_set_keyboard_input_handler (plugin->window, NULL, NULL); - ply_window_set_backspace_handler (plugin->window, NULL, NULL); - ply_window_set_enter_handler (plugin->window, NULL, NULL); + ply_window_remove_keyboard_input_handler (plugin->window, (ply_window_keyboard_input_handler_t) on_keyboard_input); + ply_window_remove_backspace_handler (plugin->window, (ply_window_backspace_handler_t) on_backspace); + ply_window_remove_enter_handler (plugin->window, (ply_window_enter_handler_t) on_enter); ply_window_set_draw_handler (plugin->window, NULL, NULL); ply_window_set_erase_handler (plugin->window, NULL, NULL); @@ -341,37 +319,82 @@ hide_splash_screen (ply_boot_splash_plugin_t *plugin, ply_show_new_kernel_messages (true); } +void display_normal (ply_boot_splash_plugin_t *plugin) +{ + start_animation(plugin); +} + void -ask_for_password (ply_boot_splash_plugin_t *plugin, +display_password (ply_boot_splash_plugin_t *plugin, const char *prompt, - ply_trigger_t *answer) + int bullets) { - int window_width, window_height; - - plugin->pending_password_answer = answer; + int window_width, window_height; + int i; + stop_animation (plugin); + ply_window_set_background_color (plugin->window, PLY_WINDOW_COLOR_DEFAULT); + ply_window_clear_screen (plugin->window); - stop_animation (plugin); - ply_window_set_background_color (plugin->window, PLY_WINDOW_COLOR_DEFAULT); - ply_window_clear_screen (plugin->window); + window_width = ply_window_get_number_of_text_columns (plugin->window); + window_height = ply_window_get_number_of_text_rows (plugin->window); + + if (!prompt) + prompt = "Password"; + + ply_window_set_text_cursor_position (plugin->window, 0, window_height / 2); + + for (i=0; i < window_width; i++) + { + write (STDOUT_FILENO, " ", strlen (" ")); + } + ply_window_set_text_cursor_position (plugin->window, + window_width / 2 - (strlen (prompt)), + window_height / 2); + write (STDOUT_FILENO, prompt, strlen (prompt)); + write (STDOUT_FILENO, ":", strlen (":")); + + for (i=0; i < bullets; i++) + { + write (STDOUT_FILENO, "*", strlen ("*")); + } + ply_window_show_text_cursor (plugin->window); +} - window_width = ply_window_get_number_of_text_columns (plugin->window); - window_height = ply_window_get_number_of_text_rows (plugin->window); +void +display_question (ply_boot_splash_plugin_t *plugin, + const char *prompt, + const char *entry_text) +{ + int window_width, window_height; + int i; + stop_animation (plugin); + ply_window_set_background_color (plugin->window, PLY_WINDOW_COLOR_DEFAULT); + ply_window_clear_screen (plugin->window); - if (prompt != NULL) - { + window_width = ply_window_get_number_of_text_columns (plugin->window); + window_height = ply_window_get_number_of_text_rows (plugin->window); + + if (!prompt) + prompt = ""; + + ply_window_set_text_cursor_position (plugin->window, + 0, window_height / 2); + + for (i=0; i < window_width; i++) + { + write (STDOUT_FILENO, " ", strlen (" ")); + } ply_window_set_text_cursor_position (plugin->window, - window_width / 2 - strlen (prompt) / 2, - window_height / 2 - 1); + window_width / 2 - (strlen (prompt)), + window_height / 2); write (STDOUT_FILENO, prompt, strlen (prompt)); - } - ply_window_set_text_cursor_position (plugin->window, - window_width / 2 - strlen ("Password: "), - window_height / 2); - write (STDOUT_FILENO, "Password: ", strlen ("Password: ")); - ply_window_show_text_cursor (plugin->window); - plugin->keyboard_input_is_hidden = true; + write (STDOUT_FILENO, ":", strlen (":")); + + write (STDOUT_FILENO, entry_text, strlen (entry_text)); + ply_window_show_text_cursor (plugin->window); } + ply_boot_splash_plugin_interface_t * ply_boot_splash_plugin_get_interface (void) { @@ -385,7 +408,9 @@ ply_boot_splash_plugin_get_interface (void) .update_status = update_status, .on_boot_progress = on_boot_progress, .hide_splash_screen = hide_splash_screen, - .ask_for_password = ask_for_password, + .display_normal = display_normal, + .display_password = display_password, + .display_question = display_question, }; return &plugin_interface; diff --git a/src/ply-boot-protocol.h b/src/ply-boot-protocol.h index f31b181a..33c3dee9 100644 --- a/src/ply-boot-protocol.h +++ b/src/ply-boot-protocol.h @@ -29,6 +29,9 @@ #define PLY_BOOT_PROTOCOL_REQUEST_TYPE_QUIT "Q" #define PLY_BOOT_PROTOCOL_REQUEST_TYPE_PASSWORD "*" #define PLY_BOOT_PROTOCOL_REQUEST_TYPE_CACHED_PASSWORD "c" +#define PLY_BOOT_PROTOCOL_REQUEST_TYPE_QUESTION "W" +#define PLY_BOOT_PROTOCOL_REQUEST_TYPE_KEYSTROKE "K" +#define PLY_BOOT_PROTOCOL_REQUEST_TYPE_KEYSTROKE_REMOVE "L" #define PLY_BOOT_PROTOCOL_REQUEST_TYPE_SHOW_SPLASH "$" #define PLY_BOOT_PROTOCOL_REQUEST_TYPE_HIDE_SPLASH "H" #define PLY_BOOT_PROTOCOL_REQUEST_TYPE_NEWROOT "R" diff --git a/src/ply-boot-server.c b/src/ply-boot-server.c index ff6ef29e..69689705 100644 --- a/src/ply-boot-server.c +++ b/src/ply-boot-server.c @@ -59,6 +59,9 @@ struct _ply_boot_server ply_boot_server_show_splash_handler_t show_splash_handler; ply_boot_server_hide_splash_handler_t hide_splash_handler; ply_boot_server_ask_for_password_handler_t ask_for_password_handler; + ply_boot_server_ask_question_handler_t ask_question_handler; + ply_boot_server_watch_for_keystroke_handler_t watch_for_keystroke_handler; + ply_boot_server_ignore_keystroke_handler_t ignore_keystroke_handler; ply_boot_server_quit_handler_t quit_handler; void *user_data; @@ -68,6 +71,9 @@ struct _ply_boot_server ply_boot_server_t * ply_boot_server_new (ply_boot_server_update_handler_t update_handler, ply_boot_server_ask_for_password_handler_t ask_for_password_handler, + ply_boot_server_ask_question_handler_t ask_question_handler, + ply_boot_server_watch_for_keystroke_handler_t watch_for_keystroke_handler, + ply_boot_server_ignore_keystroke_handler_t ignore_keystroke_handler, ply_boot_server_show_splash_handler_t show_splash_handler, ply_boot_server_hide_splash_handler_t hide_splash_handler, ply_boot_server_newroot_handler_t newroot_handler, @@ -85,6 +91,9 @@ ply_boot_server_new (ply_boot_server_update_handler_t update_handler, server->is_listening = false; server->update_handler = update_handler; server->ask_for_password_handler = ask_for_password_handler; + server->ask_question_handler = ask_question_handler; + server->watch_for_keystroke_handler = watch_for_keystroke_handler; + server->ignore_keystroke_handler = ignore_keystroke_handler; server->newroot_handler = newroot_handler; server->error_handler = error_handler; server->system_initialized_handler = initialized_handler; @@ -104,7 +113,7 @@ ply_boot_server_free (ply_boot_server_t *server) ply_list_node_t *node; if (server == NULL) return; - while (node = ply_list_get_first_node(server->connections)) + while ((node = ply_list_get_first_node(server->connections))) { ply_boot_connection_t *connection = ply_list_node_get_data (node); ply_boot_connection_on_hangup (connection); @@ -207,17 +216,17 @@ ply_boot_connection_is_from_root (ply_boot_connection_t *connection) return uid == 0; } + static void -ply_boot_connection_on_password_answer (ply_boot_connection_t *connection, - const char *password) +ply_boot_connection_send_answer (ply_boot_connection_t *connection, + const char *answer) { - uint8_t size; /* splash plugin isn't able to ask for password, * punt to client */ - if (password == NULL) + if (answer == NULL) { if (!ply_write (connection->fd, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NO_ANSWER, @@ -228,10 +237,10 @@ ply_boot_connection_on_password_answer (ply_boot_connection_t *connection, { /* FIXME: support up to 4 billion */ - if (strlen (password) > 255) - ply_error ("password to long to fit in buffer"); + if (strlen (answer) > 255) + ply_error ("answer to long to fit in buffer"); - size = (uint8_t) strlen (password); + size = (uint8_t) strlen (answer); if (!ply_write (connection->fd, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER, @@ -239,15 +248,39 @@ ply_boot_connection_on_password_answer (ply_boot_connection_t *connection, !ply_write (connection->fd, &size, sizeof (uint8_t)) || !ply_write (connection->fd, - password, size)) + answer, size)) ply_error ("could not write bytes: %m"); - ply_list_append_data (connection->server->cached_passwords, - strdup (password)); } } +static void +ply_boot_connection_on_password_answer (ply_boot_connection_t *connection, + const char *password) +{ + ply_boot_connection_send_answer (connection, password); + if (password != NULL) + ply_list_append_data (connection->server->cached_passwords, + strdup (password)); + +} + + +static void +ply_boot_connection_on_question_answer (ply_boot_connection_t *connection, + const char *answer) +{ + ply_boot_connection_send_answer (connection, answer); +} + +static void +ply_boot_connection_on_keystroke_answer (ply_boot_connection_t *connection, + const char *key) +{ + ply_boot_connection_send_answer (connection, key); +} + static void ply_boot_connection_on_request (ply_boot_connection_t *connection) { @@ -397,6 +430,53 @@ ply_boot_connection_on_request (ply_boot_connection_t *connection) free(command); return; } + else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_QUESTION) == 0) + { + ply_trigger_t *answer; + + answer = ply_trigger_new (NULL); + ply_trigger_add_handler (answer, + (ply_trigger_handler_t) + ply_boot_connection_on_question_answer, + connection); + + if (server->ask_question_handler != NULL) + server->ask_question_handler (server->user_data, + argument, + answer, + server); + /* will reply later + */ + free(command); + return; + } + else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_KEYSTROKE) == 0) + { + ply_trigger_t *answer; + + answer = ply_trigger_new (NULL); + ply_trigger_add_handler (answer, + (ply_trigger_handler_t) + ply_boot_connection_on_keystroke_answer, + connection); + + if (server->watch_for_keystroke_handler != NULL) + server->watch_for_keystroke_handler (server->user_data, + argument, + answer, + server); + /* will reply later + */ + free(command); + return; + } + else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_KEYSTROKE_REMOVE) == 0) + { + if (server->ignore_keystroke_handler != NULL) + server->ignore_keystroke_handler (server->user_data, + argument, + server); + } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_NEWROOT) == 0) { if (server->newroot_handler != NULL) @@ -565,6 +645,30 @@ on_ask_for_password (ply_event_loop_t *loop) return strdup ("password"); } +static void +on_ask_question (ply_event_loop_t *loop) +{ + printf ("got question request\n"); + return; +} + +static void +on_watch_for_keystroke (ply_event_loop_t *loop) +{ + printf ("got keystroke request\n"); + + return; +} + + +static void +on_ignore_keystroke (ply_event_loop_t *loop) +{ + printf ("got keystroke ignore request\n"); + + return; +} + int main (int argc, char **argv) @@ -579,6 +683,9 @@ main (int argc, server = ply_boot_server_new ((ply_boot_server_update_handler_t) on_update, (ply_boot_server_ask_for_password_handler_t) on_ask_for_password, + (ply_boot_server_ask_question_handler_t) on_ask_question, + (ply_boot_server_watch_for_keystroke_handler_t) on_watch_for_keystroke, + (ply_boot_server_ignore_keystroke_handler_t) on_ignore_keystroke, (ply_boot_server_show_splash_handler_t) on_show_splash, (ply_boot_server_hide_splash_handler_t) on_hide_splash, (ply_boot_server_newroot_handler_t) on_newroot, diff --git a/src/ply-boot-server.h b/src/ply-boot-server.h index e685ad91..6e140eb9 100644 --- a/src/ply-boot-server.h +++ b/src/ply-boot-server.h @@ -53,6 +53,21 @@ typedef void (* ply_boot_server_ask_for_password_handler_t) (void * const char *prompt, ply_trigger_t *answer, ply_boot_server_t *server); +typedef void (* ply_boot_server_question_answer_handler_t) (void *answer_data, + const char *answer, + ply_boot_server_t *server); +typedef void (* ply_boot_server_ask_question_handler_t) (void *user_data, + const char *prompt, + ply_trigger_t *answer, + ply_boot_server_t *server); +typedef void (* ply_boot_server_watch_for_keystroke_handler_t) (void *user_data, + const char *keys, + ply_trigger_t *answer, + ply_boot_server_t *server); + +typedef void (* ply_boot_server_ignore_keystroke_handler_t) (void *user_data, + const char *keys, + ply_boot_server_t *server); typedef void (* ply_boot_server_system_initialized_handler_t) (void *user_data, ply_boot_server_t *server); @@ -67,6 +82,9 @@ typedef void (* ply_boot_server_quit_handler_t) (void *user_data, #ifndef PLY_HIDE_FUNCTION_DECLARATIONS ply_boot_server_t *ply_boot_server_new (ply_boot_server_update_handler_t update_handler, ply_boot_server_ask_for_password_handler_t ask_for_password_handler, + ply_boot_server_ask_question_handler_t ask_question_handler, + ply_boot_server_watch_for_keystroke_handler_t watch_for_keystroke_handler, + ply_boot_server_ignore_keystroke_handler_t ignore_keystroke_handler, ply_boot_server_show_splash_handler_t show_splash_handler, ply_boot_server_hide_splash_handler_t hide_splash_handler, ply_boot_server_newroot_handler_t newroot_handler, diff --git a/src/ply-boot-splash.c b/src/ply-boot-splash.c index b6ecf433..b67ad204 100644 --- a/src/ply-boot-splash.c +++ b/src/ply-boot-splash.c @@ -283,42 +283,6 @@ ply_boot_splash_root_mounted (ply_boot_splash_t *splash) splash->plugin_interface->on_root_mounted (splash->plugin); } -static void -on_password_answered (ply_boot_splash_t *splash) -{ - if (splash->progress) - ply_progress_unpause (splash->progress); -} - -void -ply_boot_splash_ask_for_password (ply_boot_splash_t *splash, - const char *prompt, - ply_trigger_t *trigger) -{ - - assert (splash != NULL); - assert (splash->plugin_interface != NULL); - assert (splash->plugin != NULL); - assert (splash->is_shown); - - if (splash->plugin_interface->ask_for_password == NULL) - { - ply_trigger_pull (trigger, NULL); - return; - } - - if (splash->progress) - ply_progress_pause (splash->progress); - - ply_trigger_add_handler (trigger, - (ply_trigger_handler_t) - on_password_answered, splash); - - splash->plugin_interface->ask_for_password (splash->plugin, - prompt, - trigger); -} - static void ply_boot_splash_detach_from_event_loop (ply_boot_splash_t *splash) { @@ -354,6 +318,37 @@ ply_boot_splash_hide (ply_boot_splash_t *splash) } } +void ply_boot_splash_display_normal (ply_boot_splash_t *splash) +{ + assert (splash != NULL); + assert (splash->plugin_interface != NULL); + assert (splash->plugin != NULL); + if (splash->plugin_interface->display_normal != NULL) + splash->plugin_interface->display_normal (splash->plugin); +} +void ply_boot_splash_display_password (ply_boot_splash_t *splash, + const char *prompt, + int bullets) +{ + assert (splash != NULL); + assert (splash->plugin_interface != NULL); + assert (splash->plugin != NULL); + if (splash->plugin_interface->display_password != NULL) + splash->plugin_interface->display_password (splash->plugin, prompt, bullets); +} +void ply_boot_splash_display_question (ply_boot_splash_t *splash, + const char *prompt, + const char *entry_text) +{ + assert (splash != NULL); + assert (splash->plugin_interface != NULL); + assert (splash->plugin != NULL); + if (splash->plugin_interface->display_question != NULL) + splash->plugin_interface->display_question (splash->plugin, prompt, entry_text); +} + + + void ply_boot_splash_attach_to_event_loop (ply_boot_splash_t *splash, ply_event_loop_t *loop) @@ -458,7 +453,7 @@ main (int argc, } ply_window_attach_to_event_loop (state.window, state.loop); - ply_window_set_escape_handler (state.window, + ply_window_add_escape_handler (state.window, (ply_window_escape_handler_t) on_quit, &state); state.buffer = ply_buffer_new (); diff --git a/src/ply-boot-splash.h b/src/ply-boot-splash.h index d55f45f1..f925694a 100644 --- a/src/ply-boot-splash.h +++ b/src/ply-boot-splash.h @@ -53,11 +53,14 @@ void ply_boot_splash_update_output (ply_boot_splash_t *splash, const char *output, size_t size); void ply_boot_splash_root_mounted (ply_boot_splash_t *splash); - -void ply_boot_splash_ask_for_password (ply_boot_splash_t *splash, - const char *prompt, - ply_trigger_t *answer); void ply_boot_splash_hide (ply_boot_splash_t *splash); +void ply_boot_splash_display_normal (ply_boot_splash_t *splash); +void ply_boot_splash_display_password (ply_boot_splash_t *splash, + const char *prompt, + int bullets); +void ply_boot_splash_display_question (ply_boot_splash_t *splash, + const char *prompt, + const char *entry_text); void ply_boot_splash_attach_to_event_loop (ply_boot_splash_t *splash, ply_event_loop_t *loop); void ply_boot_splash_attach_progress (ply_boot_splash_t *splash,