]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
space-flares: Use new interfaces in ply-boot-splash for ply-kmsg-reader, and use...
authorn3rdopolis <bluescreen_avenger@verizon.net>
Mon, 20 Mar 2023 02:42:41 +0000 (22:42 -0400)
committernerdopolis <bluescreen_avenger@verizon.net>
Thu, 1 Jun 2023 02:45:11 +0000 (22:45 -0400)
src/plugins/splash/space-flares/plugin.c

index 2a942229f9f09d5c7a9fd71d1bf6e3de235a0f95..2fcff6dc91d5388a9e5cb931c54518d0958280f1 100644 (file)
 #include "ply-pixel-display.h"
 #include "ply-trigger.h"
 #include "ply-utils.h"
+#include "ply-kmsg-reader.h"
+#include "ply-console-viewer.h"
+#include "ply-terminal-emulator.h"
 
 #ifndef FRAMES_PER_SECOND
 #define FRAMES_PER_SECOND 40
 #endif
 
+#define CONSOLE_POLLS_PER_SECOND 4
+
 #define FLARE_FRAMES_PER_SECOND 20
 #define BG_STARS_FRAMES_PER_SECOND 10
 #define FLARE_COUNT 30
@@ -168,6 +173,8 @@ typedef struct
         ply_list_t               *sprites;
         ply_rectangle_t           box_area, lock_area, logo_area;
         ply_image_t              *scaled_background_image;
+
+        ply_console_viewer_t     *console_viewer;
 } view_t;
 
 struct _ply_boot_splash_plugin
@@ -202,10 +209,30 @@ struct _ply_boot_splash_plugin
         uint32_t                       root_is_mounted : 1;
         uint32_t                       is_visible : 1;
         uint32_t                       is_animating : 1;
+
+        char                          *monospace_font;
+        uint32_t                       has_new_console_messages : 1;
+        uint32_t                       plugin_console_messages_updating : 1;
+        uint32_t                       should_show_console_messages : 1;
+        ply_list_t                    *console_messages;
+        ply_buffer_t                  *boot_buffer;
+        ply_terminal_emulator_t       *terminal_emulator;
+        uint32_t                       console_text_color;
 };
 
 ply_boot_splash_plugin_interface_t *ply_boot_splash_plugin_get_interface (void);
 static void detach_from_event_loop (ply_boot_splash_plugin_t *plugin);
+static bool validate_input (ply_boot_splash_plugin_t *plugin,
+                            const char               *entry_text,
+                            const char               *add_text);
+static void on_boot_output (ply_boot_splash_plugin_t *plugin,
+                            const char               *output,
+                            size_t                    size);
+static void toggle_console_messages (ply_boot_splash_plugin_t *plugin);
+static void display_console_messages (ply_boot_splash_plugin_t *plugin);
+static void on_update_console_messages (ply_boot_splash_plugin_t *plugin);
+static void hide_console_messages (ply_boot_splash_plugin_t *plugin);
+static void unhide_console_messages (ply_boot_splash_plugin_t *plugin);
 
 static view_t *
 view_new (ply_boot_splash_plugin_t *plugin,
@@ -223,6 +250,10 @@ view_new (ply_boot_splash_plugin_t *plugin,
 
         view->sprites = ply_list_new ();
 
+        view->console_viewer = ply_console_viewer_new (view->display, plugin->monospace_font);
+        ply_console_viewer_attach_console_messages (view->console_viewer, plugin->console_messages);
+        ply_console_viewer_set_text_color (view->console_viewer, plugin->console_text_color);
+
         return view;
 }
 
@@ -237,6 +268,8 @@ view_free (view_t *view)
         view_free_sprites (view);
         ply_list_free (view->sprites);
 
+        ply_console_viewer_free (view->console_viewer);
+
         ply_image_free (view->scaled_background_image);
 
         free (view);
@@ -541,6 +574,18 @@ create_plugin (ply_key_file_t *key_file)
         plugin->progress_barimage = ply_image_new (image_path);
         free (image_path);
 #endif
+
+        /* Likely only able to set the font if the font is in the initrd */
+        plugin->monospace_font = ply_key_file_get_value (key_file, "two-step", "MonospaceFont");
+
+        if (plugin->monospace_font == NULL)
+                plugin->monospace_font = strdup ("monospace 9");
+
+        plugin->console_text_color =
+                ply_key_file_get_long (key_file, "two-step",
+                                       "ConsoleLogTextColor",
+                                       PLY_CONSOLE_VIEWER_LOG_TEXT_COLOR);
+
         plugin->state = PLY_BOOT_SPLASH_DISPLAY_NORMAL;
         plugin->progress = 0;
         plugin->progress_target = -1;
@@ -561,9 +606,14 @@ destroy_plugin (ply_boot_splash_plugin_t *plugin)
         free (plugin->image_dir);
 
         if (plugin->loop != NULL) {
+                ply_event_loop_stop_watching_for_timeout (plugin->loop,
+                                                          (ply_event_loop_timeout_handler_t)
+                                                          on_update_console_messages, plugin);
+
                 ply_event_loop_stop_watching_for_exit (plugin->loop, (ply_event_loop_exit_handler_t)
                                                        detach_from_event_loop,
                                                        plugin);
+
                 detach_from_event_loop (plugin);
         }
 
@@ -583,6 +633,8 @@ destroy_plugin (ply_boot_splash_plugin_t *plugin)
         ply_image_free (plugin->progress_barimage);
 #endif
 
+        free (plugin->monospace_font);
+
         free_views (plugin);
 
         free (plugin);
@@ -1346,6 +1398,10 @@ on_draw (view_t             *view,
         ply_label_draw_area (view->message_label,
                              pixel_buffer,
                              x, y, width, height);
+
+        if (plugin->plugin_console_messages_updating == false) {
+                ply_console_viewer_draw_area (view->console_viewer, pixel_buffer, x, y, width, height);
+        }
 }
 
 static void
@@ -1629,6 +1685,12 @@ show_splash_screen (ply_boot_splash_plugin_t *plugin,
         plugin->loop = loop;
         plugin->mode = mode;
 
+        if (boot_buffer) {
+                plugin->boot_buffer = boot_buffer;
+
+                ply_terminal_emulator_convert_boot_buffer (plugin->terminal_emulator, plugin->boot_buffer);
+        }
+
         ply_trace ("loading logo image");
         if (!ply_image_load (plugin->logo_image))
                 return false;
@@ -1676,6 +1738,11 @@ show_splash_screen (ply_boot_splash_plugin_t *plugin,
 
         start_animation (plugin);
 
+        ply_event_loop_watch_for_timeout (loop,
+                                          1.0 / CONSOLE_POLLS_PER_SECOND,
+                                          (ply_event_loop_timeout_handler_t)
+                                          on_update_console_messages, plugin);
+
         plugin->is_visible = true;
 
         return true;
@@ -1697,6 +1764,10 @@ hide_splash_screen (ply_boot_splash_plugin_t *plugin,
         if (plugin->loop != NULL) {
                 stop_animation (plugin);
 
+                ply_event_loop_stop_watching_for_timeout (plugin->loop,
+                                                          (ply_event_loop_timeout_handler_t)
+                                                          on_update_console_messages, plugin);
+
                 ply_event_loop_stop_watching_for_exit (plugin->loop, (ply_event_loop_exit_handler_t)
                                                        detach_from_event_loop,
                                                        plugin);
@@ -1795,7 +1866,12 @@ display_normal (ply_boot_splash_plugin_t *plugin)
                 hide_prompt (plugin);
 
         plugin->state = PLY_BOOT_SPLASH_DISPLAY_NORMAL;
-        start_animation (plugin);
+        if (plugin->should_show_console_messages == false) {
+                start_animation (plugin);
+        } else {
+                stop_animation (plugin);
+        }
+
         redraw_views (plugin);
         unpause_views (plugin);
 }
@@ -1837,6 +1913,112 @@ display_message (ply_boot_splash_plugin_t *plugin,
         show_message (plugin, message);
 }
 
+static bool
+validate_input (ply_boot_splash_plugin_t *plugin,
+                const char               *entry_text,
+                const char               *add_text)
+{
+        if (strcmp (add_text, "\e") == 0) {
+                toggle_console_messages (plugin);
+                return false;
+        }
+
+        return true;
+}
+
+static void
+toggle_console_messages (ply_boot_splash_plugin_t *plugin)
+{
+        if (plugin->should_show_console_messages == true) {
+                plugin->should_show_console_messages = false;
+                hide_console_messages (plugin);
+        } else {
+                plugin->should_show_console_messages = true;
+                unhide_console_messages (plugin);
+        }
+}
+
+static void
+on_update_console_messages (ply_boot_splash_plugin_t *plugin)
+{
+        if (plugin->loop != NULL) {
+                ply_event_loop_watch_for_timeout (plugin->loop,
+                                                  1.0 / CONSOLE_POLLS_PER_SECOND,
+                                                  (ply_event_loop_timeout_handler_t)
+                                                  on_update_console_messages, plugin);
+        }
+
+        if (plugin->has_new_console_messages == false)
+                return;
+
+        plugin->has_new_console_messages = false;
+
+        if (plugin->should_show_console_messages == false)
+                return;
+
+        display_console_messages (plugin);
+}
+
+static void
+display_console_messages (ply_boot_splash_plugin_t *plugin)
+{
+        ply_list_node_t *node;
+        view_t *view;
+
+        pause_views (plugin);
+
+        plugin->plugin_console_messages_updating = true;
+        node = ply_list_get_first_node (plugin->views);
+        while (node != NULL) {
+                view = ply_list_node_get_data (node);
+                ply_console_viewer_show (view->console_viewer, view->display);
+                node = ply_list_get_next_node (plugin->views, node);
+        }
+        plugin->plugin_console_messages_updating = false;
+
+        redraw_views (plugin);
+        unpause_views (plugin);
+}
+
+static void
+unhide_console_messages (ply_boot_splash_plugin_t *plugin)
+{
+        plugin->should_show_console_messages = true;
+        stop_animation (plugin);
+        display_console_messages (plugin);
+}
+
+static void
+hide_console_messages (ply_boot_splash_plugin_t *plugin)
+{
+        ply_list_node_t *node;
+        view_t *view;
+
+        plugin->should_show_console_messages = false;
+
+        plugin->plugin_console_messages_updating = true;
+        node = ply_list_get_first_node (plugin->views);
+        while (node != NULL) {
+                view = ply_list_node_get_data (node);
+                ply_console_viewer_hide (view->console_viewer);
+                node = ply_list_get_next_node (plugin->views, node);
+        }
+        plugin->plugin_console_messages_updating = false;
+        if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_NORMAL)
+                start_animation (plugin);
+}
+
+static void
+on_boot_output (ply_boot_splash_plugin_t *plugin,
+                const char               *output,
+                size_t                    size)
+{
+        plugin->has_new_console_messages = true;
+        char *output_text = strndup (output, size);
+
+        ply_terminal_emulator_parse_lines (plugin->terminal_emulator, output_text);
+}
+
 ply_boot_splash_plugin_interface_t *
 ply_boot_splash_plugin_get_interface (void)
 {
@@ -1856,6 +2038,8 @@ ply_boot_splash_plugin_get_interface (void)
                 .display_password     = display_password,
                 .display_question     = display_question,
                 .display_message      = display_message,
+                .on_boot_output       = on_boot_output,
+                .validate_input       = validate_input,
         };
 
         return &plugin_interface;