diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2007-11-05 23:31:02 +0000 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2007-11-05 23:31:02 +0000 |
commit | e17dfcb7398240c583b461299e3eaba1054b9377 (patch) | |
tree | db4f782217ab8561191d88649ba1fdc516424f89 | |
parent | 8e5c3423f77f990ae5ecf6543b0ef41382f4e88c (diff) | |
download | suspend-utils-e17dfcb7398240c583b461299e3eaba1054b9377.tar.gz |
From: Alon Bar-Lev <alon.barlev@gmail.com>
Add fbsplash support for suspend/resume.
fbsplash has two modes: silent and verbose.
In order to change the caption of the silent splash I added
a new callback for the splash module: set_caption().
I modified the important messages so that it will be printed to the
verbose (stdout) as well to the silent.
-rw-r--r-- | COPYING | 4 | ||||
-rw-r--r-- | Makefile.am | 19 | ||||
-rw-r--r-- | configure.ac | 19 | ||||
-rw-r--r-- | fbsplash-test.c | 70 | ||||
-rw-r--r-- | fbsplash_funcs.c | 231 | ||||
-rw-r--r-- | fbsplash_funcs.h | 28 | ||||
-rw-r--r-- | resume.c | 17 | ||||
-rw-r--r-- | splash.c | 12 | ||||
-rw-r--r-- | splash.h | 3 | ||||
-rw-r--r-- | suspend.c | 31 |
10 files changed, 426 insertions, 8 deletions
@@ -58,6 +58,10 @@ splashy Copyright 2005 Otavio Salvador <otavio@debian.org> Copyright 2005 Luis Mondesi <lemsx1@gmail.com> +splashutils + + Copyright (C) 2004-2007 Michal Januszewski <spock@gentoo.org> + m4 Macros autoconf/automake diff --git a/Makefile.am b/Makefile.am index f28c88d..830f923 100644 --- a/Makefile.am +++ b/Makefile.am @@ -16,6 +16,12 @@ if ENABLE_CREATE_DEVICE dev_DATA= endif +noinst_PROGRAMS= +if ENABLE_DEBUG +if ENABLE_FBSPLASH +noinst_PROGRAMS+=fbsplash-test +endif +endif noinst_LIBRARIES=\ libsuspend-common.a sbin_PROGRAMS=\ @@ -67,6 +73,12 @@ AM_CFLAGS+=\ common_s2disk_libs+=\ ${SPLASHY_LIBS} endif +if ENABLE_FBSPLASH +AM_CFLAGS+=\ + ${FBSPLASH_CFLAGS} +common_s2disk_libs+=\ + ${FBSPLASH_LIBS} +endif libsuspend_common_a_SOURCES=\ swsusp.h \ @@ -77,6 +89,7 @@ libsuspend_common_a_SOURCES=\ loglevel.h loglevel.c \ splash.h splash.c \ splashy_funcs.h splashy_funcs.c \ + fbsplash_funcs.h fbsplash_funcs.c \ bootsplash.h bootsplash.c \ whitelist.h whitelist.c \ s2ram.h s2ram.c @@ -144,6 +157,12 @@ suspend_keygen_LDADD=\ libsuspend-common.a \ $(LIBGCRYPT_LIBS) +fbsplash_test_SOURCES=\ + fbsplash_funcs.c \ + fbsplash-test.c +fbsplash_test_LDADD=\ + $(FBSPLASH_LIBS) + # # Misc functions # diff --git a/configure.ac b/configure.ac index f725b28..7cc442f 100644 --- a/configure.ac +++ b/configure.ac @@ -56,6 +56,12 @@ AC_ARG_ENABLE( , [enable_splashy="no"] ) +AC_ARG_ENABLE( + [fbsplash], + [AC_HELP_STRING([--enable-fbsplash], [Enable fbsplash support])], + , + [enable_fbsplash="no"] +) AC_ARG_WITH( [devdir], [AC_HELP_STRING([--with-devdir=DIR], [Use if --enable-create-device, put devices in this directory, default /dev])], @@ -208,6 +214,18 @@ if test "${enable_splashy}" = "yes"; then fi fi +if test "${enable_fbsplash}" = "yes"; then + CONFIG_FEATURES="${CONFIG_FEATURES} fbsplash" + AC_DEFINE([CONFIG_FBSPLASH], [1], [Define if fbsplash enabled]) + + PKG_CHECK_MODULES( + [FBSPLASH], + [libfbsplashrender >= 0.1], + , + [AC_MSG_ERROR([Required libfbsplashrender was not found])] + ) +fi + AC_DEFINE_UNQUOTED([CONFIG_FEATURES], ["${CONFIG_FEATURES## }"], [String representation of available features]) AC_HEADER_STDC @@ -237,6 +255,7 @@ AM_CONDITIONAL([ENABLE_ENCRYPT], [test "${enable_encrypt}" = "yes"]) AM_CONDITIONAL([ENABLE_RESUME_STATIC], [test "${enable_resume_static}" = "yes"]) AM_CONDITIONAL([ENABLE_CREATE_DEVICE], [test "${enable_create_device}" = "yes"]) AM_CONDITIONAL([ENABLE_SPLASHY], [test "${enable_splashy}" = "yes"]) +AM_CONDITIONAL([ENABLE_FBSPLASH], [test "${enable_fbsplash}" = "yes"]) AC_CONFIG_FILES([ Makefile doc/Makefile diff --git a/fbsplash-test.c b/fbsplash-test.c new file mode 100644 index 0000000..904b386 --- /dev/null +++ b/fbsplash-test.c @@ -0,0 +1,70 @@ +/* + * fbsplash.c + * + * fbsplash (framebuffer splash) splash method support + * + * Copyright (C) 2007 Alon Bar-Lev <alon.barlev@gmail.com> + * + * This file is released under the GPLv2. + * + */ + +#include "config.h" + +#include <string.h> +#include <stdio.h> +#include <linux/types.h> +#include <syscall.h> + +#include "swsusp.h" +#include "splash.h" +#include "fbsplash_funcs.h" + +char fbsplash_theme[] = ""; + +int main (void) +{ + char c; + int r; + int i; + printf("fbsplashfuncs_open...\n"); + r = fbsplashfuncs_open(SPL_SUSPEND); + printf("fbsplashfuncs_open=%d\n", r); + if (r) { + return 1; + } + + for (i=0; i<=100; i+=10) { + printf("fbsplashfuncs_progress (%d)...\n", i); + fbsplashfuncs_progress(i); + sleep(1); + if (i == 50) { + printf("fbsplashfuncs_dialog()...\n"); + printf("fbsplashfuncs_dialog=%c\n", fbsplashfuncs_dialog ("Hello world!\nPlease press a key: ")); + } +#ifdef CONFIG_ENCRYPT + else if (i==60) { + char pass[PASS_SIZE]; + printf("fbsplashfuncs_read_password(,0)..\n"); + fbsplashfuncs_read_password(pass, 0); + printf("fbsplashfuncs_read_password=%s\n", pass); + } + else if (i==80) { + char pass[PASS_SIZE]; + printf("fbsplashfuncs_read_password(,1)..\n"); + fbsplashfuncs_read_password(pass, 1); + printf("fbsplashfuncs_read_password=%s\n", pass); + } +#endif + c = fbsplashfuncs_key_pressed(); + if (c) { + char buffer[SPLASH_GENERIC_MESSAGE_SIZE]; + sprintf(buffer, "Key %c (%02x) pressed", c, (unsigned char)c); + fbsplashfuncs_set_caption(buffer); + } + } + + printf("fbsplashfuncs_finish...\n"); + fbsplashfuncs_finish(); + return 0; +} diff --git a/fbsplash_funcs.c b/fbsplash_funcs.c new file mode 100644 index 0000000..439b3a9 --- /dev/null +++ b/fbsplash_funcs.c @@ -0,0 +1,231 @@ +/* + * fbsplash.c + * + * fbsplash (framebuffer splash) splash method support + * + * Copyright (C) 2007 Alon Bar-Lev <alon.barlev@gmail.com> + * + * This file is released under the GPLv2. + * + */ + +#include "config.h" + +#ifdef CONFIG_FBSPLASH +#include <string.h> +#include <stdio.h> +#include <fbsplash.h> +#include <syscall.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <linux/input.h> + +#include "swsusp.h" +#include "splash.h" +#include "fbsplash_funcs.h" + +extern char fbsplash_theme[]; +static struct fbspl_theme *theme; +static int was_silent; +static int have_input; +static int force_verbose; + +int fbsplashfuncs_open(int mode) +{ + fbspl_cfg_t *cfg; + int have_render = 0; + int ret = 0; + + cfg = fbsplash_lib_init(fbspl_bootup); + if (!cfg) { + ret = -1; + goto cleanup; + } + cfg->verbosity = FBSPL_VERB_QUIET; + + if (strlen(fbsplash_theme) == 0) { + if (fbsplash_parse_kcmdline(0)) { + ret = -2; + goto cleanup; + } + } + else + fbsplash_acc_theme_set(fbsplash_theme); + + if (fbsplashr_init(false)) { + ret = -3; + goto cleanup; + } + have_render = 1; + + theme = fbsplashr_theme_load(); + if (!theme) { + ret = -4; + goto cleanup; + } + + was_silent = fbsplash_is_silent(); + if (!was_silent) { + fbsplash_set_silent(); + } + + fbsplashr_tty_silent_init(true); + fbsplashr_tty_silent_update(); + fbsplashr_message_set(theme, + (mode==SPL_RESUME) ? "Resuming..." : "Suspending..." ); + + fbsplashr_render_screen(theme, true, false, was_silent ? FBSPL_EFF_NONE : FBSPL_EFF_FADEIN); + + have_input = !fbsplashr_input_init(); + +cleanup: + if (ret) { + if (have_input) { + fbsplashr_input_cleanup(); + have_input = 0; + } + + if (have_render) { + fbsplashr_cleanup(); + have_render = 0; + } + + if (cfg) { + fbsplash_lib_cleanup(); + cfg = NULL; + } + } + + return ret; +} + + +int fbsplashfuncs_finish(void) +{ + if (have_input) { + fbsplashr_input_cleanup(); + have_input = 0; + } + + if (fbsplash_is_silent()) { + fbsplashr_render_screen(theme, true, false, was_silent ? FBSPL_EFF_NONE : FBSPL_EFF_FADEOUT); + } + + fbsplashr_tty_silent_cleanup(); + + if (!was_silent && fbsplash_is_silent()) + fbsplash_set_verbose(0); + + fbsplashr_theme_free(theme); + theme = NULL; + + fbsplashr_cleanup(); + fbsplash_lib_cleanup(); + + return 0; +} + +int fbsplashfuncs_progress(int p) +{ + static int old = 0; + + if (p < old || p - old >= 10) { + old = p; + + fbsplashr_progress_set(theme, FBSPL_PROGRESS_MAX/100*p); + if (fbsplash_is_silent()) + fbsplashr_render_screen(theme, true, false, FBSPL_EFF_NONE); + } + + return 0; +} + +void fbsplashfuncs_read_password(char *buf, int vrfy) +{ +#if CONFIG_ENCRYPT + char *pass; + + if (fbsplash_is_silent()) + fbsplash_set_verbose(0); + + do { + do { + pass = getpass("Passphrase please (must be non-empty): "); + } while (strlen(pass) == 0 || strlen(pass) >= PASS_SIZE); + + strcpy(buf, pass); + + if (vrfy) + pass = getpass("Verify passphrase: "); + } while (vrfy && strcmp(buf, pass)); + + if (!force_verbose) { + fbsplash_set_silent(); + fbsplashr_tty_silent_update(); + } +#endif +} + +int fbsplashfuncs_dialog(const char *prompt) +{ + int c; + + if (fbsplash_is_silent()) + fbsplash_set_verbose(0); + + printf("%s", prompt); + c = getchar(); + if (!force_verbose) { + fbsplash_set_silent(); + fbsplashr_tty_silent_update(); + } + return c; +} + +char fbsplashfuncs_key_pressed(void) +{ + if (!have_input) + return 0; + else { + char c; + c = (char)fbsplashr_input_getkey(false); + + /* + * Well... maybe someday it will work... + * But currently we cannot switch to different vt + */ + if (c == KEY_V) { + force_verbose = !force_verbose; + if (force_verbose) + fbsplash_set_verbose(0); + else + fbsplash_set_silent(); + return 0; + } else { + switch (c) { + case KEY_R: + c = REBOOT_KEY_CODE; + break; + case KEY_BACKSPACE: + c = ABORT_KEY_CODE; + break; + case 0: + break; + default: + c = '?'; + break; + } + + return c; + } + } +} + +void fbsplashfuncs_set_caption(const char *message) +{ + fbsplashr_message_set(theme, message); + if (fbsplash_is_silent()) + fbsplashr_render_screen(theme, true, false, FBSPL_EFF_NONE); +} + +#endif diff --git a/fbsplash_funcs.h b/fbsplash_funcs.h new file mode 100644 index 0000000..6fcaac1 --- /dev/null +++ b/fbsplash_funcs.h @@ -0,0 +1,28 @@ +/* + * fbsplash.h + * + * Boot splash related definitions for fbsplash method + * + * Copyright (C) 2007 Alon Bar-Lev <alon.barlev@gmail.com> + * + * This file is released under the GPLv2. + * + */ + +#ifndef FBSPLASH_FUNCS_H +#define FBSPLASH_FUNCS_H +#ifdef CONFIG_FBSPLASH + +int fbsplashfuncs_open(int mode); +int fbsplashfuncs_finish(void); +int fbsplashfuncs_progress(int p); +void fbsplashfuncs_read_password(char *, int); +int fbsplashfuncs_dialog(const char *); +void fbsplashfuncs_print(const char *); +char fbsplashfuncs_key_pressed(void); +void fbsplashfuncs_set_caption(const char *); +void fbsplashfuncs_switch_to(void); + +#endif +#endif /* FBSPLASH_FUNCS_H */ + @@ -51,6 +51,9 @@ static char do_decrypt; #define do_decrypt 0 #endif static char splash_param; +#ifdef CONFIG_FBSPLASH +char fbsplash_theme[MAX_STR_LEN] = ""; +#endif static int use_platform_suspend; static struct splash splash; @@ -128,6 +131,14 @@ static struct config_par parameters[] = { .fmt = "%s", .ptr = NULL, }, +#ifdef CONFIG_FBSPLASH + { + .name = "fbsplash theme", + .fmt = "%s", + .ptr = fbsplash_theme, + .len = MAX_STR_LEN, + }, +#endif { .name = NULL, .fmt = NULL, @@ -348,8 +359,12 @@ static int load_image(struct swap_map_handle *handle, int dev, unsigned int m, n; int ret; int error = 0; + char message[SPLASH_GENERIC_MESSAGE_SIZE]; + + sprintf(message, "Loading image data pages (%u pages)...", nr_pages); + splash.set_caption(message); + printf("%s ", message); - printf("Loading image data pages (%u pages) ... ", nr_pages); m = nr_pages / 100; if (!m) m = 1; @@ -18,6 +18,7 @@ #include "splash.h" #include "bootsplash.h" #include "splashy_funcs.h" +#include "fbsplash_funcs.h" #include "encrypt.h" /** @@ -27,6 +28,7 @@ static int splash_dummy_int_void(void) { return 0; } static int splash_dummy_int_int(int p) { return 0; } static void splash_dummy_void_void(void) { return; } +static void splash_dummy_set_caption(const char *message) { return; } #ifndef CONFIG_ENCRYPT static void splash_dummy_readpass(char *a, int b) { } #endif @@ -81,6 +83,7 @@ void splash_prepare(struct splash *splash, int mode) splash->prepare_abort = prepare_abort; splash->restore_abort = restore_abort; splash->key_pressed = key_pressed; + splash->set_caption = splash_dummy_set_caption; if (!mode) return; @@ -92,6 +95,15 @@ void splash_prepare(struct splash *splash, int mode) splash->switch_to = bootsplash_switch_to; splash->dialog = bootsplash_dialog; splash->read_password = bootsplash_read_password; +#ifdef CONFIG_FBSPLASH + } else if (!fbsplashfuncs_open(mode)) { + splash->finish = fbsplashfuncs_finish; + splash->progress = fbsplashfuncs_progress; + splash->dialog = fbsplashfuncs_dialog; + splash->read_password = fbsplashfuncs_read_password; + splash->key_pressed = fbsplashfuncs_key_pressed; + splash->set_caption = fbsplashfuncs_set_caption; +#endif #ifdef CONFIG_SPLASHY } else if (!splashy_open(mode)) { splash->finish = splashy_finish; @@ -15,6 +15,8 @@ #define SPL_SUSPEND 1 #define SPL_RESUME 2 +#define SPLASH_GENERIC_MESSAGE_SIZE 1024 + #include <termios.h> /* generic interface functions for an arbitary splash method */ @@ -27,6 +29,7 @@ struct splash { int (*prepare_abort) (struct termios *, struct termios *); char (*key_pressed) (void); void (*restore_abort) (struct termios *); + void (*set_caption) (const char *); }; void splash_prepare(struct splash *splash, int mode); @@ -78,6 +78,9 @@ static char s2ram; #endif static char early_writeout; static char splash_param; +#ifdef CONFIG_FBSPLASH +char fbsplash_theme[MAX_STR_LEN] = ""; +#endif #define SHUTDOWN_LEN 16 static char shutdown_method_value[SHUTDOWN_LEN] = ""; static enum { @@ -166,6 +169,14 @@ static struct config_par parameters[] = { .ptr = shutdown_method_value, .len = SHUTDOWN_LEN, }, +#ifdef CONFIG_FBSPLASH + { + .name = "fbsplash theme", + .fmt = "%s", + .ptr = fbsplash_theme, + .len = MAX_STR_LEN, + }, +#endif { .name = NULL, .fmt = NULL, @@ -481,6 +492,7 @@ static int save_image(struct swap_map_handle *handle, int ret, abort_possible; struct termios newtrm, savedtrm; int error = 0; + char message[SPLASH_GENERIC_MESSAGE_SIZE]; /* Switch the state of the terminal so that we can read the keyboard * without blocking and with no echo. @@ -489,13 +501,12 @@ static int save_image(struct swap_map_handle *handle, */ abort_possible = !splash.prepare_abort(&savedtrm, &newtrm); + sprintf(message, "Saving %u image data pages", nr_pages); if (abort_possible) - printf("%s: Saving %u image data pages " - "(press " ABORT_KEY_NAME " to abort) ... ", - my_name, nr_pages); - else - printf("%s: Saving image data pages (%u pages) ... ", - my_name, nr_pages); + strcat(message, "(press " ABORT_KEY_NAME " to abort)"); + strcat(message, "..."); + printf("%s: %s ", my_name, message); + splash.set_caption(message); m = nr_pages / 100; if (!m) @@ -530,6 +541,7 @@ static int save_image(struct swap_map_handle *handle, case REBOOT_KEY_CODE: printf (" reboot enabled\b\b\b\b\b\b\b" "\b\b\b\b\b\b\b\b"); + splash.set_caption("Reboot enabled"); shutdown_method = SHUTDOWN_METHOD_REBOOT; break; @@ -787,6 +799,8 @@ static int reset_signature(int fd) static void suspend_shutdown(int snapshot_fd) { + splash.set_caption("Done."); + if (shutdown_method == SHUTDOWN_METHOD_REBOOT) { reboot(); } else if (shutdown_method == SHUTDOWN_METHOD_PLATFORM) { @@ -807,6 +821,7 @@ int suspend_system(int snapshot_fd, int resume_fd) loff_t avail_swap; unsigned long image_size; int attempts, in_suspend, error = 0; + char message[SPLASH_GENERIC_MESSAGE_SIZE]; avail_swap = check_free_swap(snapshot_fd); if (avail_swap > pref_image_size) @@ -838,7 +853,9 @@ int suspend_system(int snapshot_fd, int resume_fd) } } - printf("%s: Snapshotting system\n", my_name); + sprintf(message, "Snapshotting system"); + printf("%s: %s\n", my_name, message); + splash.set_caption(message); attempts = 2; do { if (set_image_size(snapshot_fd, image_size)) { |