From 38e261ac9ae15fad78c1382cde85caa2505b11f8 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 26 Aug 2008 23:51:59 -0400 Subject: [PATCH] Add start of font rendering support We now have a plugin that we load after / is mounted. It links against pango for text support. In libplybootsplash we have a new label control that will call into the plugin if it's loaded or render invisible otherwise. --- configure.ac | 2 + src/libplybootsplash/Makefile.am | 11 +- src/libplybootsplash/ply-label-plugin.h | 55 ++++++ src/libplybootsplash/ply-label.c | 205 ++++++++++++++++++++ src/libplybootsplash/ply-label.h | 53 +++++ src/plugins/Makefile.am | 2 +- src/plugins/controls/Makefile.am | 2 + src/plugins/controls/label/Makefile.am | 20 ++ src/plugins/controls/label/plugin.c | 247 ++++++++++++++++++++++++ src/plugins/splash/spinfinity/plugin.c | 36 +++- 10 files changed, 624 insertions(+), 9 deletions(-) create mode 100644 src/libplybootsplash/ply-label-plugin.h create mode 100644 src/libplybootsplash/ply-label.c create mode 100644 src/libplybootsplash/ply-label.h create mode 100644 src/plugins/controls/Makefile.am create mode 100644 src/plugins/controls/label/Makefile.am create mode 100644 src/plugins/controls/label/plugin.c diff --git a/configure.ac b/configure.ac index 2dafade3..45a3d953 100644 --- a/configure.ac +++ b/configure.ac @@ -100,6 +100,8 @@ AC_OUTPUT([Makefile src/plugins/splash/fade-in/Makefile src/plugins/splash/text/Makefile src/plugins/splash/details/Makefile + src/plugins/controls/Makefile + src/plugins/controls/label/Makefile src/Makefile src/client/Makefile src/viewer/Makefile diff --git a/src/libplybootsplash/Makefile.am b/src/libplybootsplash/Makefile.am index 3a9793bb..f3e6dbbf 100644 --- a/src/libplybootsplash/Makefile.am +++ b/src/libplybootsplash/Makefile.am @@ -1,16 +1,18 @@ INCLUDES = -I$(top_srcdir) \ -I$(srcdir) \ - -I$(srcdir)/../libply + -I$(srcdir)/../libply \ + -I$(srcdir)/../plugins/controls lib_LTLIBRARIES = libplybootsplash.la libplybootsplashdir = $(includedir)/plymouth-1/plybootsplash -libplybootsplash_HEADERS = ply-answer.h ply-entry.h ply-text-pulser.h ply-throbber.h ply-window.h ply-boot-splash-plugin.h +libplybootsplash_HEADERS = ply-answer.h ply-entry.h ply-text-pulser.h ply-throbber.h ply-window.h ply-label.h ply-boot-splash-plugin.h libplybootsplash_la_CFLAGS = $(PLYMOUTH_CFLAGS) \ -DPLYMOUTH_BACKGROUND_COLOR=$(background_color) \ -DPLYMOUTH_BACKGROUND_END_COLOR=$(background_end_color) \ - -DPLYMOUTH_BACKGROUND_START_COLOR=$(background_start_color) + -DPLYMOUTH_BACKGROUND_START_COLOR=$(background_start_color) \ + -DPLYMOUTH_PLUGIN_PATH=\"$(libdir)/plymouth/\" libplybootsplash_la_LIBADD = $(PLYMOUTH_LIBS) ../libply/libply.la libplybootsplash_la_LDFLAGS = -export-symbols-regex '^[^_].*' \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \ @@ -18,7 +20,8 @@ libplybootsplash_la_LDFLAGS = -export-symbols-regex '^[^_].*' \ libplybootsplash_la_SOURCES = \ $(libplybootsplash_HEADERS) \ ply-answer.c \ - ply-entry.c \ + ply-entry.c \ + ply-label.c \ ply-throbber.c \ ply-text-pulser.c \ ply-window.c diff --git a/src/libplybootsplash/ply-label-plugin.h b/src/libplybootsplash/ply-label-plugin.h new file mode 100644 index 00000000..fbb65f6f --- /dev/null +++ b/src/libplybootsplash/ply-label-plugin.h @@ -0,0 +1,55 @@ +/* ply-boot-splash-plugin.h - plugin interface for ply_label_t + * + * Copyright (C) 2007 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: Ray Strode + */ +#ifndef PLY_LABEL_PLUGIN_H +#define PLY_LABEL_PLUGIN_H + +#include +#include +#include + +#include "ply-event-loop.h" +#include "ply-window.h" + +typedef struct _ply_label_plugin ply_label_plugin_t; +typedef struct _ply_label_plugin_control ply_label_plugin_control_t; + +typedef struct +{ + ply_label_plugin_control_t * (* create_control) (void); + void (* destroy_control) (ply_label_plugin_control_t *label); + bool (* show_control) (ply_label_plugin_control_t *label, + ply_window_t *window, + long x, + long y); + void (* hide_control) (ply_label_plugin_control_t *label); + void (* draw_control) (ply_label_plugin_control_t *label); + bool (* is_control_hidden) (ply_label_plugin_control_t *label); + + void (* set_text_for_control) (ply_label_plugin_control_t *label, + const char *text); + + long (* get_width_of_control) (ply_label_plugin_control_t *label); + long (* get_height_of_control) (ply_label_plugin_control_t *label); +} ply_label_plugin_interface_t; + +#endif /* PLY_LABEL_PLUGIN_H */ +/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ diff --git a/src/libplybootsplash/ply-label.c b/src/libplybootsplash/ply-label.c new file mode 100644 index 00000000..48b27ce2 --- /dev/null +++ b/src/libplybootsplash/ply-label.c @@ -0,0 +1,205 @@ +/* ply-label.c - APIs for showing text + * + * 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: Ray Strode + */ +#include "config.h" +#include "ply-label.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ply-label-plugin.h" +#include "ply-event-loop.h" +#include "ply-list.h" +#include "ply-logger.h" +#include "ply-utils.h" + +struct _ply_label +{ + ply_event_loop_t *loop; + ply_module_handle_t *module_handle; + const ply_label_plugin_interface_t *plugin_interface; + ply_label_plugin_control_t *control; + + char *text; +}; + +typedef const ply_label_plugin_interface_t * + (* get_plugin_interface_function_t) (void); + +ply_label_t * +ply_label_new (void) +{ + ply_label_t *label; + + label = calloc (1, sizeof (struct _ply_label)); + return label; +} + +void +ply_label_free (ply_label_t *label) +{ + if (label == NULL) + return; + + free (label); + +} + +static bool +ply_label_load_plugin (ply_label_t *label) +{ + assert (label != NULL); + + get_plugin_interface_function_t get_label_plugin_interface; + + label->module_handle = ply_open_module (PLYMOUTH_PLUGIN_PATH "label.so"); + + if (label->module_handle == NULL) + return false; + + get_label_plugin_interface = (get_plugin_interface_function_t) + ply_module_look_up_function (label->module_handle, + "ply_label_plugin_get_interface"); + + if (get_label_plugin_interface == NULL) + { + ply_save_errno (); + ply_close_module (label->module_handle); + label->module_handle = NULL; + ply_restore_errno (); + return false; + } + + label->plugin_interface = get_label_plugin_interface (); + + if (label->plugin_interface == NULL) + { + ply_save_errno (); + ply_close_module (label->module_handle); + label->module_handle = NULL; + ply_restore_errno (); + return false; + } + + label->control = label->plugin_interface->create_control (); + + if (label->text != NULL) + label->plugin_interface->set_text_for_control (label->control, + label->text); + + return true; +} + +static void +ply_label_unload_plugin (ply_label_t *label) +{ + assert (label != NULL); + assert (label->plugin_interface != NULL); + assert (label->module_handle != NULL); + + ply_close_module (label->module_handle); + label->plugin_interface = NULL; + label->module_handle = NULL; +} + +bool +ply_label_show (ply_label_t *label, + ply_window_t *window, + long x, + long y) +{ + if (label->plugin_interface == NULL) + { + if (!ply_label_load_plugin (label)) + return false; + } + + return label->plugin_interface->show_control (label->control, + window, x, y); +} + +void +ply_label_draw (ply_label_t *label) +{ + if (label->plugin_interface == NULL) + return; + + label->plugin_interface->draw_control (label->control); +} + +void +ply_label_hide (ply_label_t *label) +{ + if (label->plugin_interface == NULL) + return; + + label->plugin_interface->hide_control (label->control); +} + +bool +ply_label_is_hidden (ply_label_t *label) +{ + if (label->plugin_interface == NULL) + return true; + + return label->plugin_interface->is_control_hidden (label->control); +} + +void +ply_label_set_text (ply_label_t *label, + const char *text) +{ + + free (label->text); + label->text = strdup (text); + + if (label->plugin_interface == NULL) + return; + + label->plugin_interface->set_text_for_control (label->control, + text); +} + +long +ply_label_get_width (ply_label_t *label) +{ + if (label->plugin_interface == NULL) + return 0; + + return label->plugin_interface->get_width_of_control (label->control); +} + +long +ply_label_get_height (ply_label_t *label) +{ + if (label->plugin_interface == NULL) + return 0; + + return label->plugin_interface->get_height_of_control (label->control); +} +/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ diff --git a/src/libplybootsplash/ply-label.h b/src/libplybootsplash/ply-label.h new file mode 100644 index 00000000..21b46456 --- /dev/null +++ b/src/libplybootsplash/ply-label.h @@ -0,0 +1,53 @@ +/* ply-label.h - label control + * + * 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: Ray Strode + */ +#ifndef PLY_LABEL_H +#define PLY_LABEL_H + +#include +#include +#include + +#include "ply-event-loop.h" +#include "ply-window.h" + +typedef struct _ply_label ply_label_t; + +#ifndef PLY_HIDE_FUNCTION_DECLARATIONS +ply_label_t *ply_label_new (void); +void ply_label_free (ply_label_t *label); + +bool ply_label_show (ply_label_t *label, + ply_window_t *window, + long x, + long y); +void ply_label_draw (ply_label_t *label); +bool ply_label_is_hidden (ply_label_t *label); + +void ply_label_set_text (ply_label_t *label, + const char *text); + +long ply_label_get_width (ply_label_t *label); +long ply_label_get_height (ply_label_t *label); +#endif + +#endif /* PLY_LABEL_H */ +/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am index 2f352509..b4fd30b9 100644 --- a/src/plugins/Makefile.am +++ b/src/plugins/Makefile.am @@ -1,3 +1,3 @@ -SUBDIRS = splash +SUBDIRS = controls splash MAINTAINERCLEANFILES = Makefile.in diff --git a/src/plugins/controls/Makefile.am b/src/plugins/controls/Makefile.am new file mode 100644 index 00000000..d1c6b961 --- /dev/null +++ b/src/plugins/controls/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = label +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/plugins/controls/label/Makefile.am b/src/plugins/controls/label/Makefile.am new file mode 100644 index 00000000..565c1a51 --- /dev/null +++ b/src/plugins/controls/label/Makefile.am @@ -0,0 +1,20 @@ +INCLUDES = -I$(top_srcdir) \ + -I$(srcdir)/../../../libply \ + -I$(srcdir)/../../../libplybootsplash \ + -I$(srcdir)/../../.. \ + -I$(srcdir)/../.. \ + -I$(srcdir)/.. \ + -I$(srcdir) + +plugindir = $(libdir)/plymouth +plugin_LTLIBRARIES = label.la + +label_la_CFLAGS = $(PLYMOUTH_CFLAGS) $(PANGO_CFLAGS) + +label_la_LDFLAGS = -module -avoid-version -export-dynamic +label_la_LIBADD = $(PLYMOUTH_LIBS) $(PANGO_LIBS) \ + ../../../libply/libply.la \ + ../../../libplybootsplash/libplybootsplash.la +label_la_SOURCES = $(srcdir)/plugin.c + +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/plugins/controls/label/plugin.c b/src/plugins/controls/label/plugin.c new file mode 100644 index 00000000..0d17340d --- /dev/null +++ b/src/plugins/controls/label/plugin.c @@ -0,0 +1,247 @@ +/* ply-label.c - label control + * + * 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: Ray Strode + */ +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "ply-frame-buffer.h" +#include "ply-utils.h" +#include "ply-window.h" + +#include "ply-label-plugin.h" + +struct _ply_label_plugin_control +{ + ply_event_loop_t *loop; + ply_window_t *window; + ply_frame_buffer_t *frame_buffer; + ply_frame_buffer_area_t area; + + PangoLayout *pango_layout; + cairo_t *cairo_context; + cairo_surface_t *cairo_surface; + char *text; + + uint32_t is_hidden : 1; +}; + +ply_label_plugin_control_t * +create_control (void) +{ + ply_label_plugin_control_t *label; + + label = calloc (1, sizeof (ply_label_plugin_control_t)); + + label->is_hidden = true; + + return label; +} + +void +destroy_control (ply_label_plugin_control_t *label) +{ + if (label == NULL) + return; + + cairo_destroy (label->cairo_context); + cairo_surface_destroy (label->cairo_surface); + g_object_unref (label->pango_layout); + + free (label); +} + +long +get_width_of_control (ply_label_plugin_control_t *label) +{ + int width; + + pango_layout_get_size (label->pango_layout, &width, NULL); + + return (long) ((double) width / PANGO_SCALE); +} + +long +get_height_of_control (ply_label_plugin_control_t *label) +{ + int height; + + pango_layout_get_size (label->pango_layout, NULL, &height); + + return (long) ((double) height / PANGO_SCALE); +} + +static void +erase_label_area (ply_label_plugin_control_t *label) +{ + ply_window_erase_area (label->window, + label->area.x, label->area.y, + label->area.width, label->area.height); +} + +void +draw_control (ply_label_plugin_control_t *label) +{ + + if (label->is_hidden) + return; + + ply_frame_buffer_pause_updates (label->frame_buffer); + erase_label_area (label); + cairo_move_to (label->cairo_context, + label->area.x, + label->area.y); + pango_cairo_show_layout (label->cairo_context, + label->pango_layout); + cairo_surface_flush (label->cairo_surface); + ply_frame_buffer_unpause_updates (label->frame_buffer); +} + +void +set_text_for_control (ply_label_plugin_control_t *label, + const char *text) +{ + if (label->text != text) + { + free (label->text); + label->text = strdup (text); + } + + if (label->pango_layout != NULL) + { + pango_layout_set_text (label->pango_layout, text, -1); + pango_cairo_update_layout (label->cairo_context, label->pango_layout); + + label->area.width = get_width_of_control (label); + label->area.height = get_height_of_control (label); + + } +} + +bool +show_control (ply_label_plugin_control_t *label, + ply_window_t *window, + long x, + long y) +{ + PangoFontDescription *description; + ply_frame_buffer_area_t size; + unsigned char *data; + + label->window = window; + label->frame_buffer = ply_window_get_frame_buffer (window); + data = (unsigned char *) ply_frame_buffer_get_bytes (label->frame_buffer); + + label->area.x = x; + label->area.y = y; + + ply_frame_buffer_get_size (label->frame_buffer, &size); + + label->cairo_surface = cairo_image_surface_create_for_data (data, + CAIRO_FORMAT_ARGB32, + size.width, + size.height, + size.width * 4); + + label->cairo_context = cairo_create (label->cairo_surface); + label->pango_layout = pango_cairo_create_layout (label->cairo_context); + + if (label->text != NULL) + set_text_for_control (label, label->text); + + description = pango_font_description_from_string ("Sans 12"); + pango_layout_set_font_description (label->pango_layout, description); + pango_font_description_free (description); + + label->is_hidden = false; + + draw_control (label); + + return true; +} + +void +hide_control (ply_label_plugin_control_t *label) +{ + erase_label_area (label); + + g_object_unref (label->pango_layout); + label->pango_layout = NULL; + + cairo_destroy (label->cairo_context); + label->cairo_context = NULL; + + cairo_surface_destroy (label->cairo_surface); + label->cairo_surface = NULL; + + label->frame_buffer = NULL; + label->window = NULL; + label->loop = NULL; + + label->is_hidden = true; +} + +bool +is_control_hidden (ply_label_plugin_control_t *label) +{ + return label->is_hidden; +} + +ply_label_plugin_interface_t * +ply_label_plugin_get_interface (void) +{ + static ply_label_plugin_interface_t plugin_interface = + { + .create_control = create_control, + .destroy_control = destroy_control, + .show_control = show_control, + .hide_control = hide_control, + .draw_control = draw_control, + .is_control_hidden = is_control_hidden, + .set_text_for_control = set_text_for_control, + .get_width_of_control = get_width_of_control, + .get_height_of_control = get_height_of_control + }; + + return &plugin_interface; +} + +/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ diff --git a/src/plugins/splash/spinfinity/plugin.c b/src/plugins/splash/spinfinity/plugin.c index bf0b2abb..44d66cf3 100644 --- a/src/plugins/splash/spinfinity/plugin.c +++ b/src/plugins/splash/spinfinity/plugin.c @@ -44,6 +44,7 @@ #include "ply-buffer.h" #include "ply-entry.h" #include "ply-event-loop.h" +#include "ply-label.h" #include "ply-list.h" #include "ply-logger.h" #include "ply-frame-buffer.h" @@ -71,8 +72,11 @@ struct _ply_boot_splash_plugin ply_entry_t *entry; ply_throbber_t *throbber; + ply_label_t *label; ply_answer_t *pending_password_answer; + + uint32_t root_is_mounted : 1; }; static void detach_from_event_loop (ply_boot_splash_plugin_t *plugin); @@ -91,6 +95,7 @@ create_plugin (void) plugin->entry = ply_entry_new (PLYMOUTH_IMAGE_DIR "spinfinity"); plugin->throbber = ply_throbber_new (PLYMOUTH_IMAGE_DIR "spinfinity", "throbber-"); + plugin->label = ply_label_new (); return plugin; } @@ -106,6 +111,7 @@ destroy_plugin (ply_boot_splash_plugin_t *plugin) ply_image_free (plugin->lock_image); ply_entry_free (plugin->entry); ply_throbber_free (plugin->throbber); + ply_label_free (plugin->label); free (plugin); } @@ -267,7 +273,10 @@ on_draw (ply_boot_splash_plugin_t *plugin, draw_background (plugin, &area); if (plugin->pending_password_answer != NULL) - ply_entry_draw (plugin->entry); + { + ply_entry_draw (plugin->entry); + ply_label_draw (plugin->label); + } else draw_logo (plugin); ply_frame_buffer_unpause_updates (plugin->frame_buffer); @@ -400,7 +409,8 @@ hide_splash_screen (ply_boot_splash_plugin_t *plugin, } static void -show_password_entry (ply_boot_splash_plugin_t *plugin) +show_password_prompt (ply_boot_splash_plugin_t *plugin, + const char *prompt) { ply_frame_buffer_area_t area; int x, y; @@ -442,6 +452,20 @@ show_password_entry (ply_boot_splash_plugin_t *plugin) &plugin->lock_area, 0, 0, lock_data); + if (prompt != NULL) + { + int label_width, label_height; + + ply_label_set_text (plugin->label, prompt); + label_width = ply_label_get_width (plugin->label); + label_height = ply_label_get_height (plugin->label); + + x = plugin->box_area.x + plugin->lock_area.width / 2; + y = plugin->box_area.y + plugin->box_area.height + label_height; + + ply_label_show (plugin->label, plugin->window, x, y); + } + } void @@ -454,15 +478,19 @@ ask_for_password (ply_boot_splash_plugin_t *plugin, if (ply_entry_is_hidden (plugin->entry)) { stop_animation (plugin); - show_password_entry (plugin); + show_password_prompt (plugin, prompt); } else - ply_entry_draw (plugin->entry); + { + ply_entry_draw (plugin->entry); + ply_label_draw (plugin->label); + } } void on_root_mounted (ply_boot_splash_plugin_t *plugin) { + plugin->root_is_mounted = true; } ply_boot_splash_plugin_interface_t * -- 2.47.3