diff options
| author | Ray Strode <rstrode@redhat.com> | 2007-06-06 17:10:22 -0400 |
|---|---|---|
| committer | Ray Strode <rstrode@redhat.com> | 2007-06-06 17:10:22 -0400 |
| commit | 177a24020be55bfa9716cb6ebbfd018cfdf46416 (patch) | |
| tree | f9f3e3b747e9c606267f05ca1d9906c7dcd91a04 /src | |
| parent | f3b0031ba6ecccede9db5b9c6ee9c14c58532abc (diff) | |
| download | plymouth-177a24020be55bfa9716cb6ebbfd018cfdf46416.tar.gz plymouth-177a24020be55bfa9716cb6ebbfd018cfdf46416.tar.xz plymouth-177a24020be55bfa9716cb6ebbfd018cfdf46416.zip | |
add start of fedora-fade-in plugin
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.am | 23 | ||||
| -rw-r--r-- | src/fedora-fade-in.c | 316 |
2 files changed, 338 insertions, 1 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index eda2a2b..59eb2fd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,6 +2,9 @@ SUBDIRS = tests INCLUDES = -I$(top_srcdir) \ -I$(srcdir) +noinst_PROGRAMS = plymouth rhgb-client +lib_LTLIBRARIES = fedora-fade-in.la + plymouth_CFLAGS = $(PLYMOUTH_CFLAGS) plymouth_LDADD = $(PLYMOUTH_LIBS) plymouth_SOURCES = \ @@ -23,6 +26,7 @@ plymouth_SOURCES = \ ply-utils.h \ ply-utils.c \ main.c + rhgb_client_CFLAGS = $(PLYMOUTH_CFLAGS) rhgb_client_LDADD = $(PLYMOUTH_LIBS) rhgb_client_SOURCES = ply-utils.h \ @@ -37,4 +41,21 @@ rhgb_client_SOURCES = ply-utils.h \ ply-boot-client.c \ rhgb-client.c -noinst_PROGRAMS = plymouth rhgb-client + +fedora_fade_in_la_CFLAGS = $(PLYMOUTH_CFLAGS) $(IMAGE_CFLAGS) +fedora_fade_in_la_LDFLAGS = -module -avoid-version -export-dynamic +fedora_fade_in_la_LIBADD = $(PLYMOUTH_LIBS) $(IMAGE_LIBS) +fedora_fade_in_la_SOURCES = ply-utils.h \ + ply-utils.c \ + ply-logger.h \ + ply-logger.c \ + ply-list.h \ + ply-list.c \ + ply-event-loop.h \ + ply-event-loop.c \ + ply-frame-buffer.h \ + ply-frame-buffer.c \ + ply-image.h \ + ply-image.c \ + ply-boot-splash-plugin.h \ + fedora-fade-in.c diff --git a/src/fedora-fade-in.c b/src/fedora-fade-in.c new file mode 100644 index 0000000..fe9cd3b --- /dev/null +++ b/src/fedora-fade-in.c @@ -0,0 +1,316 @@ +/* fedora-fade-in.c - boot splash plugin + * + * 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 <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 <sys/ioctl.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/types.h> +#include <values.h> +#include <unistd.h> + +#include "ply-boot-splash-plugin.h" +#include "ply-event-loop.h" +#include "ply-frame-buffer.h" +#include "ply-image.h" +#include "ply-utils.h" + +#include <linux/kd.h> + +#ifndef FRAMES_PER_SECOND +#define FRAMES_PER_SECOND 50 +#endif + +struct _ply_boot_splash_plugin +{ + ply_event_loop_t *loop; + ply_frame_buffer_t *frame_buffer; + ply_image_t *image; + + int console_fd; + double start_time; +}; + +ply_boot_splash_plugin_t * +create_plugin (void) +{ + ply_boot_splash_plugin_t *plugin; + + plugin = calloc (1, sizeof (ply_boot_splash_plugin_t)); + plugin->console_fd = -1; + plugin->start_time = 0.0; + + plugin->frame_buffer = ply_frame_buffer_new (NULL); + plugin->image = ply_image_new ("booting.png"); + + return plugin; +} + +void +destroy_plugin (ply_boot_splash_plugin_t *plugin) +{ + if (plugin == NULL) + return; + + ply_image_free (plugin->image); + ply_frame_buffer_free (plugin->frame_buffer); + free (plugin); +} + +static bool +set_graphics_mode (ply_boot_splash_plugin_t *plugin) +{ + assert (plugin != NULL); + + return true; + + if (ioctl (plugin->console_fd, KDSETMODE, KD_GRAPHICS) < 0) + return false; + + return true; +} + +static void +set_text_mode (ply_boot_splash_plugin_t *plugin) +{ + assert (plugin != NULL); + + ioctl (plugin->console_fd, KDSETMODE, KD_TEXT); +} + +static bool +open_console (ply_boot_splash_plugin_t *plugin) +{ + assert (plugin != NULL); + + plugin->console_fd = open ("/dev/tty0", O_RDWR); + + if (plugin->console_fd < 0) + return false; + + return true; +} + +static void +close_console (ply_boot_splash_plugin_t *plugin) +{ + close (plugin->console_fd); + plugin->console_fd = -1; +} + +static void +animate_at_time (ply_boot_splash_plugin_t *plugin, + double time) +{ + ply_frame_buffer_t *buffer; + ply_image_t *image; + ply_frame_buffer_area_t area; + uint32_t *data; + long width, height; + static double last_opacity = 0.0; + double opacity = 0.0; + + buffer = plugin->frame_buffer; + image = plugin->image; + + data = ply_image_get_data (image); + width = ply_image_get_width (image); + height = ply_image_get_height (image); + + ply_frame_buffer_get_size (buffer, &area); + area.x = (area.width / 2) - (width / 2); + area.y = (area.height / 2) - (height / 2); + area.width = width; + area.height = height; + + opacity = .5 * sin ((time / 4) * (2 * M_PI)) + .8; + opacity = CLAMP (opacity, 0, 1.0); + + if (fabs (opacity - last_opacity) <= DBL_MIN) + return; + + last_opacity = opacity; + + ply_frame_buffer_pause_updates (buffer); + ply_frame_buffer_fill_with_color (buffer, &area, 0.1, 0.1, .7, 1.0); + ply_frame_buffer_fill_with_argb32_data_at_opacity (buffer, &area, + 0, 0, width, height, + data, opacity); + ply_frame_buffer_unpause_updates (buffer); +} + +static void +on_timeout (ply_boot_splash_plugin_t *plugin) +{ + struct itimerval timer; + long sleep_time; + + double now; + + now = ply_get_timestamp (); + animate_at_time (plugin, + now - plugin->start_time); + sleep_time = 1000000 / FRAMES_PER_SECOND; + sleep_time = MAX (sleep_time - ((ply_get_timestamp () - now) / 1000000), + 10000); + + timer.it_value.tv_sec = 0; + timer.it_value.tv_usec = sleep_time; + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = sleep_time; + setitimer (ITIMER_REAL, &timer, NULL); +} + +static void +start_animation (ply_boot_splash_plugin_t *plugin) +{ + struct itimerval timer; + double interval; + + assert (plugin != NULL); + assert (plugin->loop != NULL); + + ply_event_loop_watch_signal (plugin->loop, SIGALRM, + (ply_event_handler_t) on_timeout, plugin); + + interval = 1000000.0 / FRAMES_PER_SECOND; + timer.it_value.tv_sec = 0; + timer.it_value.tv_usec = interval; + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = interval; + + setitimer (ITIMER_REAL, &timer, NULL); + + plugin->start_time = ply_get_timestamp (); + ply_frame_buffer_fill_with_color (plugin->frame_buffer, NULL, + 0.1, 0.1, .7, 1.0); +} + +static void +stop_animation (ply_boot_splash_plugin_t *plugin) +{ + struct itimerval timer; + + assert (plugin != NULL); + assert (plugin->loop != NULL); + + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = 0; + timer.it_value.tv_sec = 0; + timer.it_value.tv_usec = 0; + + setitimer (ITIMER_REAL, &timer, NULL); + + ply_event_loop_stop_watching_signal (plugin->loop, SIGALRM); + + ply_frame_buffer_fill_with_color (plugin->frame_buffer, + NULL, 0.0, 0.0, 0.0, 1.0); +} + +bool +show_splash_screen (ply_boot_splash_plugin_t *plugin) +{ + assert (plugin != NULL); + assert (plugin->image != NULL); + assert (plugin->frame_buffer != NULL); + + if (!ply_image_load (plugin->image)) + return false; + + if (!ply_frame_buffer_open (plugin->frame_buffer)) + return false; + + if (!open_console (plugin)) + return false; + + if (!set_graphics_mode (plugin)) + { + ply_save_errno (); + close_console (plugin); + ply_restore_errno (); + return false; + } + + start_animation (plugin); + + return true; +} + +void +update_status (ply_boot_splash_plugin_t *plugin, + const char *status) +{ + assert (plugin != NULL); +} + +void +hide_splash_screen (ply_boot_splash_plugin_t *plugin) +{ + assert (plugin != NULL); + + stop_animation (plugin); + ply_frame_buffer_close (plugin->frame_buffer); +} + +static void +detach_from_event_loop (ply_boot_splash_plugin_t *plugin) +{ + plugin->loop = NULL; +} + +void +attach_to_event_loop (ply_boot_splash_plugin_t *plugin, + ply_event_loop_t *loop) +{ + plugin->loop = loop; + + ply_event_loop_watch_for_exit (loop, (ply_event_loop_exit_handler_t) + detach_from_event_loop, + 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, + .show_splash_screen = show_splash_screen, + .update_status = update_status, + .hide_splash_screen = hide_splash_screen, + .attach_to_event_loop = attach_to_event_loop + }; + + return &plugin_interface; +} + +/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ |
