#include <wchar.h>
#include "ply-boot-splash-plugin.h"
+#include "ply-console.h"
#include "ply-event-loop.h"
#include "ply-list.h"
#include "ply-logger.h"
#include "ply-trigger.h"
#include "ply-utils.h"
#include "ply-progress.h"
+#include "ply-keyboard.h"
#include "ply-key-file.h"
#ifndef UPDATES_PER_SECOND
#define UPDATES_PER_SECOND 30
#endif
+#define KEY_CTRL_L ('\100' ^'L')
+#define KEY_CTRL_T ('\100' ^'T')
+#define KEY_CTRL_V ('\100' ^'V')
struct _ply_boot_splash
{
ply_module_handle_t *module_handle;
const ply_boot_splash_plugin_interface_t *plugin_interface;
ply_boot_splash_plugin_t *plugin;
+ ply_console_t *console;
+ ply_keyboard_t *keyboard;
ply_buffer_t *boot_buffer;
ply_trigger_t *idle_trigger;
+ ply_list_t *pixel_displays;
+ ply_list_t *text_displays;
char *theme_path;
char *plugin_dir;
uint32_t is_loaded : 1;
uint32_t is_shown : 1;
+ uint32_t should_force_text_mode : 1;
};
typedef const ply_boot_splash_plugin_interface_t *
ply_boot_splash_t *
ply_boot_splash_new (const char *theme_path,
const char *plugin_dir,
- ply_buffer_t *boot_buffer)
+ ply_buffer_t *boot_buffer,
+ ply_console_t *console)
{
ply_boot_splash_t *splash;
splash->is_shown = false;
splash->boot_buffer = boot_buffer;
+ splash->console = console;
+ splash->pixel_displays = ply_list_new ();
+ splash->text_displays = ply_list_new ();
return splash;
}
+static void
+refresh_displays (ply_boot_splash_t *splash)
+{
+ ply_list_node_t *node;
+
+ node = ply_list_get_first_node (splash->pixel_displays);
+ while (node != NULL)
+ {
+ ply_pixel_display_t *display;
+ ply_list_node_t *next_node;
+ unsigned long width, height;
+
+ display = ply_list_node_get_data (node);
+ next_node = ply_list_get_next_node (splash->pixel_displays, node);
+
+ width = ply_pixel_display_get_width (display);
+ height = ply_pixel_display_get_height (display);
+
+ ply_pixel_display_draw_area (display, 0, 0, width, height);
+ node = next_node;
+ }
+
+ node = ply_list_get_first_node (splash->text_displays);
+ while (node != NULL)
+ {
+ ply_text_display_t *display;
+ ply_list_node_t *next_node;
+ int number_of_columns, number_of_rows;
+
+ display = ply_list_node_get_data (node);
+ next_node = ply_list_get_next_node (splash->text_displays, node);
+
+ number_of_columns = ply_text_display_get_number_of_columns (display);
+ number_of_rows = ply_text_display_get_number_of_rows (display);
+
+ ply_text_display_draw_area (display, 0, 0,
+ number_of_columns,
+ number_of_rows);
+ node = next_node;
+ }
+}
+
+static void
+on_keyboard_input (ply_boot_splash_t *splash,
+ const char *keyboard_input,
+ size_t character_size)
+{
+ wchar_t key;
+
+ if ((ssize_t) mbrtowc (&key, keyboard_input, character_size, NULL) > 0)
+ {
+ switch (key)
+ {
+ case KEY_CTRL_L:
+ refresh_displays (splash);
+ return;
+
+ case KEY_CTRL_T:
+ ply_trace ("toggle text mode!");
+ splash->should_force_text_mode = !splash->should_force_text_mode;
+ ply_console_force_text_mode (splash->console,
+ splash->should_force_text_mode);
+ ply_trace ("text mode toggled!");
+ return;
+
+ case KEY_CTRL_V:
+ ply_trace ("toggle verbose mode!");
+ ply_toggle_tracing ();
+ ply_trace ("verbose mode toggled!");
+ return;
+ }
+ }
+}
+
+void
+ply_boot_splash_set_keyboard (ply_boot_splash_t *splash,
+ ply_keyboard_t *keyboard)
+{
+ splash->keyboard = keyboard;
+
+ ply_keyboard_add_input_handler (keyboard,
+ (ply_keyboard_input_handler_t)
+ on_keyboard_input, splash);
+
+ if (splash->plugin_interface->set_keyboard == NULL)
+ return;
+
+ splash->plugin_interface->set_keyboard (splash->plugin, keyboard);
+}
+
+void
+ply_boot_splash_unset_keyboard (ply_boot_splash_t *splash)
+{
+ ply_keyboard_remove_input_handler (splash->keyboard,
+ (ply_keyboard_input_handler_t)
+ on_keyboard_input);
+
+ if (splash->plugin_interface->set_keyboard == NULL)
+ return;
+
+ splash->plugin_interface->unset_keyboard (splash->plugin, splash->keyboard);
+}
+
+void
+ply_boot_splash_add_pixel_display (ply_boot_splash_t *splash,
+ ply_pixel_display_t *display)
+{
+ ply_list_append_data (splash->pixel_displays, display);
+
+ if (splash->plugin_interface->add_pixel_display == NULL)
+ return;
+
+ splash->plugin_interface->add_pixel_display (splash->plugin, display);
+}
+
+void
+ply_boot_splash_remove_pixel_display (ply_boot_splash_t *splash,
+ ply_pixel_display_t *display)
+{
+ ply_list_remove_data (splash->pixel_displays, display);
+
+ if (splash->plugin_interface->remove_pixel_display == NULL)
+ return;
+
+ splash->plugin_interface->remove_pixel_display (splash->plugin, display);
+}
+
void
-ply_boot_splash_add_window (ply_boot_splash_t *splash,
- ply_window_t *window)
+ply_boot_splash_add_text_display (ply_boot_splash_t *splash,
+ ply_text_display_t *display)
{
- splash->plugin_interface->add_window (splash->plugin, window);
+ ply_list_append_data (splash->text_displays, display);
+
+ if (splash->plugin_interface->add_text_display == NULL)
+ return;
+
+ splash->plugin_interface->add_text_display (splash->plugin, display);
}
void
-ply_boot_splash_remove_window (ply_boot_splash_t *splash,
- ply_window_t *window)
+ply_boot_splash_remove_text_display (ply_boot_splash_t *splash,
+ ply_text_display_t *display)
{
- splash->plugin_interface->remove_window (splash->plugin, window);
+ ply_list_remove_data (splash->text_displays, display);
+
+ if (splash->plugin_interface->remove_pixel_display == NULL)
+ return;
+
+ splash->plugin_interface->remove_text_display (splash->plugin, display);
}
bool
if (splash->idle_trigger != NULL)
ply_trigger_free (splash->idle_trigger);
+ ply_list_free (splash->pixel_displays);
+ ply_list_free (splash->text_displays);
free (splash->theme_path);
free (splash->plugin_dir);
free (splash);
splash->plugin_interface->hide_splash_screen (splash->plugin,
splash->loop);
+ ply_console_set_mode (splash->console, PLY_CONSOLE_MODE_TEXT);
+
splash->is_shown = false;
if (splash->loop != NULL)
struct test_state {
ply_event_loop_t *loop;
ply_boot_splash_t *splash;
- ply_window_t *window;
ply_buffer_t *buffer;
};
ply_event_loop_exit (state->loop, 0);
}
+static void
+add_displays_to_splash_from_renderer (test_state_t *state,
+ ply_renderer_t *renderer)
+{
+ ply_list_t *heads;
+ ply_list_node_t *node;
+
+ heads = ply_renderer_get_heads (renderer);
+
+ node = ply_list_get_first_node (heads);
+ while (node != NULL)
+ {
+ ply_list_node_t *next_node;
+ ply_renderer_head_t *head;
+ ply_pixel_display_t *display;
+
+ head = ply_list_node_get_data (node);
+ next_node = ply_list_get_next_node (heads, node);
+
+ display = ply_pixel_display_new (renderer, head);
+
+ ply_boot_splash_add_pixel_display (state->splash, display);
+
+ node = next_node;
+ }
+}
+
int
main (int argc,
char **argv)
test_state_t state;
char *tty_name;
const char *theme_path;
+ ply_text_display_t *text_display;
+ ply_renderer_t *renderer;
+ ply_console_t *console;
+ ply_terminal_t *terminal;
+ ply_keyboard_t *keyboard;
exit_code = 0;
else
tty_name = strdup("tty0");
- state.window = ply_window_new (tty_name);
+ console = ply_console_new ();
+
+ if (!ply_console_open (console))
+ {
+ perror ("could not open console");
+ return errno;
+ }
+
+ terminal = ply_terminal_new (tty_name);
+
+ if (!ply_terminal_open (terminal))
+ {
+ perror ("could not open tty");
+ return errno;
+ }
+
+ renderer = ply_renderer_new (NULL, terminal, console);
free(tty_name);
- ply_window_attach_to_event_loop (state.window, state.loop);
- if (!ply_window_open (state.window))
+ if (!ply_renderer_open (renderer))
{
- perror ("could not open terminal");
+ perror ("could not open renderer /dev/fb");
+ ply_renderer_free (renderer);
return errno;
}
- ply_window_attach_to_event_loop (state.window, state.loop);
- ply_window_add_escape_handler (state.window,
- (ply_window_escape_handler_t) on_quit, &state);
+ keyboard = ply_keyboard_new_for_renderer (renderer);
+ ply_keyboard_add_escape_handler (keyboard,
+ (ply_keyboard_escape_handler_t) on_quit, &state);
state.buffer = ply_buffer_new ();
- state.splash = ply_boot_splash_new (theme_path, PLYMOUTH_PLUGIN_PATH, state.buffer);
+ state.splash = ply_boot_splash_new (theme_path, PLYMOUTH_PLUGIN_PATH, state.buffer, console);
+
if (!ply_boot_splash_load (state.splash))
{
perror ("could not load splash screen");
return errno;
}
- ply_boot_splash_add_window (state.splash, state.window);
+ ply_boot_splash_set_keyboard (state.splash, keyboard);
+ add_displays_to_splash_from_renderer (&state, renderer);
+
+ text_display = ply_text_display_new (terminal, console);
+ ply_boot_splash_add_text_display (state.splash, text_display);
+
ply_boot_splash_attach_to_event_loop (state.splash, state.loop);
if (!ply_boot_splash_show (state.splash, PLY_BOOT_SPLASH_MODE_BOOT_UP))
on_timeout,
state.splash);
exit_code = ply_event_loop_run (state.loop);
- ply_window_free (state.window);
ply_boot_splash_free (state.splash);
ply_buffer_free (state.buffer);