From 7e14cb94526e222061774e5ed3adfc9751a53928 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Fri, 23 May 2008 01:00:28 -0400 Subject: [PATCH] Move keyboard handling to window so we can do line editing The logic for line editing is a little complicated, so it's best not to duplicate it across all the plugins. Now we manage it all from the window. The plugins now access the various editing events via there vtable, but that's an extra layer of indirection that doesn't matter given that we pass the window to the plugins anyway. We should drop that and just have the plugins register for edit events directly. --- TODO | 2 +- src/ply-boot-splash-plugin.h | 4 ++ src/ply-boot-splash.c | 22 ++++++ src/ply-window.c | 71 +++++++++++++++++++ src/ply-window.h | 11 +++ src/splash-plugins/details/details.c | 49 +++++++------ .../fedora-fade-in/fedora-fade-in.c | 41 ++++++----- src/splash-plugins/text/text.c | 48 +++++++------ 8 files changed, 180 insertions(+), 68 deletions(-) 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;