aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2007-11-05 23:31:02 +0000
committerRafael J. Wysocki <rjw@sisk.pl>2007-11-05 23:31:02 +0000
commite17dfcb7398240c583b461299e3eaba1054b9377 (patch)
treedb4f782217ab8561191d88649ba1fdc516424f89
parent8e5c3423f77f990ae5ecf6543b0ef41382f4e88c (diff)
downloadsuspend-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--COPYING4
-rw-r--r--Makefile.am19
-rw-r--r--configure.ac19
-rw-r--r--fbsplash-test.c70
-rw-r--r--fbsplash_funcs.c231
-rw-r--r--fbsplash_funcs.h28
-rw-r--r--resume.c17
-rw-r--r--splash.c12
-rw-r--r--splash.h3
-rw-r--r--suspend.c31
10 files changed, 426 insertions, 8 deletions
diff --git a/COPYING b/COPYING
index c3bec47..eba3f96 100644
--- a/COPYING
+++ b/COPYING
@@ -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 */
+
diff --git a/resume.c b/resume.c
index 7dedb47..141d64e 100644
--- a/resume.c
+++ b/resume.c
@@ -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;
diff --git a/splash.c b/splash.c
index 9db10c8..4b1997d 100644
--- a/splash.c
+++ b/splash.c
@@ -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;
diff --git a/splash.h b/splash.h
index f2db96c..15d315f 100644
--- a/splash.h
+++ b/splash.h
@@ -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);
diff --git a/suspend.c b/suspend.c
index 05b23de..d6211a2 100644
--- a/suspend.c
+++ b/suspend.c
@@ -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)) {