]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
script: Get the messages from the console and ply-kmsg-reader, and use ply-terminal...
authornerdopolis <bluescreen_avenger@verizon.net>
Tue, 26 Dec 2023 23:19:52 +0000 (18:19 -0500)
committerRay Strode <halfline@gmail.com>
Fri, 8 Mar 2024 13:23:02 +0000 (13:23 +0000)
src/plugins/splash/script/plugin.c
src/plugins/splash/script/script-lib-consoleviewer.script [new file with mode: 0644]
src/plugins/splash/script/script-lib-sprite.c
src/plugins/splash/script/script-lib-sprite.h

index 2ff10292fb05447bf824e2fdbddd21976d8facf4..d60ed4a2d834f6faf40481dda38d3e141d2de9de 100644 (file)
@@ -21,6 +21,7 @@
  * Written by: Charlie Brej <cbrej@cs.man.ac.uk>
  *             Ray Strode <rstrode@redhat.com>
  */
+#include "config.h"
 
 #include <assert.h>
 #include <errno.h>
 #define FRAMES_PER_SECOND 50
 #endif
 
+typedef enum
+{
+        PLY_BOOT_SPLASH_DISPLAY_NORMAL,
+        PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY,
+        PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY
+} ply_boot_splash_display_type_t;
+
 struct _ply_boot_splash_plugin
 {
-        ply_event_loop_t           *loop;
-        ply_boot_splash_mode_t      mode;
-        ply_list_t                 *displays;
-        ply_keyboard_t             *keyboard;
+        ply_event_loop_t              *loop;
+        ply_boot_splash_mode_t         mode;
+        ply_list_t                    *displays;
+        ply_keyboard_t                *keyboard;
+
+        ply_boot_splash_display_type_t state;
+        char                          *script_filename;
+        char                          *image_dir;
 
-        char                       *script_filename;
-        char                       *image_dir;
+        ply_list_t                    *script_env_vars;
+        script_op_t                   *script_main_op;
 
-        ply_list_t                 *script_env_vars;
-        script_op_t                *script_main_op;
+        script_state_t                *script_state;
+        script_lib_sprite_data_t      *script_sprite_lib;
+        script_lib_image_data_t       *script_image_lib;
+        script_lib_plymouth_data_t    *script_plymouth_lib;
+        script_lib_math_data_t        *script_math_lib;
+        script_lib_string_data_t      *script_string_lib;
 
-        script_state_t             *script_state;
-        script_lib_sprite_data_t   *script_sprite_lib;
-        script_lib_image_data_t    *script_image_lib;
-        script_lib_plymouth_data_t *script_plymouth_lib;
-        script_lib_math_data_t     *script_math_lib;
-        script_lib_string_data_t   *script_string_lib;
+        uint32_t                       is_animating : 1;
 
-        uint32_t                    is_animating : 1;
+        char                          *monospace_font;
+        uint32_t                       should_show_console_messages : 1;
+        ply_buffer_t                  *boot_buffer;
+        uint32_t                       console_text_color;
 };
 
 typedef struct
@@ -103,6 +117,37 @@ ply_boot_splash_plugin_interface_t *ply_boot_splash_plugin_get_interface (void);
 static void on_keyboard_input (ply_boot_splash_plugin_t *plugin,
                                const char               *keyboard_input,
                                size_t                    character_size);
+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 hide_console_messages (ply_boot_splash_plugin_t *plugin);
+static void unhide_console_messages (ply_boot_splash_plugin_t *plugin);
+
+static void
+show_prompt_on_console_viewer (ply_boot_splash_plugin_t *plugin,
+                               const char               *prompt,
+                               const char               *entry_text,
+                               int                       number_of_bullets)
+{
+        if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_NORMAL)
+                script_lib_sprite_console_viewer_print (plugin->script_sprite_lib, "\n");
+
+        script_lib_sprite_console_viewer_clear_line (plugin->script_sprite_lib);
+
+        script_lib_sprite_console_viewer_print (plugin->script_sprite_lib, prompt);
+
+        script_lib_sprite_console_viewer_print (plugin->script_sprite_lib, ": ");
+        if (entry_text)
+                script_lib_sprite_console_viewer_print (plugin->script_sprite_lib, "%s", entry_text);
+
+        for (int i = 0; i < number_of_bullets; i++) {
+                script_lib_sprite_console_viewer_print (plugin->script_sprite_lib, " ");
+        }
+
+        script_lib_sprite_console_viewer_print (plugin->script_sprite_lib, "_");
+}
 
 static void
 pause_displays (ply_boot_splash_plugin_t *plugin)
@@ -175,10 +220,24 @@ create_plugin (ply_key_file_t *key_file)
                                                           "script",
                                                           "ScriptFile");
 
+        plugin->state = PLY_BOOT_SPLASH_DISPLAY_NORMAL;
+
         plugin->script_env_vars = ply_list_new ();
         ply_key_file_foreach_entry (key_file, add_script_env_var, plugin->script_env_vars);
 
+        /* Likely only able to set the font if the font is in the initrd */
+        plugin->monospace_font = ply_key_file_get_value (key_file, "script", "MonospaceFont");
+
+        if (plugin->monospace_font == NULL)
+                plugin->monospace_font = strdup ("monospace 10");
+
+        plugin->console_text_color =
+                ply_key_file_get_long (key_file, "script",
+                                       "ConsoleLogTextColor",
+                                       PLY_CONSOLE_VIEWER_LOG_TEXT_COLOR);
+
         plugin->displays = ply_list_new ();
+
         return plugin;
 }
 
@@ -193,6 +252,7 @@ destroy_plugin (ply_boot_splash_plugin_t *plugin)
 
         if (plugin->loop != NULL) {
                 stop_animation (plugin);
+
                 ply_event_loop_stop_watching_for_exit (plugin->loop,
                                                        (ply_event_loop_exit_handler_t)
                                                        detach_from_event_loop,
@@ -211,6 +271,7 @@ destroy_plugin (ply_boot_splash_plugin_t *plugin)
         ply_list_free (plugin->script_env_vars);
         free (plugin->script_filename);
         free (plugin->image_dir);
+        free (plugin->monospace_font);
         free (plugin);
 }
 
@@ -229,6 +290,7 @@ on_timeout (ply_boot_splash_plugin_t *plugin)
                                         plugin->script_plymouth_lib);
 
         pause_displays (plugin);
+        script_lib_sprite_set_needs_redraw (plugin->script_sprite_lib);
         script_lib_sprite_refresh (plugin->script_sprite_lib);
         unpause_displays (plugin);
 }
@@ -247,6 +309,7 @@ on_boot_progress (ply_boot_splash_plugin_t *plugin,
 static bool
 start_script_animation (ply_boot_splash_plugin_t *plugin)
 {
+        ply_list_t *displays;
         ply_list_node_t *node;
         script_obj_t *target_obj;
         script_obj_t *value_obj;
@@ -277,6 +340,32 @@ start_script_animation (ply_boot_splash_plugin_t *plugin)
         plugin->script_math_lib = script_lib_math_setup (plugin->script_state);
         plugin->script_string_lib = script_lib_string_setup (plugin->script_state);
 
+
+        displays = script_lib_get_displays (plugin->script_sprite_lib);
+        node = ply_list_get_first_node (displays);
+        while (node != NULL) {
+                script_lib_display_t *display;
+                ply_list_node_t *next_node;
+
+                display = ply_list_node_get_data (node);
+                next_node = ply_list_get_next_node (displays, node);
+
+                if (ply_console_viewer_preferred ()) {
+                        display->console_viewer = ply_console_viewer_new (display->pixel_display, plugin->monospace_font);
+                        ply_console_viewer_set_text_color (display->console_viewer, plugin->console_text_color);
+
+                        if (plugin->boot_buffer)
+                                ply_console_viewer_convert_boot_buffer (display->console_viewer, plugin->boot_buffer);
+                } else {
+                        display->console_viewer = NULL;
+                }
+
+                node = next_node;
+        }
+
+        plugin->script_sprite_lib->monospace_font = plugin->monospace_font;
+        plugin->script_sprite_lib->boot_buffer = plugin->boot_buffer;
+
         ply_trace ("executing script file");
         script_return_t ret = script_execute (plugin->script_state,
                                               plugin->script_main_op);
@@ -417,6 +506,8 @@ show_splash_screen (ply_boot_splash_plugin_t *plugin,
                     ply_buffer_t             *boot_buffer,
                     ply_boot_splash_mode_t    mode)
 {
+        ply_list_node_t *node;
+
         assert (plugin != NULL);
 
         if (ply_list_get_length (plugin->displays) == 0) {
@@ -427,10 +518,15 @@ show_splash_screen (ply_boot_splash_plugin_t *plugin,
         plugin->loop = loop;
         plugin->mode = mode;
 
+        if (boot_buffer && ply_console_viewer_preferred ())
+                plugin->boot_buffer = boot_buffer;
+
         ply_event_loop_watch_for_exit (loop, (ply_event_loop_exit_handler_t)
                                        detach_from_event_loop,
                                        plugin);
 
+        plugin->should_show_console_messages = false;
+
         ply_trace ("starting boot animation");
         return start_animation (plugin);
 }
@@ -488,8 +584,19 @@ static void
 display_normal (ply_boot_splash_plugin_t *plugin)
 {
         pause_displays (plugin);
+
+        if (plugin->state != PLY_BOOT_SPLASH_DISPLAY_NORMAL) {
+                if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY)
+                        script_lib_sprite_console_viewer_clear_line (plugin->script_sprite_lib);
+
+                script_lib_sprite_console_viewer_print (plugin->script_sprite_lib, "\n");
+        }
+
         script_lib_plymouth_on_display_normal (plugin->script_state,
                                                plugin->script_plymouth_lib);
+
+        script_lib_sprite_refresh (plugin->script_sprite_lib);
+        plugin->state = PLY_BOOT_SPLASH_DISPLAY_NORMAL;
         unpause_displays (plugin);
 }
 
@@ -498,11 +605,14 @@ display_password (ply_boot_splash_plugin_t *plugin,
                   const char               *prompt,
                   int                       bullets)
 {
+        plugin->state = PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY;
         pause_displays (plugin);
+        show_prompt_on_console_viewer (plugin, prompt, NULL, bullets);
         script_lib_plymouth_on_display_password (plugin->script_state,
                                                  plugin->script_plymouth_lib,
                                                  prompt,
                                                  bullets);
+        script_lib_sprite_refresh (plugin->script_sprite_lib);
         unpause_displays (plugin);
 }
 
@@ -511,11 +621,14 @@ display_question (ply_boot_splash_plugin_t *plugin,
                   const char               *prompt,
                   const char               *entry_text)
 {
+        plugin->state = PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY;
         pause_displays (plugin);
+        show_prompt_on_console_viewer (plugin, prompt, entry_text, -1);
         script_lib_plymouth_on_display_question (plugin->script_state,
                                                  plugin->script_plymouth_lib,
                                                  prompt,
                                                  entry_text);
+        script_lib_sprite_refresh (plugin->script_sprite_lib);
         unpause_displays (plugin);
 }
 
@@ -524,10 +637,19 @@ validate_input (ply_boot_splash_plugin_t *plugin,
                 const char               *entry_text,
                 const char               *add_text)
 {
-        return script_lib_plymouth_on_validate_input (plugin->script_state,
-                                                      plugin->script_plymouth_lib,
-                                                      entry_text,
-                                                      add_text);
+        bool ret = script_lib_plymouth_on_validate_input (plugin->script_state,
+                                                          plugin->script_plymouth_lib,
+                                                          entry_text,
+                                                          add_text);
+        if (!ply_console_viewer_preferred ())
+                return true;
+
+        if (strcmp (add_text, "\e") == 0) {
+                toggle_console_messages (plugin);
+                return false;
+        }
+
+        return ret;
 }
 
 static void
@@ -542,6 +664,7 @@ display_prompt (ply_boot_splash_plugin_t *plugin,
                                                prompt,
                                                entry_text,
                                                is_secret);
+        script_lib_sprite_refresh (plugin->script_sprite_lib);
         unpause_displays (plugin);
 }
 
@@ -553,6 +676,9 @@ display_message (ply_boot_splash_plugin_t *plugin,
         script_lib_plymouth_on_display_message (plugin->script_state,
                                                 plugin->script_plymouth_lib,
                                                 message);
+        script_lib_sprite_console_viewer_print (plugin->script_sprite_lib,
+                                                message);
+        script_lib_sprite_refresh (plugin->script_sprite_lib);
         unpause_displays (plugin);
 }
 
@@ -564,9 +690,69 @@ hide_message (ply_boot_splash_plugin_t *plugin,
         script_lib_plymouth_on_hide_message (plugin->script_state,
                                              plugin->script_plymouth_lib,
                                              message);
+        script_lib_sprite_refresh (plugin->script_sprite_lib);
+        unpause_displays (plugin);
+}
+
+static void
+toggle_console_messages (ply_boot_splash_plugin_t *plugin)
+{
+        if (plugin->should_show_console_messages) {
+                plugin->should_show_console_messages = false;
+                hide_console_messages (plugin);
+        } else {
+                unhide_console_messages (plugin);
+        }
+}
+
+static void
+display_console_messages (ply_boot_splash_plugin_t *plugin)
+{
+        pause_displays (plugin);
+        script_lib_sprite_console_viewer_show (plugin->script_sprite_lib);
         unpause_displays (plugin);
 }
 
+static void
+unhide_console_messages (ply_boot_splash_plugin_t *plugin)
+{
+        plugin->should_show_console_messages = true;
+        display_console_messages (plugin);
+}
+
+static void
+hide_console_messages (ply_boot_splash_plugin_t *plugin)
+{
+        plugin->should_show_console_messages = false;
+        script_lib_sprite_console_viewer_hide (plugin->script_sprite_lib);
+}
+
+static void
+on_boot_output (ply_boot_splash_plugin_t *plugin,
+                const char               *output,
+                size_t                    size)
+{
+        ply_list_t *displays;
+        ply_list_node_t *node;
+
+        if (!ply_console_viewer_preferred ())
+                return;
+
+        displays = script_lib_get_displays (plugin->script_sprite_lib);
+        node = ply_list_get_first_node (displays);
+        while (node != NULL) {
+                script_lib_display_t *display;
+                ply_list_node_t *next_node;
+
+                display = ply_list_node_get_data (node);
+                next_node = ply_list_get_next_node (displays, node);
+
+                ply_console_viewer_write (display->console_viewer, output, size);
+
+                node = next_node;
+        }
+}
+
 ply_boot_splash_plugin_interface_t *
 ply_boot_splash_plugin_get_interface (void)
 {
@@ -591,6 +777,7 @@ ply_boot_splash_plugin_get_interface (void)
                 .display_prompt       = display_prompt,
                 .display_message      = display_message,
                 .hide_message         = hide_message,
+                .on_boot_output       = on_boot_output,
                 .validate_input       = validate_input,
         };
 
diff --git a/src/plugins/splash/script/script-lib-consoleviewer.script b/src/plugins/splash/script/script-lib-consoleviewer.script
new file mode 100644 (file)
index 0000000..150e610
--- /dev/null
@@ -0,0 +1,5 @@
+ConsoleViewer |= fun ()
+{
+  new_console_viewer = ConsoleViewer._New() | [] | ConsoleViewer | Sprite;
+  return new_console_viewer;
+};
index b9d7165587fe7edee54e5099c15dae7b00dd0d95..e51cabc2eefaacb768d9cdea9fc8989e23f44088 100644 (file)
  *
  * Written by: Charlie Brej <cbrej@cs.man.ac.uk>
  */
+#include "config.h"
 #include "ply-image.h"
 #include "ply-utils.h"
 #include "ply-logger.h"
 #include "ply-key-file.h"
 #include "ply-pixel-buffer.h"
 #include "ply-pixel-display.h"
+#include "ply-console-viewer.h"
 #include "script.h"
 #include "script-parse.h"
 #include "script-execute.h"
@@ -66,12 +68,50 @@ static script_return_t sprite_new (script_state_t *state,
         sprite->remove_me = false;
         sprite->image = NULL;
         sprite->image_obj = NULL;
+        sprite->state = state;
+        sprite->monospace_font = data->monospace_font;
+        sprite->draw_func = NULL;
         ply_list_append_data (data->sprite_list, sprite);
 
         reply = script_obj_new_native (sprite, data->class);
         return script_return_obj (reply);
 }
 
+static script_return_t consoleviewer_new (script_state_t *state,
+                                          void           *user_data)
+{
+        sprite_t *sprite;
+        script_lib_sprite_data_t *data = user_data;
+        script_obj_t *reply;
+        ply_list_node_t *node;
+        int index;
+        script_obj_t *index_obj;
+        script_lib_display_t *display;
+        ply_console_viewer_t *console_viewer;
+
+        script_return_t ret = sprite_new (state, user_data);
+        sprite = ret.object->data.native.object_data;
+
+        index_obj = script_obj_hash_peek_element (state->local, "window");
+
+        if (index_obj) {
+                index = script_obj_as_number (index_obj);
+                script_obj_unref (index_obj);
+                if (index < 0)
+                        return script_return_obj_null ();
+                node = ply_list_get_nth_node (data->displays, index);
+                if (node == NULL)
+                        return script_return_obj_null ();
+                display = ply_list_node_get_data (node);
+                console_viewer = ply_console_viewer_new (display->pixel_display, sprite->monospace_font);
+
+                reply = script_obj_new_native (console_viewer, data->class);
+                return script_return_obj (reply);
+        }
+
+        return script_return_obj_null ();
+}
+
 static script_return_t sprite_get_image (script_state_t *state,
                                          void           *user_data)
 {
@@ -399,6 +439,11 @@ static void script_lib_draw_brackground (ply_pixel_buffer_t       *pixel_buffer,
                                          ply_rectangle_t          *clip_area,
                                          script_lib_sprite_data_t *data)
 {
+        if (data->should_show_console_messages) {
+                ply_pixel_buffer_fill_with_hex_color (pixel_buffer, clip_area, 0);
+                return;
+        }
+
         if (data->background_color_start == data->background_color_end) {
                 ply_pixel_buffer_fill_with_hex_color (pixel_buffer,
                                                       clip_area,
@@ -428,6 +473,11 @@ static void script_lib_sprite_draw_area (script_lib_display_t *display,
         clip_area.width = width;
         clip_area.height = height;
 
+        if (data->plugin_console_messages_updating == false && display->console_viewer != NULL && data->should_show_console_messages == true) {
+                script_lib_draw_brackground (pixel_buffer, &clip_area, data);
+                ply_console_viewer_draw_area (display->console_viewer, pixel_buffer, x, y, width, height);
+                return;
+        }
 
         node = ply_list_get_first_node (data->sprite_list);
         if (node == NULL)
@@ -470,6 +520,18 @@ static void script_lib_sprite_draw_area (script_lib_display_t *display,
 
                 if ((position_x + (int) ply_pixel_buffer_get_width (sprite->image)) <= x) continue;
                 if ((position_y + (int) ply_pixel_buffer_get_height (sprite->image)) <= y) continue;
+
+                if (sprite->draw_func != NULL) {
+                        script_return_t ret = script_execute_object (sprite->state,
+                                                                     sprite->draw_func,
+                                                                     NULL,
+                                                                     NULL);
+
+                        script_obj_unref (ret.object);
+
+                        continue;
+                }
+
                 ply_pixel_buffer_fill_with_buffer_at_opacity_with_clip (pixel_buffer,
                                                                         sprite->image,
                                                                         position_x,
@@ -548,6 +610,7 @@ script_lib_sprite_data_t *script_lib_sprite_setup (script_state_t *state,
 {
         ply_list_node_t *node;
         script_lib_sprite_data_t *data = malloc (sizeof(script_lib_sprite_data_t));
+        script_return_t ret;
 
         data->class = script_obj_native_class_new (sprite_free, "sprite", data);
         data->sprite_list = ply_list_new ();
@@ -684,11 +747,31 @@ script_lib_sprite_data_t *script_lib_sprite_setup (script_state_t *state,
                                     NULL);
         script_obj_unref (window_hash);
 
+
+        data->script_consoleviewer_op = script_parse_string (script_lib_sprite_string, "script-lib-consoleviewer.script");
+        ret = script_execute (state, data->script_consoleviewer_op);
+        script_obj_unref (ret.object);
+
+        script_obj_t *consoleviewer_hash = script_obj_hash_get_element (state->global, "ConsoleViewer");
+
+        script_add_native_function (consoleviewer_hash,
+                                    "New",
+                                    consoleviewer_new,
+                                    data,
+                                    "window",
+                                    NULL);
+
+        script_obj_unref (consoleviewer_hash);
+
         data->script_main_op = script_parse_string (script_lib_sprite_string, "script-lib-sprite.script");
         data->background_color_start = 0x000000;
         data->background_color_end = 0x000000;
         data->full_refresh = true;
-        script_return_t ret = script_execute (state, data->script_main_op);
+        data->needs_redraw = true;
+        ret = script_execute (state, data->script_main_op);
+
+        data->should_show_console_messages = false;
+        data->plugin_console_messages_updating = false;
 
         script_obj_unref (ret.object);
         return data;
@@ -754,6 +837,12 @@ void script_lib_sprite_pixel_display_removed (script_lib_sprite_data_t *data,
                 update_displays (data);
 }
 
+void
+script_lib_sprite_set_needs_redraw (script_lib_sprite_data_t *data)
+{
+        data->needs_redraw = true;
+}
+
 void
 script_lib_sprite_refresh (script_lib_sprite_data_t *data)
 {
@@ -764,6 +853,9 @@ script_lib_sprite_refresh (script_lib_sprite_data_t *data)
         if (!data)
                 return;
 
+        if (!data->needs_redraw)
+                return;
+
         region = ply_region_new ();
 
         ply_list_sort_stable (data->sprite_list, &sprite_compare_z);
@@ -798,6 +890,8 @@ script_lib_sprite_refresh (script_lib_sprite_data_t *data)
                         }
                         ply_list_remove_node (data->sprite_list, node);
                         script_obj_unref (sprite->image_obj);
+                        if (sprite->draw_func != NULL)
+                                script_obj_unref (sprite->draw_func);
                         free (sprite);
                 }
                 node = next_node;
@@ -806,6 +900,9 @@ script_lib_sprite_refresh (script_lib_sprite_data_t *data)
         for (node = ply_list_get_first_node (data->sprite_list);
              node;
              node = ply_list_get_next_node (data->sprite_list, node)) {
+                if (data->should_show_console_messages)
+                        break;
+
                 sprite_t *sprite = ply_list_node_get_data (node);
                 if (!sprite->image) continue;
                 if ((sprite->x != sprite->old_x)
@@ -850,6 +947,8 @@ script_lib_sprite_refresh (script_lib_sprite_data_t *data)
         }
 
         ply_region_free (region);
+
+        data->needs_redraw = false;
 }
 
 void script_lib_sprite_destroy (script_lib_sprite_data_t *data)
@@ -860,6 +959,10 @@ void script_lib_sprite_destroy (script_lib_sprite_data_t *data)
              node;
              node = ply_list_get_next_node (data->displays, node)) {
                 script_lib_display_t *display = ply_list_node_get_data (node);
+
+                if (display->console_viewer)
+                        ply_console_viewer_free (display->console_viewer);
+
                 ply_pixel_display_set_draw_handler (display->pixel_display, NULL, NULL);
         }
 
@@ -871,6 +974,7 @@ void script_lib_sprite_destroy (script_lib_sprite_data_t *data)
                                                                      node);
                 ply_list_remove_node (data->sprite_list, node);
                 script_obj_unref (sprite->image_obj);
+                script_obj_unref (sprite->draw_func);
                 free (sprite);
                 node = next_node;
         }
@@ -881,3 +985,130 @@ void script_lib_sprite_destroy (script_lib_sprite_data_t *data)
         free (data);
         data = NULL;
 }
+
+ply_list_t *
+script_lib_get_displays (script_lib_sprite_data_t *data)
+{
+        return data->displays;
+}
+
+void
+script_lib_sprite_console_viewer_print (script_lib_sprite_data_t *data,
+                                        const char               *format,
+                                        ...)
+{
+        va_list arguments;
+        char *buffer = NULL;
+        int length;
+        ply_list_node_t *node;
+
+        if (format == NULL)
+                return;
+
+        va_start (arguments, format);
+        length = vsnprintf (NULL, 0, format, arguments);
+        if (length > 0)
+                buffer = calloc (1, length + 1);
+        va_end (arguments);
+
+        if (buffer == NULL)
+                return;
+
+        va_start (arguments, format);
+        vsnprintf (buffer, length + 1, format, arguments);
+
+        node = ply_list_get_first_node (data->displays);
+        while (node != NULL) {
+                script_lib_display_t *display;
+                ply_list_node_t *next_node;
+
+                display = ply_list_node_get_data (node);
+                next_node = ply_list_get_next_node (data->displays, node);
+
+                if (display->console_viewer != NULL)
+                        ply_console_viewer_print (display->console_viewer, buffer);
+
+                node = next_node;
+        }
+
+        va_end (arguments);
+        free (buffer);
+}
+
+void
+script_lib_sprite_console_viewer_clear_line (script_lib_sprite_data_t *data)
+{
+        ply_list_node_t *node;
+
+        node = ply_list_get_first_node (data->displays);
+        while (node != NULL) {
+                script_lib_display_t *display;
+                ply_list_node_t *next_node;
+
+                display = ply_list_node_get_data (node);
+                next_node = ply_list_get_next_node (data->displays, node);
+
+                if (display->console_viewer != NULL)
+                        ply_console_viewer_clear_line (display->console_viewer);
+
+                node = next_node;
+        }
+}
+
+void
+script_lib_sprite_console_viewer_show (script_lib_sprite_data_t *data)
+{
+        ply_list_node_t *node;
+
+        data->should_show_console_messages = true;
+
+        data->plugin_console_messages_updating = true;
+
+        data->full_refresh = true;
+
+        node = ply_list_get_first_node (data->displays);
+        while (node != NULL) {
+                script_lib_display_t *display;
+                ply_list_node_t *next_node;
+
+                display = ply_list_node_get_data (node);
+                next_node = ply_list_get_next_node (data->displays, node);
+
+                ply_console_viewer_show (display->console_viewer, display->pixel_display);
+
+                node = next_node;
+        }
+
+        script_lib_sprite_set_needs_redraw (data);
+        data->plugin_console_messages_updating = false;
+        script_lib_sprite_refresh (data);
+}
+
+void
+script_lib_sprite_console_viewer_hide (script_lib_sprite_data_t *data)
+{
+        ply_list_node_t *node;
+
+        data->should_show_console_messages = false;
+
+        data->plugin_console_messages_updating = true;
+
+        data->full_refresh = true;
+
+        node = ply_list_get_first_node (data->displays);
+        while (node != NULL) {
+                script_lib_display_t *display;
+                ply_list_node_t *next_node;
+
+                display = ply_list_node_get_data (node);
+                next_node = ply_list_get_next_node (data->displays, node);
+
+                ply_console_viewer_hide (display->console_viewer);
+
+                node = next_node;
+        }
+
+        script_lib_sprite_set_needs_redraw (data);
+        data->plugin_console_messages_updating = false;
+        script_lib_sprite_refresh (data);
+}
index 6783d25d8539d31af0ad53eb2775f66eb6b42bbb..41bc2ae0fd901eea0ec6036cbf09baaf7634633f 100644 (file)
@@ -25,6 +25,7 @@
 #include "script.h"
 #include "ply-pixel-buffer.h"
 #include "ply-pixel-display.h"
+#include "ply-console-viewer.h"
 
 typedef struct
 {
@@ -32,11 +33,18 @@ typedef struct
         ply_list_t                *sprite_list;
         script_obj_native_class_t *class;
         script_op_t               *script_main_op;
+        script_op_t               *script_consoleviewer_op;
         uint32_t                   background_color_start;
         uint32_t                   background_color_end;
         bool                       full_refresh;
         unsigned int               max_width;
         unsigned int               max_height;
+
+        ply_buffer_t              *boot_buffer;
+        char                      *monospace_font;
+        bool                       needs_redraw;
+        bool                       plugin_console_messages_updating;
+        bool                       should_show_console_messages;
 } script_lib_sprite_data_t;
 
 typedef struct
@@ -45,6 +53,8 @@ typedef struct
         script_lib_sprite_data_t *data;
         int                       x;
         int                       y;
+
+        ply_console_viewer_t     *console_viewer;
 } script_lib_display_t;
 
 typedef struct
@@ -63,6 +73,9 @@ typedef struct
         bool                remove_me;
         ply_pixel_buffer_t *image;
         script_obj_t       *image_obj;
+        char               *monospace_font;
+        script_state_t     *state;
+        script_obj_t       *draw_func;
 } sprite_t;
 
 script_lib_sprite_data_t *script_lib_sprite_setup (script_state_t *state,
@@ -73,5 +86,12 @@ void script_lib_sprite_pixel_display_removed (script_lib_sprite_data_t *data,
                                               ply_pixel_display_t      *pixel_display);
 void script_lib_sprite_refresh (script_lib_sprite_data_t *data);
 void script_lib_sprite_destroy (script_lib_sprite_data_t *data);
-
+ply_list_t *script_lib_get_displays (script_lib_sprite_data_t *data);
+void script_lib_sprite_set_needs_redraw (script_lib_sprite_data_t *data);
+void script_lib_sprite_console_viewer_print (script_lib_sprite_data_t *data,
+                                             const char               *format,
+                                             ...);
+void script_lib_sprite_console_viewer_clear_line (script_lib_sprite_data_t *data);
+void script_lib_sprite_console_viewer_show (script_lib_sprite_data_t *data);
+void script_lib_sprite_console_viewer_hide (script_lib_sprite_data_t *data);
 #endif /* SCRIPT_LIB_SPRITE_H */