Add ubuntu-text splash plugin and theme

Forwarded: not-needed
Last-Update: 2011-01-21


Gbp-Pq: Name ubuntu-text.patch
This commit is contained in:
Scott James Remnant 2022-08-31 13:59:44 +08:00 committed by luoyaoming
parent 03fb7e4f59
commit d3619ffb00
7 changed files with 847 additions and 2 deletions

View File

@ -309,6 +309,7 @@ AC_CONFIG_FILES([Makefile po/Makefile.in
src/plugins/splash/Makefile
src/plugins/splash/fade-throbber/Makefile
src/plugins/splash/tribar/Makefile
src/plugins/splash/ubuntu-text/Makefile
src/plugins/splash/text/Makefile
src/plugins/splash/details/Makefile
src/plugins/splash/space-flares/Makefile
@ -332,6 +333,7 @@ AC_CONFIG_FILES([Makefile po/Makefile.in
themes/script/Makefile
themes/ubuntu-logo/Makefile
themes/bgrt/Makefile
themes/ubuntu-text/Makefile
images/Makefile
scripts/plymouth-generate-initrd
scripts/plymouth-populate-initrd

View File

@ -1,2 +1,2 @@
SUBDIRS = fade-throbber text details space-flares two-step script tribar
SUBDIRS = fade-throbber text details space-flares two-step script tribar ubuntu-text
MAINTAINERCLEANFILES = Makefile.in

View File

@ -0,0 +1,23 @@
INCLUDES = -I$(top_srcdir) \
-I$(srcdir)/../../../libply \
-I$(srcdir)/../../../libply-splash-core \
-I$(srcdir)/../../.. \
-I$(srcdir)/../.. \
-I$(srcdir)/.. \
-I$(srcdir)
plugindir = $(libdir)/plymouth
plugin_LTLIBRARIES = ubuntu-text.la
ubuntu_text_la_CFLAGS = $(PLYMOUTH_CFLAGS) \
-DPLYMOUTH_BACKGROUND_COLOR=$(background_color) \
-DPLYMOUTH_BACKGROUND_END_COLOR=$(background_end_color) \
-DPLYMOUTH_BACKGROUND_START_COLOR=$(background_start_color)
ubuntu_text_la_LDFLAGS = -module -avoid-version -export-dynamic
ubuntu_text_la_LIBADD = $(PLYMOUTH_LIBS) \
../../../libply/libply.la \
../../../libply-splash-core/libply-splash-core.la
ubuntu_text_la_SOURCES = $(srcdir)/plugin.c
MAINTAINERCLEANFILES = Makefile.in

View File

@ -0,0 +1,805 @@
/* ubuntu-text.c - boot splash plugin
*
* Copyright (C) 2010 Canonical Ltd.
* Copyright (C) 2008 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Written by: Scott James Remnant <scott@ubuntu.com>
* Adam Jackson <ajax@redhat.com>
* Ray Strode <rstrode@redhat.com>
*/
#include "config.h"
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <math.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <termios.h>
#include <unistd.h>
#include <values.h>
#include <wchar.h>
#include "ply-trigger.h"
#include "ply-boot-splash-plugin.h"
#include "ply-buffer.h"
#include "ply-event-loop.h"
#include "ply-key-file.h"
#include "ply-list.h"
#include "ply-logger.h"
#include "ply-text-display.h"
#include "ply-text-progress-bar.h"
#include "ply-utils.h"
#include <linux/kd.h>
#define CLEAR_LINE_SEQUENCE "\033[2K\r\n"
#define BACKSPACE "\b\033[0K"
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 *views;
ply_boot_splash_display_type_t state;
char *message;
uint32_t is_animating : 1;
uint32_t black;
uint32_t white;
uint32_t brown;
uint32_t blue;
char *title;
};
typedef struct
{
ply_boot_splash_plugin_t *plugin;
ply_text_display_t *display;
} view_t;
static void hide_splash_screen (ply_boot_splash_plugin_t *plugin,
ply_event_loop_t *loop);
static view_t *
view_new (ply_boot_splash_plugin_t *plugin,
ply_text_display_t *display)
{
view_t *view;
view = calloc (1, sizeof (view_t));
view->plugin = plugin;
view->display = display;
return view;
}
static void
view_free (view_t *view)
{
free (view);
}
static void
view_show_message (view_t *view)
{
ply_boot_splash_plugin_t *plugin;
int display_width, display_height, y;
ply_terminal_color_t color;
char *message;
plugin = view->plugin;
display_width = ply_text_display_get_number_of_columns (view->display);
display_height = ply_text_display_get_number_of_rows (view->display);
if (!strncmp (plugin->message, "keys:", 5))
{
message = plugin->message + 5;
color = PLY_TERMINAL_COLOR_WHITE;
y = display_height - 4;
}
else
{
message = plugin->message;
color = PLY_TERMINAL_COLOR_BLUE;
y = display_height / 2 + 7;
}
ply_text_display_set_cursor_position (view->display, 0, y);
ply_text_display_clear_line (view->display);
ply_text_display_set_cursor_position (view->display,
(display_width -
strlen (message)) / 2,
y);
ply_text_display_set_foreground_color (view->display, color);
ply_text_display_write (view->display, "%s", message);
}
static void
view_show_prompt (view_t *view,
const char *prompt,
const char *entered_text)
{
int display_width, display_height;
display_width = ply_text_display_get_number_of_columns (view->display);
display_height = ply_text_display_get_number_of_rows (view->display);
ply_text_display_set_cursor_position (view->display, 0,
display_height / 2 + 8);
ply_text_display_clear_line (view->display);
ply_text_display_set_cursor_position (view->display,
display_width / 2 - (strlen (prompt)),
display_height / 2 + 8);
ply_text_display_write (view->display, "%s:%s", prompt, entered_text);
ply_text_display_show_cursor (view->display);
}
static void
view_start_animation (view_t *view)
{
ply_boot_splash_plugin_t *plugin;
ply_terminal_t *terminal;
assert (view != NULL);
plugin = view->plugin;
terminal = ply_text_display_get_terminal (view->display);
ply_terminal_set_color_hex_value (terminal,
PLY_TERMINAL_COLOR_BLACK,
plugin->black);
ply_terminal_set_color_hex_value (terminal,
PLY_TERMINAL_COLOR_WHITE,
plugin->white);
ply_terminal_set_color_hex_value (terminal,
PLY_TERMINAL_COLOR_BROWN,
plugin->brown);
ply_terminal_set_color_hex_value (terminal,
PLY_TERMINAL_COLOR_BLUE,
plugin->blue);
ply_text_display_set_background_color (view->display,
PLY_TERMINAL_COLOR_BLACK);
ply_text_display_clear_screen (view->display);
ply_text_display_hide_cursor (view->display);
}
static void
view_redraw (view_t *view)
{
unsigned long screen_width, screen_height;
screen_width = ply_text_display_get_number_of_columns (view->display);
screen_height = ply_text_display_get_number_of_rows (view->display);
ply_text_display_draw_area (view->display, 0, 0,
screen_width, screen_height);
}
static void
redraw_views (ply_boot_splash_plugin_t *plugin)
{
ply_list_node_t *node;
node = ply_list_get_first_node (plugin->views);
while (node != NULL)
{
ply_list_node_t *next_node;
view_t *view;
view = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (plugin->views, node);
view_redraw (view);
node = next_node;
}
}
static void
view_hide (view_t *view)
{
if (view->display != NULL)
{
ply_terminal_t *terminal;
terminal = ply_text_display_get_terminal (view->display);
ply_text_display_set_background_color (view->display, PLY_TERMINAL_COLOR_DEFAULT);
ply_text_display_clear_screen (view->display);
ply_text_display_show_cursor (view->display);
ply_terminal_reset_colors (terminal);
}
}
static void
hide_views (ply_boot_splash_plugin_t *plugin)
{
ply_list_node_t *node;
node = ply_list_get_first_node (plugin->views);
while (node != NULL)
{
ply_list_node_t *next_node;
view_t *view;
view = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (plugin->views, node);
view_hide (view);
node = next_node;
}
}
static void
pause_views (ply_boot_splash_plugin_t *plugin)
{
ply_list_node_t *node;
node = ply_list_get_first_node (plugin->views);
while (node != NULL)
{
ply_list_node_t *next_node;
view_t *view;
view = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (plugin->views, node);
ply_text_display_pause_updates (view->display);
node = next_node;
}
}
static void
unpause_views (ply_boot_splash_plugin_t *plugin)
{
ply_list_node_t *node;
node = ply_list_get_first_node (plugin->views);
while (node != NULL)
{
ply_list_node_t *next_node;
view_t *view;
view = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (plugin->views, node);
ply_text_display_unpause_updates (view->display);
node = next_node;
}
}
static ply_boot_splash_plugin_t *
create_plugin (ply_key_file_t *key_file)
{
char *option;
ply_boot_splash_plugin_t *plugin;
ply_trace ("creating plugin");
plugin = calloc (1, sizeof (ply_boot_splash_plugin_t));
plugin->message = NULL;
plugin->views = ply_list_new ();
/* Not a pretty API for setting defaults for your config file... */
plugin->black = 0x2c001e;
plugin->white = 0xffffff;
plugin->brown = 0xff4012;
plugin->blue = 0x988592;
option = ply_key_file_get_value (key_file, "ubuntu-text", "black");
if (option)
sscanf(option, "0x%x", &plugin->black);
option = ply_key_file_get_value (key_file, "ubuntu-text", "white");
if (option)
sscanf(option, "0x%x", &plugin->white);
option = ply_key_file_get_value (key_file, "ubuntu-text", "brown");
if (option)
sscanf(option, "0x%x", &plugin->brown);
option = ply_key_file_get_value (key_file, "ubuntu-text", "blue");
if (option)
sscanf(option, "0x%x", &plugin->blue);
plugin->title = ply_key_file_get_value (key_file, "ubuntu-text", "title");
return plugin;
}
static void
detach_from_event_loop (ply_boot_splash_plugin_t *plugin)
{
plugin->loop = NULL;
ply_trace ("detaching from event loop");
}
static void
free_views (ply_boot_splash_plugin_t *plugin)
{
ply_list_node_t *node;
node = ply_list_get_first_node (plugin->views);
while (node != NULL)
{
ply_list_node_t *next_node;
view_t *view;
view = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (plugin->views, node);
view_free (view);
ply_list_remove_node (plugin->views, node);
node = next_node;
}
ply_list_free (plugin->views);
plugin->views = NULL;
}
static void
destroy_plugin (ply_boot_splash_plugin_t *plugin)
{
ply_trace ("destroying plugin");
if (plugin == NULL)
return;
/* It doesn't ever make sense to keep this plugin on screen
* after exit
*/
hide_splash_screen (plugin, plugin->loop);
free_views (plugin);
if (plugin->message != NULL)
free (plugin->message);
free (plugin);
}
static void
show_message (ply_boot_splash_plugin_t *plugin)
{
ply_list_node_t *node;
node = ply_list_get_first_node (plugin->views);
while (node != NULL)
{
ply_list_node_t *next_node;
view_t *view;
view = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (plugin->views, node);
view_show_message (view);
node = next_node;
}
}
static void
animate_frame (ply_boot_splash_plugin_t *plugin,
int frame)
{
ply_list_node_t *node;
node = ply_list_get_first_node (plugin->views);
while (node != NULL)
{
ply_list_node_t *next_node;
view_t *view;
int display_width, display_height;
view = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (plugin->views, node);
display_width = ply_text_display_get_number_of_columns (view->display);
display_height = ply_text_display_get_number_of_rows (view->display);
ply_text_display_set_cursor_position (view->display,
(display_width - 12) / 2,
display_height / 2);
ply_text_display_set_background_color (view->display, PLY_TERMINAL_COLOR_BLACK);
ply_text_display_set_foreground_color (view->display, PLY_TERMINAL_COLOR_WHITE);
ply_text_display_write (view->display, "%s", plugin->title);
ply_text_display_set_cursor_position (view->display,
(display_width - 10) / 2,
(display_height / 2) + 2);
if ((frame < 1) || (frame > 4))
ply_text_display_set_foreground_color (view->display, PLY_TERMINAL_COLOR_WHITE);
else
ply_text_display_set_foreground_color (view->display, PLY_TERMINAL_COLOR_BROWN);
ply_text_display_write (view->display, "%s", ". ");
if ((frame < 2) || (frame > 5))
ply_text_display_set_foreground_color (view->display, PLY_TERMINAL_COLOR_WHITE);
else
ply_text_display_set_foreground_color (view->display, PLY_TERMINAL_COLOR_BROWN);
ply_text_display_write (view->display, "%s", ". ");
if ((frame < 3) || (frame > 6))
ply_text_display_set_foreground_color (view->display, PLY_TERMINAL_COLOR_WHITE);
else
ply_text_display_set_foreground_color (view->display, PLY_TERMINAL_COLOR_BROWN);
ply_text_display_write (view->display, "%s", ". ");
if (frame < 4)
ply_text_display_set_foreground_color (view->display, PLY_TERMINAL_COLOR_WHITE);
else
ply_text_display_set_foreground_color (view->display, PLY_TERMINAL_COLOR_BROWN);
ply_text_display_write (view->display, "%s", ".");
node = next_node;
}
}
static void
on_timeout (ply_boot_splash_plugin_t *plugin)
{
static int frame = 0;
frame += 1;
frame %= 8;
animate_frame (plugin, frame);
ply_event_loop_watch_for_timeout (plugin->loop, 1.0,
(ply_event_loop_timeout_handler_t)
on_timeout, plugin);
}
static void
start_animation (ply_boot_splash_plugin_t *plugin)
{
ply_list_node_t *node;
assert (plugin != NULL);
assert (plugin->loop != NULL);
redraw_views (plugin);
if (plugin->message != NULL)
show_message (plugin);
if (plugin->is_animating)
return;
node = ply_list_get_first_node (plugin->views);
while (node != NULL)
{
ply_list_node_t *next_node;
view_t *view;
view = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (plugin->views, node);
view_start_animation (view);
node = next_node;
}
plugin->is_animating = true;
animate_frame (plugin, 0);
ply_event_loop_watch_for_timeout (plugin->loop, 1.0,
(ply_event_loop_timeout_handler_t)
on_timeout, plugin);
}
static void
stop_animation (ply_boot_splash_plugin_t *plugin)
{
assert (plugin != NULL);
assert (plugin->loop != NULL);
if (!plugin->is_animating)
return;
plugin->is_animating = false;
ply_event_loop_stop_watching_for_timeout (plugin->loop,
(ply_event_loop_timeout_handler_t)
on_timeout, plugin);
redraw_views (plugin);
}
static void
on_draw (view_t *view,
ply_terminal_t *terminal,
int x,
int y,
int width,
int height)
{
}
static void
add_text_display (ply_boot_splash_plugin_t *plugin,
ply_text_display_t *display)
{
view_t *view;
ply_terminal_t *terminal;
view = view_new (plugin, display);
terminal = ply_text_display_get_terminal (view->display);
if (ply_terminal_open (terminal))
{
ply_terminal_set_mode (terminal, PLY_TERMINAL_MODE_TEXT);
ply_terminal_activate_vt (terminal);
}
ply_text_display_set_draw_handler (view->display,
(ply_text_display_draw_handler_t)
on_draw, view);
ply_list_append_data (plugin->views, view);
}
static void
remove_text_display (ply_boot_splash_plugin_t *plugin,
ply_text_display_t *display)
{
ply_list_node_t *node;
node = ply_list_get_first_node (plugin->views);
while (node != NULL)
{
view_t *view;
ply_list_node_t *next_node;
view = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (plugin->views, node);
if (view->display == display)
{
ply_text_display_set_draw_handler (view->display,
NULL, NULL);
view_free (view);
ply_list_remove_node (plugin->views, node);
return;
}
node = next_node;
}
}
static bool
show_splash_screen (ply_boot_splash_plugin_t *plugin,
ply_event_loop_t *loop,
ply_buffer_t *boot_buffer,
ply_boot_splash_mode_t mode)
{
assert (plugin != NULL);
plugin->loop = loop;
plugin->mode = mode;
ply_event_loop_watch_for_exit (loop, (ply_event_loop_exit_handler_t)
detach_from_event_loop,
plugin);
ply_show_new_kernel_messages (false);
start_animation (plugin);
return true;
}
static void
update_status (ply_boot_splash_plugin_t *plugin,
const char *status)
{
assert (plugin != NULL);
ply_trace ("status update");
}
static void
hide_splash_screen (ply_boot_splash_plugin_t *plugin,
ply_event_loop_t *loop)
{
assert (plugin != NULL);
ply_trace ("hiding splash screen");
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,
plugin);
detach_from_event_loop (plugin);
}
hide_views (plugin);
ply_show_new_kernel_messages (true);
}
static void
display_normal (ply_boot_splash_plugin_t *plugin)
{
pause_views (plugin);
if (plugin->state != PLY_BOOT_SPLASH_DISPLAY_NORMAL)
{
plugin->state = PLY_BOOT_SPLASH_DISPLAY_NORMAL;
start_animation (plugin);
redraw_views (plugin);
}
unpause_views (plugin);
}
static void
display_message (ply_boot_splash_plugin_t *plugin,
const char *message)
{
if (plugin->message != NULL)
free (plugin->message);
plugin->message = strdup (message);
start_animation (plugin);
}
static void
show_password_prompt (ply_boot_splash_plugin_t *plugin,
const char *prompt,
int bullets)
{
ply_list_node_t *node;
int i;
char *entered_text;
entered_text = calloc (bullets + 1, sizeof (char));
for (i = 0; i < bullets; i++)
entered_text[i] = '*';
node = ply_list_get_first_node (plugin->views);
while (node != NULL)
{
ply_list_node_t *next_node;
view_t *view;
view = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (plugin->views, node);
view_show_prompt (view, prompt, entered_text);
node = next_node;
}
free (entered_text);
}
static void
show_prompt (ply_boot_splash_plugin_t *plugin,
const char *prompt,
const char *text)
{
ply_list_node_t *node;
node = ply_list_get_first_node (plugin->views);
while (node != NULL)
{
ply_list_node_t *next_node;
view_t *view;
view = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (plugin->views, node);
view_show_prompt (view, prompt, text);
node = next_node;
}
}
static void
display_password (ply_boot_splash_plugin_t *plugin,
const char *prompt,
int bullets)
{
pause_views (plugin);
if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_NORMAL)
stop_animation (plugin);
plugin->state = PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY;
if (!prompt)
prompt = "Password";
show_password_prompt (plugin, prompt, bullets);
unpause_views (plugin);
}
static void
display_question (ply_boot_splash_plugin_t *plugin,
const char *prompt,
const char *entry_text)
{
pause_views (plugin);
if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_NORMAL)
stop_animation (plugin);
plugin->state = PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY;
if (!prompt)
prompt = "Password";
show_prompt (plugin, prompt, entry_text);
unpause_views (plugin);
}
ply_boot_splash_plugin_interface_t *
ply_boot_splash_plugin_get_interface (void)
{
static ply_boot_splash_plugin_interface_t plugin_interface =
{
.create_plugin = create_plugin,
.destroy_plugin = destroy_plugin,
.add_text_display = add_text_display,
.remove_text_display = remove_text_display,
.show_splash_screen = show_splash_screen,
.update_status = update_status,
.hide_splash_screen = hide_splash_screen,
.display_normal = display_normal,
.display_message = display_message,
.display_password = display_password,
.display_question = display_question,
};
return &plugin_interface;
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View File

@ -1,2 +1,2 @@
SUBDIRS = spinfinity fade-in text details solar glow script spinner tribar ubuntu-logo bgrt
SUBDIRS = spinfinity fade-in text details solar glow script spinner tribar ubuntu-logo bgrt ubuntu-text
MAINTAINERCLEANFILES = Makefile.in

View File

@ -0,0 +1,4 @@
themedir = $(datadir)/plymouth/themes/ubuntu-text
dist_theme_DATA = ubuntu-text.plymouth.in
MAINTAINERCLEANFILES = Makefile.in

View File

@ -0,0 +1,11 @@
[Plymouth Theme]
Name=Ubuntu Text
Description=Text mode theme based on ubuntu-logo theme
ModuleName=ubuntu-text
[ubuntu-text]
title=Ubuntu 18.04 LTS
black=0x2c001e
white=0xffffff
brown=0xff4012
blue=0x988592