]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
Keystroke sensitifity
authorCharles Brej <cbrej@cs.man.ac.uk>
Sun, 30 Nov 2008 13:30:02 +0000 (13:30 +0000)
committerCharles Brej <cbrej@cs.man.ac.uk>
Sun, 30 Nov 2008 13:30:02 +0000 (13:30 +0000)
16 files changed:
src/client/ply-boot-client.c
src/client/ply-boot-client.h
src/client/plymouth.c
src/libplybootsplash/ply-window.c
src/libplybootsplash/ply-window.h
src/main.c
src/plugins/splash/details/plugin.c
src/plugins/splash/fade-in/plugin.c
src/plugins/splash/pulser/plugin.c
src/plugins/splash/solar/plugin.c
src/plugins/splash/spinfinity/plugin.c
src/plugins/splash/text/plugin.c
src/ply-boot-protocol.h
src/ply-boot-server.c
src/ply-boot-server.h
src/ply-boot-splash.c

index cb9546bbba4b96dfbec9dca6bca7f15eefc33faf..43d550722b3b64750d7eff5e7ed6b6bf3dbbffea 100644 (file)
@@ -569,6 +569,34 @@ ply_boot_client_ask_daemon_for_cached_passwords (ply_boot_client_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_key_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_key_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,
index a4fc432ea3d36a5eb716c136e779eed7af8a76df..dcdf92400637ab9d70f7e60ae24dcbbddb4ef43b 100644 (file)
@@ -36,6 +36,10 @@ typedef void (* ply_boot_client_answer_handler_t) (void              *user_data,
                                                    const char        *answer,
                                                    ply_boot_client_t *client);
 
+typedef void (* ply_boot_client_key_answer_handler_t) (void              *user_data,
+                                                   const char        *answer,
+                                                   ply_boot_client_t *client);
+
 typedef void (* ply_boot_client_multiple_answers_handler_t) (void    *user_data,
                                                              const char * const *answers,
                                                              ply_boot_client_t *client);
@@ -68,11 +72,20 @@ void ply_boot_client_ask_daemon_for_password (ply_boot_client_t
                                               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_to_watch_for_keystroke (ply_boot_client_t                  *client,
+                                         const char *keys,
+                                         ply_boot_client_key_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_key_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,
index 6ad90eaf5285453581ebffea01fb7a51084c94b1..3b9fa8ccca4ccefa52e4f25b65d5f0f454c1aa83 100644 (file)
@@ -52,6 +52,15 @@ typedef struct
   int      number_of_tries_left;
 } answer_state_t;
 
+
+typedef struct
+{
+  state_t *state;
+  char    *command;
+  char    *prompt;
+  char    *keys;
+} key_answer_state_t;
+
 static char **
 split_string (const char *command,
               const char  delimiter)
@@ -147,20 +156,22 @@ answer_via_command (answer_state_t *answer_state,
 out:
   if (answer != NULL)
     close (command_input_sender_fd);
-  waitpid (pid, exit_status, 0); 
+  if (exit_status) waitpid (pid, exit_status, 0); 
+  else waitpid (pid, NULL, 0);
 
   return gave_answer;
 }
 
 static void
-on_answer_failure (answer_state_t *answer_state)
+on_answer_failure (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)
+           const char       *answer,
+           ply_boot_client_t *client)
 {
   int exit_status;
 
@@ -199,6 +210,28 @@ on_answer (answer_state_t   *answer_state,
   ply_event_loop_exit (answer_state->state->loop, WEXITSTATUS (exit_status));
 }
 
+
+static void
+on_key_reply (answer_state_t   *answer_state,
+           const char       *answer,
+           ply_boot_client_t *client)
+{
+  
+  if (answer_state->command != NULL)
+    {
+      bool command_started = false;
+
+      command_started = answer_via_command (answer_state, 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 (answer_state_t     *answer_state,
                      const char * const *answers)
@@ -241,13 +274,13 @@ on_multiple_answers (answer_state_t     *answer_state,
 }
 
 static void
-on_failure (state_t *state)
+on_failure (state_t *state, ply_boot_client_t *client)
 {
   ply_event_loop_exit (state->loop, 1);
 }
 
 static void
-on_success (state_t *state)
+on_success (state_t *state, ply_boot_client_t *client)
 {
   ply_event_loop_exit (state->loop, 0);
 }
@@ -320,6 +353,37 @@ on_password_request (state_t    *state,
     }
 }
 
+static void
+on_keystroke_request (state_t    *state,
+                     const char *command)
+{
+  char *prompt;
+  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_key_answer_handler_t)
+                                       on_key_reply,
+                                       (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 +422,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 +443,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 +461,17 @@ main (int    argc,
                                   PLY_COMMAND_OPTION_TYPE_INTEGER,
                                   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 +507,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,
@@ -520,6 +597,15 @@ main (int    argc,
                                                (ply_boot_client_response_handler_t)
                                                on_answer_failure, &answer_state);
     }
+  else if (ignore_keystroke)
+    {
+      ply_boot_client_ask_daemon_to_ignore_keystroke (state.client,
+                                           ignore_keystroke,
+                                           (ply_boot_client_key_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,
                                    (ply_boot_client_response_handler_t)
index d3c9e790ec75369aeb6b144221f7ea568460441f..564ade43e78713fbbe60af8ac7dfa0dbf64aca62 100644 (file)
@@ -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"
 
 #define TEXT_PALETTE_SIZE 48
 #endif
 
+typedef struct
+{
+  void *function;
+  void *user_data;
+} ply_window_callback_t;
+
 struct _ply_window
 {
   ply_event_loop_t *loop;
@@ -125,17 +132,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 +153,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,6 +229,7 @@ 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);
@@ -237,8 +243,12 @@ process_backspace (ply_window_t *window)
     {
       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_callback_t *callback = ply_list_node_get_data (node);
+          ply_window_backspace_handler_t backspace_handler = callback->function;
+          backspace_handler (callback->user_data);
+        }
     }
 }
 
@@ -257,8 +267,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 (mbrtowc (&key, keyboard_input, character_size, NULL) > 0)
     {
       switch (key)
         {
@@ -302,8 +313,13 @@ 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_callback_t *callback = ply_list_node_get_data (node);
+                ply_window_escape_handler_t escape_handler = callback->function;
+                escape_handler (callback->user_data);
+              }
+            
             ply_trace ("end escape key handler");
           return;
 
@@ -315,10 +331,12 @@ 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_callback_t *callback = ply_list_node_get_data (node);
+                ply_window_enter_handler_t enter_handler = callback->function;
+                enter_handler (callback->user_data, ply_buffer_get_bytes (window->line_buffer));
+              }
             ply_buffer_clear (window->line_buffer);
           return;
 
@@ -328,10 +346,14 @@ process_keyboard_input (ply_window_t *window,
           break;
         }
     }
-
-  if (window->keyboard_input_handler != NULL)
-    window->keyboard_input_handler (window->keyboard_input_handler_user_data,
+  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_callback_t *callback = ply_list_node_get_data (node);
+      ply_window_keyboard_input_handler_t keyboard_input_handler = callback->function;
+      
+      keyboard_input_handler (callback->user_data,
                                     keyboard_input, character_size);
+    }
 }
 
 static void
@@ -836,48 +858,130 @@ ply_window_free (ply_window_t *window)
   free (window);
 }
 
+ply_window_callback_t *
+ply_window_callback_new(void* function, void* user_data)
+{
+  ply_window_callback_t *callback = calloc (1, sizeof (ply_window_callback_t));
+  callback->function = function;
+  callback->user_data = user_data;
+}
+
 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_callback_t *callback = ply_window_callback_new(input_handler, user_data);
+  ply_list_append_data (window->keyboard_input_handler_list, callback);
+}
 
-  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_callback_t *callback = ply_list_node_get_data (node);
+      if (callback->function == input_handler)
+        {
+          free(callback);
+          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_callback_t *callback = ply_window_callback_new(backspace_handler, user_data);
+  ply_list_append_data (window->backspace_handler_list, callback);
+}
+
 
-  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_callback_t *callback = ply_list_node_get_data (node);
+      if (callback->function == backspace_handler)
+        {
+          free(callback);
+          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_callback_t *callback = ply_window_callback_new(escape_handler, user_data);
+  ply_list_append_data (window->escape_handler_list, callback);
+}
+
 
-  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_callback_t *callback = ply_list_node_get_data (node);
+      if (callback->function == escape_handler)
+        {
+          free(callback);
+          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_callback_t *callback = ply_window_callback_new(enter_handler, user_data);
+  ply_list_append_data (window->enter_handler_list, callback);
+}
+
 
-  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_callback_t *callback = ply_list_node_get_data (node);
+      if (callback->function == enter_handler)
+        {
+          free(callback);
+          ply_list_remove_node (window->enter_handler_list, node);
+          return;
+        }
+    }
 }
 
 void
@@ -965,7 +1069,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);
 
index a6b2caa5a596f69dd4e9e8ecbb03b79b21efd55d..7d4ebff5a06e9a76d827df49a66315568eb8378a 100644 (file)
@@ -76,24 +76,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,
+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_set_backspace_handler (ply_window_t *window,
+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_set_escape_handler (ply_window_t *window,
+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_set_enter_handler (ply_window_t *window,
+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_set_draw_handler (ply_window_t *window,
+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_set_erase_handler (ply_window_t *window,
+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);
index 6afffc43ad2abac3a1c618a506a1ba5b6ab2808b..bbc57deaa114af95d3a4aee4db0f352b893fd264 100644 (file)
 #define PLY_MAX_COMMAND_LINE_SIZE 512
 #endif
 
+typedef struct 
+{
+  const char    *keys;
+  ply_trigger_t *trigger;
+} ply_keystroke_trigger_t;
+
 typedef struct
 {
   ply_event_loop_t *loop;
@@ -57,6 +63,7 @@ typedef struct
   ply_terminal_session_t *session;
   ply_buffer_t *boot_buffer;
   ply_progress_t *progress;
+  ply_list_t *keystroke_triggers;
   long ptmx;
 
   char kernel_command_line[PLY_MAX_COMMAND_LINE_SIZE];
@@ -160,6 +167,41 @@ on_ask_for_password (state_t      *state,
                                     prompt, answer);
 }
 
+
+static void
+on_watch_for_keystroke (state_t      *state,
+                     const char    *keys,
+                     ply_trigger_t *trigger)
+{
+  ply_keystroke_trigger_t *keystroke_trigger =
+                                  calloc (1, sizeof (ply_keystroke_trigger_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))
+    {
+      ply_keystroke_trigger_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;
+        }
+    }
+}
+
+
 static void
 on_newroot (state_t    *state,
              const char *root_dir)
@@ -462,6 +504,8 @@ 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_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,
@@ -505,6 +549,27 @@ on_escape_pressed (state_t *state)
     }
 }
 
+static void
+on_keyboard_input (state_t                  *state,
+                   const char               *keyboard_input,
+                   size_t                    character_size)
+{
+  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))
+    {
+      ply_keystroke_trigger_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);
+          return;
+        }
+    }
+  return;
+}
+
 static ply_window_t *
 create_window (state_t    *state,
                const char *tty_name)
@@ -542,8 +607,11 @@ 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)
+          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);
         }
       node = next_node;
     }
@@ -788,6 +856,7 @@ initialize_environment (state_t *state)
   check_logging (state);
 
   state->windows = ply_list_new ();
+  state->keystroke_triggers = ply_list_new ();
   check_for_consoles (state);
 
   if (state->console != NULL)
index b4fc3e6d3a3f97c2f9976f0c64a600ea638684f9..f7259fca2074ca6ad7099d2f9fe442aa2509ec32 100644 (file)
@@ -212,15 +212,15 @@ initialize_window (ply_window_t             *window,
 
   ply_window_set_mode (window, PLY_WINDOW_MODE_TEXT);
 
-  ply_window_set_keyboard_input_handler (window,
-                                         (ply_window_keyboard_input_handler_t)
-                                         on_keyboard_input, plugin);
-  ply_window_set_backspace_handler (window,
-                                    (ply_window_backspace_handler_t)
-                                    on_backspace, plugin);
-  ply_window_set_enter_handler (window,
-                                (ply_window_enter_handler_t)
-                                on_enter, plugin);
+   ply_window_add_keyboard_input_handler (window,
+                                          (ply_window_keyboard_input_handler_t)
+                                          on_keyboard_input, plugin);
+   ply_window_add_backspace_handler (window,
+                                     (ply_window_backspace_handler_t)
+                                     on_backspace, plugin);
+   ply_window_add_enter_handler (window,
+                                 (ply_window_enter_handler_t)
+                                 on_enter, plugin);
 
   interface = ply_boot_splash_plugin_get_interface ();
 
@@ -231,9 +231,9 @@ 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
index e5101ad708cab21b0ed33f32ceaf4bdaae0f9d3f..dad17aa8a6ff1ac781088557071629993b93c2eb 100644 (file)
@@ -470,13 +470,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);
 
@@ -619,9 +619,12 @@ hide_splash_screen (ply_boot_splash_plugin_t *plugin,
       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);
+    (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)
     {
index d938cff1bd97cf227a010d991a104b0795de0241..c2d4352e1ef74c3c40db8812cf444e8597705763 100644 (file)
@@ -240,13 +240,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,
@@ -302,9 +302,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);
 
index 293ae78c23bfcbbded72c540ca285f73fe30b8d6..bd1e56813975fbae8703edbd7377c4eaac462cb8 100644 (file)
@@ -1351,13 +1351,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);
 
@@ -1455,9 +1455,9 @@ hide_splash_screen (ply_boot_splash_plugin_t *plugin,
       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);
 
index b63e9b1a09a493d79234ac6b32309f18314be44b..e94c89860d24fee97ed238388be6e29847e9bda5 100644 (file)
@@ -362,13 +362,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);
 
@@ -464,9 +464,9 @@ hide_splash_screen (ply_boot_splash_plugin_t *plugin,
       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);
 
index f28fdebc68fbea63fae3bd090718601260c14b91..69e0e87d00a2b5995e016fcc5fb038d4a898241b 100644 (file)
@@ -244,13 +244,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,
@@ -326,9 +326,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);
 
index f31b181a0ccd0aac7adbfeff883e31a4fb858afa..a8a27b10ddd3a5d3e4d09257580f270d0eda881f 100644 (file)
@@ -29,6 +29,8 @@
 #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_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"
index ff6ef29e765bcaabd2e7c83360e35c720ade608e..3a9d607739b7a357525548fb113401b9b8768cbb 100644 (file)
@@ -45,6 +45,7 @@ typedef struct
   ply_boot_server_t *server;
 } ply_boot_connection_t;
 
+
 struct _ply_boot_server
 {
   ply_event_loop_t *loop;
@@ -59,6 +60,8 @@ 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_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,8 @@ 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_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 +90,8 @@ 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->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;
@@ -248,6 +255,44 @@ ply_boot_connection_on_password_answer (ply_boot_connection_t *connection,
 
 }
 
+static void
+ply_boot_connection_on_keystroke_answer (ply_boot_connection_t *connection,
+                                        const char            *key)
+{
+
+  uint8_t size;
+
+  /* splash plugin isn't able to ask for password,
+   * punt to client
+   */
+  if (key == NULL)
+    {
+      if (!ply_write (connection->fd,
+                      PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NO_ANSWER,
+                      strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NO_ANSWER)))
+        ply_error ("could not write bytes: %m");
+    }
+  else
+    {
+      /* FIXME: support up to 4 billion (probably fine)
+      */
+      if (strlen (key) > 255)
+          ply_error ("password to long to fit in buffer");
+
+      size = (uint8_t) strlen (key);
+
+      if (!ply_write (connection->fd,
+                      PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER,
+                      strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER)) ||
+          !ply_write (connection->fd,
+                      &size, sizeof (uint8_t)) ||
+          !ply_write (connection->fd,
+                      key, size))
+          ply_error ("could not write bytes: %m");
+    }
+
+}
+
 static void
 ply_boot_connection_on_request (ply_boot_connection_t *connection)
 {
@@ -397,6 +442,33 @@ ply_boot_connection_on_request (ply_boot_connection_t *connection)
       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)
@@ -557,12 +629,29 @@ on_error (ply_event_loop_t *loop)
   printf ("got error starting service\n");
 }
 
-static char *
+static void
 on_ask_for_password (ply_event_loop_t *loop)
 {
   printf ("got password request, returning 'password'...\n");
 
-  return strdup ("password");
+  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
@@ -579,6 +668,8 @@ 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_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,
index e685ad913290cafaf334fd72f8ac078b4d8df819..1c5c376bacd3e3deda7fd650f294557d2d9b8bce 100644 (file)
@@ -54,6 +54,15 @@ typedef void (* ply_boot_server_ask_for_password_handler_t) (void              *
                                                              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 +76,8 @@ 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_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,
index b6ecf433624475d7b1c609a50f23816f4adfa807..02fbba19da1a2a70d2ea72c04500ca28f6986223 100644 (file)
@@ -458,7 +458,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 ();