add start of fedora-fade-in plugin

This commit is contained in:
Ray Strode 2007-06-06 17:10:22 -04:00
parent f3b0031ba6
commit 177a24020b
2 changed files with 338 additions and 1 deletions

View file

@ -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

316
src/fedora-fade-in.c Normal file
View file

@ -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: */