diff --git a/TODO b/TODO index 4441b6d..40abb73 100644 --- a/TODO +++ b/TODO @@ -3,4 +3,4 @@ - Drop all the make ram disk and copy code. That was just to make bolting things on easier. We can integrate now. - allow longer than 255 byte replies from server to client - make server send immediate ACK for password request and then ANSWER later with a link back to original request in ANSWER -- buffer keyboard input from window instead of individual splash plugins +- have plugins hook into line editing through window directly, instead of via vtable functions diff --git a/src/ply-boot-splash-plugin.h b/src/ply-boot-splash-plugin.h index 8b8b53c..6b04e06 100644 --- a/src/ply-boot-splash-plugin.h +++ b/src/ply-boot-splash-plugin.h @@ -59,6 +59,10 @@ typedef struct const char *keyboard_input, size_t character_size); + void (* on_backspace) (ply_boot_splash_plugin_t *plugin); + void (* on_enter) (ply_boot_splash_plugin_t *plugin, + const char *line); + } ply_boot_splash_plugin_interface_t; #endif /* PLY_BOOT_SPLASH_PLUGIN_H */ diff --git a/src/ply-boot-splash.c b/src/ply-boot-splash.c index a2abc38..70acfa6 100644 --- a/src/ply-boot-splash.c +++ b/src/ply-boot-splash.c @@ -159,6 +159,21 @@ on_keyboard_input (ply_boot_splash_t *splash, splash->plugin_interface->on_keyboard_input (splash->plugin, keyboard_input, character_size); } +static void +on_backspace (ply_boot_splash_t *splash) +{ + if (splash->plugin_interface->on_backspace != NULL) + splash->plugin_interface->on_backspace (splash->plugin); +} + +static void +on_enter (ply_boot_splash_t *splash, + const char *line) +{ + if (splash->plugin_interface->on_enter != NULL) + splash->plugin_interface->on_enter (splash->plugin, line); +} + bool ply_boot_splash_show (ply_boot_splash_t *splash) { @@ -183,6 +198,12 @@ ply_boot_splash_show (ply_boot_splash_t *splash) ply_window_set_keyboard_input_handler (splash->window, (ply_window_keyboard_input_handler_t) on_keyboard_input, splash); + ply_window_set_backspace_handler (splash->window, + (ply_window_backspace_handler_t) + on_backspace, splash); + ply_window_set_enter_handler (splash->window, + (ply_window_enter_handler_t) + on_enter, splash); ply_trace ("showing splash screen\n"); if (!splash->plugin_interface->show_splash_screen (splash->plugin, @@ -263,6 +284,7 @@ ply_boot_splash_hide (ply_boot_splash_t *splash) splash->window); ply_window_set_keyboard_input_handler (splash->window, NULL, NULL); + ply_window_set_backspace_handler (splash->window, NULL, NULL); ply_boot_splash_unload_plugin (splash); splash->is_shown = false; diff --git a/src/ply-window.c b/src/ply-window.c index f077997..222cd80 100644 --- a/src/ply-window.c +++ b/src/ply-window.c @@ -45,11 +45,14 @@ #define KEY_CTRL_V '\026' #define KEY_ESCAPE '\033' +#define KEY_RETURN '\r' +#define KEY_BACKSPACE '\177' struct _ply_window { ply_event_loop_t *loop; ply_buffer_t *keyboard_input_buffer; + ply_buffer_t *line_buffer; char *tty_name; int tty_fd; @@ -60,8 +63,14 @@ struct _ply_window 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_window_t * @@ -73,6 +82,7 @@ ply_window_new (const char *tty_name) window = calloc (1, sizeof (ply_window_t)); window->keyboard_input_buffer = ply_buffer_new (); + window->line_buffer = ply_buffer_new (); window->loop = NULL; window->tty_name = strdup (tty_name); window->tty_fd = -1; @@ -104,7 +114,45 @@ process_keyboard_input (ply_window_t *window, ply_trace ("end escape key handler"); return; + case KEY_BACKSPACE: + { + ssize_t bytes_to_remove; + ssize_t previous_character_size; + const char *bytes; + size_t size; + ply_trace ("backspace key!"); + + bytes = ply_buffer_get_bytes (window->line_buffer); + size = ply_buffer_get_size (window->line_buffer); + + bytes_to_remove = 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; + + 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); + } + } + return; + + 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)); + + ply_buffer_clear (window->line_buffer); + return; + default: + ply_buffer_append_bytes (window->line_buffer, + keyboard_input, character_size); break; } } @@ -260,6 +308,7 @@ ply_window_free (ply_window_t *window) ply_window_close (window); ply_buffer_free (window->keyboard_input_buffer); + ply_buffer_free (window->line_buffer); free (window); } @@ -275,6 +324,17 @@ ply_window_set_keyboard_input_handler (ply_window_t *window, window->keyboard_input_handler_user_data = user_data; } +void +ply_window_set_backspace_handler (ply_window_t *window, + ply_window_backspace_handler_t backspace_handler, + void *user_data) +{ + assert (window != NULL); + + window->backspace_handler = backspace_handler; + window->backspace_handler_user_data = user_data; +} + void ply_window_set_escape_handler (ply_window_t *window, ply_window_escape_handler_t escape_handler, @@ -286,6 +346,17 @@ ply_window_set_escape_handler (ply_window_t *window, window->escape_handler_user_data = user_data; } +void +ply_window_set_enter_handler (ply_window_t *window, + ply_window_enter_handler_t enter_handler, + void *user_data) +{ + assert (window != NULL); + + window->enter_handler = enter_handler; + window->enter_handler_user_data = user_data; +} + void ply_window_attach_to_event_loop (ply_window_t *window, ply_event_loop_t *loop) diff --git a/src/ply-window.h b/src/ply-window.h index 4e8844d..f5dbcb5 100644 --- a/src/ply-window.h +++ b/src/ply-window.h @@ -27,6 +27,7 @@ #include #include "ply-event-loop.h" +#include "ply-buffer.h" typedef struct _ply_window ply_window_t; @@ -34,7 +35,11 @@ typedef void (* ply_window_keyboard_input_handler_t) (void *user_data, const char *keyboard_input, 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); typedef enum { @@ -49,9 +54,15 @@ 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); bool ply_window_open (ply_window_t *window); void ply_window_close (ply_window_t *window); diff --git a/src/splash-plugins/details/details.c b/src/splash-plugins/details/details.c index b8afb37..eb16331 100644 --- a/src/splash-plugins/details/details.c +++ b/src/splash-plugins/details/details.c @@ -52,7 +52,8 @@ #include -#define CLEAR_LINE_SEQUENCE "\033[2K" +#define CLEAR_LINE_SEQUENCE "\033[2K\r\n" +#define BACKSPACE "\b\033[0K" struct _ply_boot_splash_plugin { @@ -61,7 +62,6 @@ struct _ply_boot_splash_plugin ply_boot_splash_password_answer_handler_t password_answer_handler; void *password_answer_data; - ply_buffer_t *keyboard_input_buffer; uint32_t keyboard_input_is_hidden : 1; }; @@ -73,7 +73,6 @@ create_plugin (void) ply_trace ("creating plugin"); plugin = calloc (1, sizeof (ply_boot_splash_plugin_t)); - plugin->keyboard_input_buffer = ply_buffer_new (); return plugin; } @@ -86,8 +85,6 @@ destroy_plugin (ply_boot_splash_plugin_t *plugin) if (plugin == NULL) return; - ply_buffer_free (plugin->keyboard_input_buffer); - free (plugin); } @@ -176,29 +173,33 @@ on_keyboard_input (ply_boot_splash_plugin_t *plugin, const char *keyboard_input, size_t character_size) { - if (plugin->password_answer_handler != NULL) - { - if (character_size == 1 && keyboard_input[0] == '\r') - { - plugin->password_answer_handler (plugin->password_answer_data, - ply_buffer_get_bytes (plugin->keyboard_input_buffer)); - plugin->keyboard_input_is_hidden = false; - ply_buffer_clear (plugin->keyboard_input_buffer); - plugin->password_answer_handler = NULL; - write (STDOUT_FILENO, CLEAR_LINE_SEQUENCE, strlen (CLEAR_LINE_SEQUENCE)); - return; - } - } - - ply_buffer_append_bytes (plugin->keyboard_input_buffer, - keyboard_input, 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->password_answer_handler != NULL) + { + plugin->password_answer_handler (plugin->password_answer_data, + line); + plugin->keyboard_input_is_hidden = false; + plugin->password_answer_handler = NULL; + write (STDOUT_FILENO, CLEAR_LINE_SEQUENCE, strlen (CLEAR_LINE_SEQUENCE)); + } +} + + ply_boot_splash_plugin_interface_t * ply_boot_splash_plugin_get_interface (void) { @@ -211,7 +212,9 @@ ply_boot_splash_plugin_get_interface (void) .on_boot_output = on_boot_output, .hide_splash_screen = hide_splash_screen, .ask_for_password = ask_for_password, - .on_keyboard_input = on_keyboard_input + .on_keyboard_input = on_keyboard_input, + .on_backspace = on_backspace, + .on_enter = on_enter }; return &plugin_interface; diff --git a/src/splash-plugins/fedora-fade-in/fedora-fade-in.c b/src/splash-plugins/fedora-fade-in/fedora-fade-in.c index b599f80..88dd43f 100644 --- a/src/splash-plugins/fedora-fade-in/fedora-fade-in.c +++ b/src/splash-plugins/fedora-fade-in/fedora-fade-in.c @@ -87,8 +87,6 @@ struct _ply_boot_splash_plugin ply_boot_splash_password_answer_handler_t password_answer_handler; void *password_answer_data; - ply_buffer_t *keyboard_input_buffer; - double start_time; double now; }; @@ -102,8 +100,6 @@ create_plugin (void) plugin = calloc (1, sizeof (ply_boot_splash_plugin_t)); plugin->start_time = 0.0; - plugin->keyboard_input_buffer = ply_buffer_new (); - plugin->frame_buffer = ply_frame_buffer_new (NULL); plugin->logo_image = ply_image_new (PLYMOUTH_IMAGE_DIR "fedora-logo.png"); plugin->star_image = ply_image_new (PLYMOUTH_IMAGE_DIR "star.png"); @@ -190,8 +186,6 @@ destroy_plugin (ply_boot_splash_plugin_t *plugin) if (plugin == NULL) return; - ply_buffer_free (plugin->keyboard_input_buffer); - free_stars (plugin); ply_image_free (plugin->logo_image); ply_image_free (plugin->star_image); @@ -629,24 +623,27 @@ on_keyboard_input (ply_boot_splash_plugin_t *plugin, if (plugin->password_answer_handler == NULL) return; - if (character_size == 1 && keyboard_input[0] == '\r') - { - plugin->password_answer_handler (plugin->password_answer_data, - ply_buffer_get_bytes (plugin->keyboard_input_buffer)); - ply_buffer_clear (plugin->keyboard_input_buffer); - plugin->password_answer_handler = NULL; - - start_animation (plugin); - return; - } - - ply_buffer_append_bytes (plugin->keyboard_input_buffer, - keyboard_input, character_size); - plugin->entry->number_of_bullets++; draw_password_entry (plugin); } +void +on_backspace (ply_boot_splash_plugin_t *plugin) +{ + plugin->entry->number_of_bullets--; + draw_password_entry (plugin); +} + +void +on_enter (ply_boot_splash_plugin_t *plugin, + const char *text) +{ + plugin->password_answer_handler (plugin->password_answer_data, + text); + plugin->entry->number_of_bullets = 0; + start_animation (plugin); +} + ply_boot_splash_plugin_interface_t * ply_boot_splash_plugin_get_interface (void) { @@ -658,7 +655,9 @@ ply_boot_splash_plugin_get_interface (void) .update_status = update_status, .hide_splash_screen = hide_splash_screen, .ask_for_password = ask_for_password, - .on_keyboard_input = on_keyboard_input + .on_keyboard_input = on_keyboard_input, + .on_backspace = on_backspace, + .on_enter = on_enter }; return &plugin_interface; diff --git a/src/splash-plugins/text/text.c b/src/splash-plugins/text/text.c index 5198e93..bfa591a 100644 --- a/src/splash-plugins/text/text.c +++ b/src/splash-plugins/text/text.c @@ -52,7 +52,8 @@ #include -#define CLEAR_LINE_SEQUENCE "\033[2K" +#define CLEAR_LINE_SEQUENCE "\033[2K\r\n" +#define BACKSPACE "\b\033[0K" struct _ply_boot_splash_plugin { @@ -62,7 +63,6 @@ struct _ply_boot_splash_plugin ply_boot_splash_password_answer_handler_t password_answer_handler; void *password_answer_data; - ply_buffer_t *keyboard_input_buffer; uint32_t keyboard_input_is_hidden : 1; }; @@ -74,7 +74,6 @@ create_plugin (void) ply_trace ("creating plugin"); plugin = calloc (1, sizeof (ply_boot_splash_plugin_t)); - plugin->keyboard_input_buffer = ply_buffer_new (); plugin->console_fd = -1; return plugin; @@ -88,8 +87,6 @@ destroy_plugin (ply_boot_splash_plugin_t *plugin) if (plugin == NULL) return; - ply_buffer_free (plugin->keyboard_input_buffer); - free (plugin); } @@ -180,29 +177,32 @@ on_keyboard_input (ply_boot_splash_plugin_t *plugin, const char *keyboard_input, size_t character_size) { - if (plugin->password_answer_handler != NULL) - { - if (character_size == 1 && keyboard_input[0] == '\r') - { - plugin->password_answer_handler (plugin->password_answer_data, - ply_buffer_get_bytes (plugin->keyboard_input_buffer)); - plugin->keyboard_input_is_hidden = false; - ply_buffer_clear (plugin->keyboard_input_buffer); - plugin->password_answer_handler = NULL; - write (STDOUT_FILENO, CLEAR_LINE_SEQUENCE, strlen (CLEAR_LINE_SEQUENCE)); - return; - } - } - - ply_buffer_append_bytes (plugin->keyboard_input_buffer, - keyboard_input, 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->password_answer_handler != NULL) + { + plugin->password_answer_handler (plugin->password_answer_data, + line); + plugin->keyboard_input_is_hidden = false; + plugin->password_answer_handler = NULL; + write (STDOUT_FILENO, CLEAR_LINE_SEQUENCE, strlen (CLEAR_LINE_SEQUENCE)); + } +} + ply_boot_splash_plugin_interface_t * ply_boot_splash_plugin_get_interface (void) { @@ -214,7 +214,9 @@ ply_boot_splash_plugin_get_interface (void) .update_status = update_status, .hide_splash_screen = hide_splash_screen, .ask_for_password = ask_for_password, - .on_keyboard_input = on_keyboard_input + .on_keyboard_input = on_keyboard_input, + .on_backspace = on_backspace, + .on_enter = on_enter }; return &plugin_interface;