You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
364 lines
9.6 KiB
364 lines
9.6 KiB
/* ply-boot-splash.h - APIs for putting up a splash screen
|
|
*
|
|
* 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 "ply-boot-splash.h"
|
|
|
|
#include <assert.h>
|
|
#include <errno.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
#include <wchar.h>
|
|
|
|
#include "ply-boot-splash-plugin.h"
|
|
#include "ply-event-loop.h"
|
|
#include "ply-list.h"
|
|
#include "ply-logger.h"
|
|
#include "ply-utils.h"
|
|
|
|
struct _ply_boot_splash
|
|
{
|
|
ply_event_loop_t *loop;
|
|
ply_module_handle_t *module_handle;
|
|
const ply_boot_splash_plugin_interface_t *plugin_interface;
|
|
ply_boot_splash_plugin_t *plugin;
|
|
ply_window_t *window;
|
|
ply_buffer_t *boot_buffer;
|
|
|
|
char *module_name;
|
|
char *status;
|
|
|
|
uint32_t is_shown : 1;
|
|
};
|
|
|
|
typedef const ply_boot_splash_plugin_interface_t *
|
|
(* get_plugin_interface_function_t) (void);
|
|
|
|
ply_boot_splash_t *
|
|
ply_boot_splash_new (const char *module_name,
|
|
ply_window_t *window,
|
|
ply_buffer_t *boot_buffer)
|
|
{
|
|
ply_boot_splash_t *splash;
|
|
|
|
assert (module_name != NULL);
|
|
|
|
splash = calloc (1, sizeof (ply_boot_splash_t));
|
|
splash->loop = NULL;
|
|
splash->module_name = strdup (module_name);
|
|
splash->module_handle = NULL;
|
|
splash->is_shown = false;
|
|
|
|
splash->window = window;
|
|
splash->boot_buffer = boot_buffer;
|
|
|
|
return splash;
|
|
}
|
|
|
|
void
|
|
ply_boot_splash_free (ply_boot_splash_t *splash)
|
|
{
|
|
if (splash == NULL)
|
|
return;
|
|
|
|
if (splash->is_shown)
|
|
ply_boot_splash_hide (splash);
|
|
|
|
free (splash->module_name);
|
|
free (splash);
|
|
}
|
|
|
|
static bool
|
|
ply_boot_splash_load_plugin (ply_boot_splash_t *splash)
|
|
{
|
|
assert (splash != NULL);
|
|
assert (splash->module_name != NULL);
|
|
|
|
get_plugin_interface_function_t get_boot_splash_plugin_interface;
|
|
|
|
splash->module_handle = ply_open_module (splash->module_name);
|
|
|
|
if (splash->module_handle == NULL)
|
|
return false;
|
|
|
|
get_boot_splash_plugin_interface = (get_plugin_interface_function_t)
|
|
ply_module_look_up_function (splash->module_handle,
|
|
"ply_boot_splash_plugin_get_interface");
|
|
|
|
if (get_boot_splash_plugin_interface == NULL)
|
|
{
|
|
ply_save_errno ();
|
|
ply_close_module (splash->module_handle);
|
|
splash->module_handle = NULL;
|
|
ply_restore_errno ();
|
|
return false;
|
|
}
|
|
|
|
splash->plugin_interface = get_boot_splash_plugin_interface ();
|
|
|
|
if (splash->plugin_interface == NULL)
|
|
{
|
|
ply_save_errno ();
|
|
ply_close_module (splash->module_handle);
|
|
splash->module_handle = NULL;
|
|
ply_restore_errno ();
|
|
return false;
|
|
}
|
|
|
|
splash->plugin = splash->plugin_interface->create_plugin ();
|
|
|
|
assert (splash->plugin != NULL);
|
|
|
|
return true;
|
|
}
|
|
|
|
static void
|
|
ply_boot_splash_unload_plugin (ply_boot_splash_t *splash)
|
|
{
|
|
assert (splash != NULL);
|
|
assert (splash->plugin != NULL);
|
|
assert (splash->plugin_interface != NULL);
|
|
assert (splash->module_handle != NULL);
|
|
|
|
splash->plugin_interface->destroy_plugin (splash->plugin);
|
|
splash->plugin = NULL;
|
|
|
|
ply_close_module (splash->module_handle);
|
|
splash->plugin_interface = NULL;
|
|
splash->module_handle = NULL;
|
|
}
|
|
|
|
bool
|
|
ply_boot_splash_show (ply_boot_splash_t *splash)
|
|
{
|
|
assert (splash != NULL);
|
|
assert (splash->module_name != NULL);
|
|
assert (splash->loop != NULL);
|
|
|
|
ply_trace ("trying to load %s", splash->module_name);
|
|
if (!ply_boot_splash_load_plugin (splash))
|
|
{
|
|
ply_save_errno ();
|
|
ply_trace ("can't load plugin: %m");
|
|
ply_restore_errno ();
|
|
return false;
|
|
}
|
|
|
|
assert (splash->plugin_interface != NULL);
|
|
assert (splash->plugin != NULL);
|
|
assert (splash->plugin_interface->show_splash_screen != NULL);
|
|
assert (splash->window != NULL);
|
|
|
|
ply_trace ("showing splash screen\n");
|
|
if (!splash->plugin_interface->show_splash_screen (splash->plugin,
|
|
splash->loop,
|
|
splash->window,
|
|
splash->boot_buffer))
|
|
{
|
|
|
|
ply_save_errno ();
|
|
ply_trace ("can't show splash: %m");
|
|
ply_restore_errno ();
|
|
return false;
|
|
}
|
|
|
|
splash->is_shown = true;
|
|
return true;
|
|
}
|
|
|
|
void
|
|
ply_boot_splash_update_status (ply_boot_splash_t *splash,
|
|
const char *status)
|
|
{
|
|
assert (splash != NULL);
|
|
assert (status != NULL);
|
|
assert (splash->plugin_interface != NULL);
|
|
assert (splash->plugin != NULL);
|
|
assert (splash->plugin_interface->update_status != NULL);
|
|
assert (splash->is_shown);
|
|
|
|
splash->plugin_interface->update_status (splash->plugin, status);
|
|
}
|
|
|
|
void
|
|
ply_boot_splash_update_output (ply_boot_splash_t *splash,
|
|
const char *output,
|
|
size_t size)
|
|
{
|
|
assert (splash != NULL);
|
|
assert (output != NULL);
|
|
|
|
if (splash->plugin_interface->on_boot_output != NULL)
|
|
splash->plugin_interface->on_boot_output (splash->plugin, output, size);
|
|
}
|
|
|
|
void
|
|
ply_boot_splash_ask_for_password (ply_boot_splash_t *splash,
|
|
ply_boot_splash_password_answer_handler_t *answer_handler,
|
|
void *answer_data)
|
|
{
|
|
|
|
assert (splash != NULL);
|
|
assert (splash->plugin_interface != NULL);
|
|
assert (splash->plugin != NULL);
|
|
assert (splash->plugin_interface->ask_for_password != NULL);
|
|
assert (splash->is_shown);
|
|
|
|
splash->plugin_interface->ask_for_password (splash->plugin,
|
|
answer_handler, answer_data);
|
|
}
|
|
|
|
static void
|
|
ply_boot_splash_detach_from_event_loop (ply_boot_splash_t *splash)
|
|
{
|
|
assert (splash != NULL);
|
|
splash->loop = NULL;
|
|
}
|
|
|
|
void
|
|
ply_boot_splash_hide (ply_boot_splash_t *splash)
|
|
{
|
|
assert (splash != NULL);
|
|
assert (splash->plugin_interface != NULL);
|
|
assert (splash->plugin != NULL);
|
|
assert (splash->plugin_interface->hide_splash_screen != NULL);
|
|
|
|
splash->plugin_interface->hide_splash_screen (splash->plugin,
|
|
splash->loop,
|
|
splash->window);
|
|
|
|
ply_boot_splash_unload_plugin (splash);
|
|
splash->is_shown = false;
|
|
|
|
if (splash->loop != NULL)
|
|
{
|
|
ply_event_loop_stop_watching_for_exit (splash->loop, (ply_event_loop_exit_handler_t)
|
|
ply_boot_splash_detach_from_event_loop,
|
|
splash);
|
|
}
|
|
}
|
|
|
|
void
|
|
ply_boot_splash_attach_to_event_loop (ply_boot_splash_t *splash,
|
|
ply_event_loop_t *loop)
|
|
{
|
|
assert (splash != NULL);
|
|
assert (loop != NULL);
|
|
assert (splash->loop == NULL);
|
|
|
|
splash->loop = loop;
|
|
|
|
ply_event_loop_watch_for_exit (loop, (ply_event_loop_exit_handler_t)
|
|
ply_boot_splash_detach_from_event_loop,
|
|
splash);
|
|
}
|
|
|
|
#ifdef PLY_BOOT_SPLASH_ENABLE_TEST
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "ply-event-loop.h"
|
|
#include "ply-boot-splash.h"
|
|
|
|
typedef struct test_state test_state_t;
|
|
struct test_state {
|
|
ply_event_loop_t *loop;
|
|
ply_boot_splash_t *splash;
|
|
ply_window_t *window;
|
|
ply_buffer_t *buffer;
|
|
};
|
|
|
|
static void
|
|
on_timeout (ply_boot_splash_t *splash)
|
|
{
|
|
ply_boot_splash_update_status (splash, "foo");
|
|
ply_event_loop_watch_for_timeout (splash->loop,
|
|
5.0,
|
|
(ply_event_loop_timeout_handler_t)
|
|
on_timeout,
|
|
splash);
|
|
}
|
|
|
|
static void
|
|
on_quit (test_state_t *state)
|
|
{
|
|
ply_boot_splash_hide (state->splash);
|
|
ply_event_loop_exit (state->loop, 0);
|
|
}
|
|
|
|
int
|
|
main (int argc,
|
|
char **argv)
|
|
{
|
|
int exit_code;
|
|
test_state_t state;
|
|
const char *module_name;
|
|
|
|
exit_code = 0;
|
|
|
|
state.loop = ply_event_loop_new ();
|
|
|
|
if (argc > 1)
|
|
module_name = argv[1];
|
|
else
|
|
module_name = "../splash-plugins/fedora-fade-in/.libs/fedora-fade-in.so";
|
|
|
|
state.window = ply_window_new (ttyname (0));
|
|
|
|
if (!ply_window_open (state.window))
|
|
{
|
|
perror ("could not open terminal");
|
|
return errno;
|
|
}
|
|
|
|
ply_window_attach_to_event_loop (state.window, state.loop);
|
|
ply_window_set_escape_handler (state.window,
|
|
(ply_window_escape_handler_t)on_quit, &state);
|
|
|
|
state.buffer = ply_buffer_new ();
|
|
state.splash = ply_boot_splash_new (module_name, state.window, state.buffer);
|
|
ply_boot_splash_attach_to_event_loop (state.splash, state.loop);
|
|
|
|
if (!ply_boot_splash_show (state.splash))
|
|
{
|
|
perror ("could not show splash screen");
|
|
return errno;
|
|
}
|
|
|
|
ply_event_loop_watch_for_timeout (state.loop,
|
|
1.0,
|
|
(ply_event_loop_timeout_handler_t)
|
|
on_timeout,
|
|
state.splash);
|
|
exit_code = ply_event_loop_run (state.loop);
|
|
ply_boot_splash_free (state.splash);
|
|
ply_buffer_free (state.buffer);
|
|
|
|
return exit_code;
|
|
}
|
|
|
|
#endif /* PLY_BOOT_SPLASH_ENABLE_TEST */
|
|
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */
|