branch-merge: land udev support

A certain class of machines don't work in plymouth because
they draw the kernel console to /dev/dri/card1 instead of
/dev/dri/card2.

This branch fixes that, by adding support for querying udev
to determine the available drm devices.

As part of this effort, some clean up was performed:

1) a bunch of bit rotted tests were removed
2) large chunks of code were moved from main.c to helper
objects implemented in other files.
3) Other parts of main.c were moved around or refactored
so they were easier to read.

Based on work from Kevin Murphy <kemurphy.cmu@gmail.com>

https://bugs.freedesktop.org/show_bug.cgi?id=25943
This commit is contained in:
Ray Strode 2013-12-10 01:29:30 -05:00
commit e982dc255c
49 changed files with 1731 additions and 2243 deletions

View file

@ -38,6 +38,10 @@ PKG_CHECK_MODULES(IMAGE, [libpng >= 1.2.16 ])
AC_SUBST(IMAGE_CFLAGS)
AC_SUBST(IMAGE_LIBS)
PKG_CHECK_MODULES(UDEV, [libudev]);
AC_SUBST(UDEV_CFLAGS)
AC_SUBST(UDEV_LIBS)
PLYMOUTH_CFLAGS=""
PLYMOUTH_LIBS="-lm -lrt -ldl"

View file

@ -1,4 +1,4 @@
SUBDIRS = libply libply-splash-core libply-splash-graphics . plugins client viewer tests
SUBDIRS = libply libply-splash-core libply-splash-graphics . plugins client viewer
if ENABLE_UPSTART_MONITORING
SUBDIRS += upstart-bridge
endif
@ -15,12 +15,13 @@ plymouthdbindir = $(plymouthdaemondir)
plymouthdbin_PROGRAMS = plymouthd
plymouthd_CFLAGS = $(PLYMOUTH_CFLAGS) \
$(UDEV_CFLAGS) \
-DPLYMOUTH_PLUGIN_PATH=\"$(PLYMOUTH_PLUGIN_PATH)\" \
-DPLYMOUTH_THEME_PATH=\"$(PLYMOUTH_THEME_PATH)/\" \
-DPLYMOUTH_POLICY_DIR=\"$(PLYMOUTH_POLICY_DIR)/\" \
-DPLYMOUTH_RUNTIME_DIR=\"$(PLYMOUTH_RUNTIME_DIR)\" \
-DPLYMOUTH_CONF_DIR=\"$(PLYMOUTH_CONF_DIR)/\"
plymouthd_LDADD = $(PLYMOUTH_LIBS) libply/libply.la libply-splash-core/libply-splash-core.la
plymouthd_LDADD = $(PLYMOUTH_LIBS) $(UDEV_LIBS) libply/libply.la libply-splash-core/libply-splash-core.la
plymouthd_SOURCES = \
ply-boot-protocol.h \
ply-boot-server.h \

View file

@ -1,5 +1,3 @@
SUBDIRS = . tests
INCLUDES = -I$(top_srcdir) \
-I$(top_srcdir)/src \
-I$(top_srcdir)/src/libply \

View file

@ -869,137 +869,4 @@ ply_boot_client_attach_to_event_loop (ply_boot_client_t *client,
}
#ifdef PLY_BOOT_CLIENT_ENABLE_TEST
#include <stdio.h>
#include "ply-event-loop.h"
#include "ply-boot-client.h"
static void
on_pinged (ply_event_loop_t *loop)
{
printf ("PING!\n");
}
static void
on_ping_failed (ply_event_loop_t *loop)
{
printf ("PING FAILED! %m\n");
ply_event_loop_exit (loop, 1);
}
static void
on_update (ply_event_loop_t *loop)
{
printf ("UPDATE!\n");
}
static void
on_update_failed (ply_event_loop_t *loop)
{
printf ("UPDATE FAILED! %m\n");
ply_event_loop_exit (loop, 1);
}
static void
on_newroot (ply_event_loop_t *loop)
{
printf ("NEWROOT!\n");
}
static void
on_system_initialized (ply_event_loop_t *loop)
{
printf ("SYSTEM INITIALIZED!\n");
}
static void
on_system_initialized_failed (ply_event_loop_t *loop)
{
printf ("SYSTEM INITIALIZATION REQUEST FAILED!\n");
ply_event_loop_exit (loop, 1);
}
static void
on_quit (ply_event_loop_t *loop)
{
printf ("QUIT!\n");
ply_event_loop_exit (loop, 0);
}
static void
on_quit_failed (ply_event_loop_t *loop)
{
printf ("QUIT FAILED! %m\n");
ply_event_loop_exit (loop, 2);
}
static void
on_disconnect (ply_event_loop_t *loop)
{
printf ("DISCONNECT!\n");
ply_event_loop_exit (loop, 1);
}
int
main (int argc,
char **argv)
{
ply_event_loop_t *loop;
ply_boot_client_t *client;
int exit_code;
exit_code = 0;
loop = ply_event_loop_new ();
client = ply_boot_client_new ();
if (!ply_boot_client_connect (client,
(ply_boot_client_disconnect_handler_t) on_disconnect,
loop))
{
perror ("could not start boot client");
return errno;
}
ply_boot_client_attach_to_event_loop (client, loop);
ply_boot_client_ping_daemon (client,
(ply_boot_client_response_handler_t) on_pinged,
(ply_boot_client_response_handler_t) on_ping_failed,
loop);
ply_boot_client_update_daemon (client,
"loading",
(ply_boot_client_response_handler_t) on_update,
(ply_boot_client_response_handler_t) on_update_failed,
loop);
ply_boot_client_update_daemon (client,
"loading more",
(ply_boot_client_response_handler_t) on_update,
(ply_boot_client_response_handler_t) on_update_failed,
loop);
ply_boot_client_tell_daemon_system_is_initialized (client,
(ply_boot_client_response_handler_t)
on_system_initialized,
(ply_boot_client_response_handler_t)
on_system_initialized_failed,
loop);
ply_boot_client_tell_daemon_to_quit (client,
(ply_boot_client_response_handler_t) on_quit,
(ply_boot_client_response_handler_t) on_quit_failed,
loop);
exit_code = ply_event_loop_run (loop);
ply_boot_client_free (client);
return exit_code;
}
#endif /* PLY_BOOT_CLIENT_ENABLE_TEST */
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -1,10 +0,0 @@
INCLUDES = \
-I$(top_srcdir) \
-I$(srcdir)/.. \
-I$(srcdir)/../.. \
-I$(srcdir)
TESTS =
noinst_PROGRAMS = $(TESTS)
MAINTAINERCLEANFILES = Makefile.in

View file

@ -1,16 +0,0 @@
TESTS += ply-boot-client-test
ply_boot_client_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_BOOT_CLIENT_ENABLE_TEST
ply_boot_client_test_LDADD = $(PLYMOUTH_LIBS)
ply_boot_client_test_SOURCES = \
$(srcdir)/../ply-utils.h \
$(srcdir)/../ply-utils.c \
$(srcdir)/../ply-logger.h \
$(srcdir)/../ply-logger.c \
$(srcdir)/../ply-list.h \
$(srcdir)/../ply-list.c \
$(srcdir)/../ply-event-loop.h \
$(srcdir)/../ply-event-loop.c \
$(srcdir)/../ply-boot-client.h \
$(srcdir)/../ply-boot-client.c

View file

@ -15,11 +15,13 @@ libply_splash_coredir = $(includedir)/plymouth-1/ply-splash-core
libply_splash_core_HEADERS = \
ply-boot-splash.h \
ply-boot-splash-plugin.h \
ply-device-manager.h \
ply-keyboard.h \
ply-pixel-buffer.h \
ply-pixel-display.h \
ply-renderer.h \
ply-renderer-plugin.h \
ply-seat.h \
ply-terminal.h \
ply-text-display.h \
ply-text-progress-bar.h \
@ -36,6 +38,7 @@ libply_splash_core_la_LDFLAGS = -export-symbols-regex '^[^_].*' \
-no-undefined
libply_splash_core_la_SOURCES = \
$(libply_splash_core_HEADERS) \
ply-device-manager.c \
ply-keyboard.c \
ply-pixel-display.c \
ply-text-display.c \
@ -44,6 +47,7 @@ libply_splash_core_la_SOURCES = \
ply-terminal.c \
ply-pixel-buffer.c \
ply-renderer.c \
ply-seat.c \
ply-boot-splash.c
MAINTAINERCLEANFILES = Makefile.in

View file

@ -48,10 +48,6 @@
#define UPDATES_PER_SECOND 30
#endif
#define KEY_CTRL_L ('\100' ^'L')
#define KEY_CTRL_T ('\100' ^'T')
#define KEY_CTRL_V ('\100' ^'V')
struct _ply_boot_splash
{
ply_event_loop_t *loop;
@ -59,11 +55,9 @@ struct _ply_boot_splash
const ply_boot_splash_plugin_interface_t *plugin_interface;
ply_boot_splash_plugin_t *plugin;
ply_boot_splash_mode_t mode;
ply_keyboard_t *keyboard;
ply_buffer_t *boot_buffer;
ply_trigger_t *idle_trigger;
ply_list_t *pixel_displays;
ply_list_t *text_displays;
ply_list_t *seats;
char *theme_path;
char *plugin_dir;
@ -100,18 +94,30 @@ ply_boot_splash_new (const char *theme_path,
splash->mode = PLY_BOOT_SPLASH_MODE_INVALID;
splash->boot_buffer = boot_buffer;
splash->pixel_displays = ply_list_new ();
splash->text_displays = ply_list_new ();
splash->seats = ply_list_new ();
return splash;
}
static void
refresh_displays (ply_boot_splash_t *splash)
detach_from_seat (ply_boot_splash_t *splash,
ply_seat_t *seat)
{
ply_list_node_t *node;
ply_keyboard_t *keyboard;
ply_list_t *displays;
ply_list_node_t *node, *next_node;
node = ply_list_get_first_node (splash->pixel_displays);
ply_trace ("removing keyboard");
if (splash->plugin_interface->unset_keyboard != NULL)
{
keyboard = ply_seat_get_keyboard (seat);
splash->plugin_interface->unset_keyboard (splash->plugin, keyboard);
}
ply_trace ("removing pixel displays");
displays = ply_seat_get_pixel_displays (seat);
node = ply_list_get_first_node (displays);
while (node != NULL)
{
ply_pixel_display_t *display;
@ -119,184 +125,137 @@ refresh_displays (ply_boot_splash_t *splash)
unsigned long width, height;
display = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (splash->pixel_displays, node);
next_node = ply_list_get_next_node (displays, node);
width = ply_pixel_display_get_width (display);
height = ply_pixel_display_get_height (display);
ply_pixel_display_draw_area (display, 0, 0, width, height);
ply_trace ("Removing %lux%lu pixel display", width, height);
if (splash->plugin_interface->remove_pixel_display != NULL)
splash->plugin_interface->remove_pixel_display (splash->plugin, display);
node = next_node;
}
node = ply_list_get_first_node (splash->text_displays);
ply_trace ("removing text displays");
displays = ply_seat_get_text_displays (seat);
node = ply_list_get_first_node (displays);
while (node != NULL)
{
ply_text_display_t *display;
ply_list_node_t *next_node;
int number_of_columns, number_of_rows;
display = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (splash->text_displays, node);
next_node = ply_list_get_next_node (displays, node);
number_of_columns = ply_text_display_get_number_of_columns (display);
number_of_rows = ply_text_display_get_number_of_rows (display);
ply_text_display_draw_area (display, 0, 0,
number_of_columns,
number_of_rows);
node = next_node;
}
}
ply_trace ("Removing %dx%d text display", number_of_columns, number_of_rows);
static ply_terminal_t *
find_local_console_terminal (ply_boot_splash_t *splash)
{
ply_list_node_t *node;
node = ply_list_get_first_node (splash->text_displays);
while (node != NULL)
{
ply_text_display_t *display;
ply_terminal_t *terminal;
ply_list_node_t *next_node;
display = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (splash->text_displays, node);
terminal = ply_text_display_get_terminal (display);
if (terminal != NULL && ply_terminal_is_vt (terminal))
return terminal;
if (splash->plugin_interface->remove_text_display != NULL)
splash->plugin_interface->remove_text_display (splash->plugin, display);
node = next_node;
}
return NULL;
}
static void
on_keyboard_input (ply_boot_splash_t *splash,
const char *keyboard_input,
size_t character_size)
attach_to_seat (ply_boot_splash_t *splash,
ply_seat_t *seat)
{
wchar_t key;
ply_keyboard_t *keyboard;
ply_list_t *displays;
ply_list_node_t *node, *next_node;
if ((ssize_t) mbrtowc (&key, keyboard_input, character_size, NULL) > 0)
if (splash->plugin_interface->set_keyboard != NULL)
{
switch (key)
keyboard = ply_seat_get_keyboard (seat);
splash->plugin_interface->set_keyboard (splash->plugin, keyboard);
}
if (splash->plugin_interface->add_pixel_display != NULL)
{
displays = ply_seat_get_pixel_displays (seat);
ply_trace ("adding pixel displays");
node = ply_list_get_first_node (displays);
while (node != NULL)
{
case KEY_CTRL_L:
refresh_displays (splash);
return;
ply_pixel_display_t *display;
ply_list_node_t *next_node;
unsigned long width, height;
case KEY_CTRL_T:
ply_trace ("toggle text mode!");
splash->should_force_text_mode = !splash->should_force_text_mode;
display = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (displays, node);
if (ply_list_get_length (splash->pixel_displays) >= 1)
{
ply_terminal_t *terminal;
width = ply_pixel_display_get_width (display);
height = ply_pixel_display_get_height (display);
terminal = find_local_console_terminal (splash);
ply_trace ("Adding %lux%lu pixel display", width, height);
if (terminal != NULL)
{
if (splash->should_force_text_mode)
{
ply_terminal_set_mode (terminal, PLY_TERMINAL_MODE_TEXT);
ply_terminal_ignore_mode_changes (terminal, true);
}
else
ply_terminal_ignore_mode_changes (terminal, false);
}
}
ply_trace ("text mode toggled!");
return;
splash->plugin_interface->add_pixel_display (splash->plugin, display);
case KEY_CTRL_V:
ply_trace ("toggle verbose mode!");
ply_toggle_tracing ();
ply_trace ("verbose mode toggled!");
return;
node = next_node;
}
}
if (splash->plugin_interface->add_text_display != NULL)
{
displays = ply_seat_get_text_displays (seat);
ply_trace ("adding text displays");
node = ply_list_get_first_node (displays);
while (node != NULL)
{
ply_text_display_t *display;
int number_of_columns, number_of_rows;
display = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (displays, node);
number_of_columns = ply_text_display_get_number_of_columns (display);
number_of_rows = ply_text_display_get_number_of_rows (display);
ply_trace ("Adding %dx%d text display", number_of_columns, number_of_rows);
splash->plugin_interface->add_text_display (splash->plugin, display);
node = next_node;
}
}
}
void
ply_boot_splash_set_keyboard (ply_boot_splash_t *splash,
ply_keyboard_t *keyboard)
ply_boot_splash_attach_to_seat (ply_boot_splash_t *splash,
ply_seat_t *seat)
{
splash->keyboard = keyboard;
ply_list_node_t *node;
ply_keyboard_add_input_handler (keyboard,
(ply_keyboard_input_handler_t)
on_keyboard_input, splash);
node = ply_list_find_node (splash->seats, seat);
if (splash->plugin_interface->set_keyboard == NULL)
if (node != NULL)
return;
splash->plugin_interface->set_keyboard (splash->plugin, keyboard);
ply_list_append_data (splash->seats, seat);
attach_to_seat (splash, seat);
}
void
ply_boot_splash_unset_keyboard (ply_boot_splash_t *splash)
ply_boot_splash_detach_from_seat (ply_boot_splash_t *splash,
ply_seat_t *seat)
{
ply_keyboard_remove_input_handler (splash->keyboard,
(ply_keyboard_input_handler_t)
on_keyboard_input);
ply_list_node_t *node;
if (splash->plugin_interface->set_keyboard == NULL)
node = ply_list_find_node (splash->seats, seat);
if (node == NULL)
return;
splash->plugin_interface->unset_keyboard (splash->plugin, splash->keyboard);
}
void
ply_boot_splash_add_pixel_display (ply_boot_splash_t *splash,
ply_pixel_display_t *display)
{
ply_list_append_data (splash->pixel_displays, display);
if (splash->plugin_interface->add_pixel_display == NULL)
return;
splash->plugin_interface->add_pixel_display (splash->plugin, display);
}
void
ply_boot_splash_remove_pixel_display (ply_boot_splash_t *splash,
ply_pixel_display_t *display)
{
ply_list_remove_data (splash->pixel_displays, display);
if (splash->plugin_interface->remove_pixel_display == NULL)
return;
splash->plugin_interface->remove_pixel_display (splash->plugin, display);
}
void
ply_boot_splash_add_text_display (ply_boot_splash_t *splash,
ply_text_display_t *display)
{
ply_list_append_data (splash->text_displays, display);
if (splash->plugin_interface->add_text_display == NULL)
return;
splash->plugin_interface->add_text_display (splash->plugin, display);
}
void
ply_boot_splash_remove_text_display (ply_boot_splash_t *splash,
ply_text_display_t *display)
{
ply_list_remove_data (splash->text_displays, display);
if (splash->plugin_interface->remove_pixel_display == NULL)
return;
splash->plugin_interface->remove_text_display (splash->plugin, display);
ply_list_remove_data (splash->seats, seat);
detach_from_seat (splash, seat);
}
bool
@ -432,56 +391,24 @@ ply_boot_splash_unload (ply_boot_splash_t *splash)
}
static void
remove_displays (ply_boot_splash_t *splash)
detach_from_seats (ply_boot_splash_t *splash)
{
ply_list_node_t *node, *next_node;
ply_list_node_t *node;
ply_trace ("removing pixel displays");
ply_trace ("detaching from seats");
node = ply_list_get_first_node (splash->pixel_displays);
node = ply_list_get_first_node (splash->seats);
while (node != NULL)
{
ply_pixel_display_t *display;
ply_seat_t *seat;
ply_list_node_t *next_node;
unsigned long width, height;
display = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (splash->pixel_displays, node);
seat = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (splash->seats, node);
width = ply_pixel_display_get_width (display);
height = ply_pixel_display_get_height (display);
detach_from_seat (splash, seat);
ply_trace ("Removing %lux%lu pixel display", width, height);
if (splash->plugin_interface->remove_pixel_display != NULL)
splash->plugin_interface->remove_pixel_display (splash->plugin, display);
ply_trace ("Removing node");
ply_list_remove_node (splash->pixel_displays, node);
node = next_node;
}
ply_trace ("removing text displays");
node = ply_list_get_first_node (splash->text_displays);
while (node != NULL)
{
ply_text_display_t *display;
int number_of_columns, number_of_rows;
display = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (splash->text_displays, node);
number_of_columns = ply_text_display_get_number_of_columns (display);
number_of_rows = ply_text_display_get_number_of_rows (display);
ply_trace ("Removing %dx%d text display", number_of_columns, number_of_rows);
if (splash->plugin_interface->remove_text_display != NULL)
splash->plugin_interface->remove_text_display (splash->plugin, display);
ply_trace ("Removing node");
ply_list_remove_node (splash->text_displays, node);
ply_list_remove_node (splash->seats, node);
node = next_node;
}
@ -508,9 +435,8 @@ ply_boot_splash_free (ply_boot_splash_t *splash)
splash);
}
remove_displays (splash);
ply_list_free (splash->pixel_displays);
ply_list_free (splash->text_displays);
detach_from_seats (splash);
ply_list_free (splash->seats);
if (splash->module_handle != NULL)
ply_boot_splash_unload (splash);
@ -676,16 +602,6 @@ ply_boot_splash_hide (ply_boot_splash_t *splash)
splash->plugin_interface->hide_splash_screen (splash->plugin,
splash->loop);
if (ply_list_get_length (splash->pixel_displays) >= 1)
{
ply_terminal_t *terminal;
terminal = find_local_console_terminal (splash);
if (terminal != NULL)
ply_terminal_set_mode (terminal, PLY_TERMINAL_MODE_TEXT);
}
splash->mode = PLY_BOOT_SPLASH_MODE_INVALID;
if (splash->loop != NULL)
@ -820,148 +736,4 @@ ply_boot_splash_become_idle (ply_boot_splash_t *splash,
splash->plugin_interface->become_idle (splash->plugin, splash->idle_trigger);
}
#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_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);
}
static void
add_displays_to_splash_from_renderer (test_state_t *state,
ply_renderer_t *renderer)
{
ply_list_t *heads;
ply_list_node_t *node;
heads = ply_renderer_get_heads (renderer);
node = ply_list_get_first_node (heads);
while (node != NULL)
{
ply_list_node_t *next_node;
ply_renderer_head_t *head;
ply_pixel_display_t *display;
head = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (heads, node);
display = ply_pixel_display_new (renderer, head);
ply_boot_splash_add_pixel_display (state->splash, display);
node = next_node;
}
}
int
main (int argc,
char **argv)
{
int exit_code;
test_state_t state;
char *tty_name;
const char *theme_path;
ply_text_display_t *text_display;
ply_renderer_t *renderer;
ply_terminal_t *terminal;
ply_keyboard_t *keyboard;
exit_code = 0;
state.loop = ply_event_loop_new ();
if (argc > 1)
theme_path = argv[1];
else
theme_path = PLYMOUTH_THEME_PATH "/fade-in/fade-in.plymouth";
if (argc > 2)
asprintf(&tty_name, "tty%s", argv[2]);
else
tty_name = strdup("tty0");
terminal = ply_terminal_new (tty_name);
if (!ply_terminal_open (terminal))
{
perror ("could not open tty");
return errno;
}
renderer = ply_renderer_new (NULL, terminal);
free(tty_name);
if (!ply_renderer_open (renderer))
{
perror ("could not open renderer /dev/fb");
ply_renderer_free (renderer);
return errno;
}
keyboard = ply_keyboard_new_for_renderer (renderer);
ply_keyboard_add_escape_handler (keyboard,
(ply_keyboard_escape_handler_t) on_quit, &state);
state.buffer = ply_buffer_new ();
state.splash = ply_boot_splash_new (theme_path, PLYMOUTH_PLUGIN_PATH, state.buffer);
if (!ply_boot_splash_load (state.splash))
{
perror ("could not load splash screen");
return errno;
}
ply_boot_splash_set_keyboard (state.splash, keyboard);
add_displays_to_splash_from_renderer (&state, renderer);
text_display = ply_text_display_new (terminal);
ply_boot_splash_add_text_display (state.splash, text_display);
ply_boot_splash_attach_to_event_loop (state.splash, state.loop);
if (!ply_boot_splash_show (state.splash, PLY_BOOT_SPLASH_MODE_BOOT_UP))
{
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: */

View file

@ -33,10 +33,12 @@
#include "ply-pixel-display.h"
#include "ply-text-display.h"
#include "ply-progress.h"
#include "ply-seat.h"
#include "ply-boot-splash-plugin.h"
typedef struct _ply_boot_splash ply_boot_splash_t;
typedef struct _ply_seat ply_seat_t;
typedef void (* ply_boot_splash_on_idle_handler_t) (void *user_data);
@ -48,17 +50,10 @@ ply_boot_splash_t *ply_boot_splash_new (const char * theme_path,
bool ply_boot_splash_load (ply_boot_splash_t *splash);
bool ply_boot_splash_load_built_in (ply_boot_splash_t *splash);
void ply_boot_splash_unload (ply_boot_splash_t *splash);
void ply_boot_splash_set_keyboard (ply_boot_splash_t *splash,
ply_keyboard_t *keyboard);
void ply_boot_splash_unset_keyboard (ply_boot_splash_t *splash);
void ply_boot_splash_add_pixel_display (ply_boot_splash_t *splash,
ply_pixel_display_t *display);
void ply_boot_splash_remove_pixel_display (ply_boot_splash_t *splash,
ply_pixel_display_t *display);
void ply_boot_splash_add_text_display (ply_boot_splash_t *splash,
ply_text_display_t *display);
void ply_boot_splash_remove_text_display (ply_boot_splash_t *splash,
ply_text_display_t *display);
void ply_boot_splash_attach_to_seat (ply_boot_splash_t *splash,
ply_seat_t *seat);
void ply_boot_splash_detach_from_seat (ply_boot_splash_t *splash,
ply_seat_t *seat);
void ply_boot_splash_free (ply_boot_splash_t *splash);
bool ply_boot_splash_show (ply_boot_splash_t *splash,
ply_boot_splash_mode_t mode);

View file

@ -0,0 +1,771 @@
/* ply-device-manager.c - device manager
*
* Copyright (C) 2013 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.
*/
#include "config.h"
#include "ply-device-manager.h"
#include <assert.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <libudev.h>
#include "ply-logger.h"
#include "ply-event-loop.h"
#include "ply-hashtable.h"
#include "ply-list.h"
#include "ply-utils.h"
static void create_seat_for_terminal_and_renderer_type (ply_device_manager_t *manager,
const char *device_path,
ply_terminal_t *terminal,
ply_renderer_type_t renderer_type);
struct _ply_device_manager
{
ply_device_manager_flags_t flags;
ply_event_loop_t *loop;
ply_hashtable_t *terminals;
ply_terminal_t *local_console_terminal;
ply_list_t *seats;
struct udev *udev_context;
struct udev_monitor *udev_monitor;
ply_seat_added_handler_t seat_added_handler;
ply_seat_removed_handler_t seat_removed_handler;
void *seat_event_handler_data;
};
static void
detach_from_event_loop (ply_device_manager_t *manager)
{
assert (manager != NULL);
manager->loop = NULL;
}
static void
attach_to_event_loop (ply_device_manager_t *manager,
ply_event_loop_t *loop)
{
assert (manager != NULL);
assert (loop != NULL);
assert (manager->loop == NULL);
manager->loop = loop;
ply_event_loop_watch_for_exit (loop, (ply_event_loop_exit_handler_t)
detach_from_event_loop,
manager);
}
static bool
device_is_for_local_console (ply_device_manager_t *manager,
struct udev_device *device)
{
const char *device_path;
struct udev_device *bus_device;
char *bus_device_path;
const char *boot_vga;
bool for_local_console;
/* Look at the associated bus device to see if this card is the
* card the kernel is using for its console. */
device_path = udev_device_get_syspath (device);
asprintf (&bus_device_path, "%s/device", device_path);
bus_device = udev_device_new_from_syspath (manager->udev_context, bus_device_path);
boot_vga = udev_device_get_sysattr_value (bus_device, "boot_vga");
free (bus_device_path);
if (boot_vga != NULL && strcmp (boot_vga, "1") == 0)
for_local_console = true;
else
for_local_console = false;
return for_local_console;
}
static char *
get_drm_device_node_path_from_fb_device (ply_device_manager_t *manager,
struct udev_device *fb_device)
{
struct udev_enumerate *card_matches;
struct udev_list_entry *card_entry;
const char *id_path;
char *device_node_path = NULL;
/* We want to see if the framebuffer is associated with a DRM-capable
* graphics card, if it is, we'll use the DRM device */
card_matches = udev_enumerate_new (manager->udev_context);
udev_enumerate_add_match_is_initialized(card_matches);
udev_enumerate_add_match_parent (card_matches, udev_device_get_parent (fb_device));
udev_enumerate_add_match_subsystem (card_matches, "drm");
id_path = udev_device_get_property_value (fb_device, "ID_PATH");
udev_enumerate_add_match_property (card_matches, "ID_PATH", id_path);
udev_enumerate_scan_devices (card_matches);
/* there should only ever be at most one match so we don't iterate through
* the list, but just look at the first entry */
card_entry = udev_enumerate_get_list_entry (card_matches);
if (card_entry != NULL)
{
struct udev_device *card_device = NULL;
const char *card_node;
const char *card_path;
card_path = udev_list_entry_get_name (card_entry);
card_device = udev_device_new_from_syspath (manager->udev_context, card_path);
card_node = udev_device_get_devnode (card_device);
if (card_node != NULL)
device_node_path = strdup (card_node);
udev_device_unref (card_device);
}
udev_enumerate_unref (card_matches);
return device_node_path;
}
static void
create_seat_for_udev_device (ply_device_manager_t *manager,
struct udev_device *device)
{
bool for_local_console;
char *card_path;
ply_terminal_t *terminal = NULL;
for_local_console = device_is_for_local_console (manager, device);
if (for_local_console)
terminal = manager->local_console_terminal;
card_path = get_drm_device_node_path_from_fb_device (manager, device);
if (card_path != NULL)
{
create_seat_for_terminal_and_renderer_type (manager,
card_path,
terminal,
PLY_RENDERER_TYPE_DRM);
free (card_path);
}
else
{
const char *fb_device_node_path;
fb_device_node_path = udev_device_get_devnode (device);
if (fb_device_node_path != NULL)
create_seat_for_terminal_and_renderer_type (manager,
fb_device_node_path,
terminal,
PLY_RENDERER_TYPE_FRAME_BUFFER);
}
}
static void
free_seat_from_device_path (ply_device_manager_t *manager,
const char *device_path)
{
ply_list_node_t *node;
node = ply_list_get_first_node (manager->seats);
while (node != NULL)
{
ply_seat_t *seat;
ply_renderer_t *renderer;
ply_list_node_t *next_node;
const char *renderer_device_path;
seat = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (manager->seats, node);
renderer = ply_seat_get_renderer (seat);
if (renderer != NULL)
{
renderer_device_path = ply_renderer_get_device_name (renderer);
if (renderer_device_path != NULL)
{
if (strcmp (device_path, renderer_device_path) == 0)
{
ply_trace ("removing seat associated with %s", device_path);
if (manager->seat_removed_handler != NULL)
manager->seat_removed_handler (manager->seat_event_handler_data, seat);
ply_seat_free (seat);
ply_list_remove_node (manager->seats, node);
break;
}
}
}
node = next_node;
}
}
static void
free_seat_for_udev_device (ply_device_manager_t *manager,
struct udev_device *device)
{
char *card_path;
card_path = get_drm_device_node_path_from_fb_device (manager, device);
if (card_path != NULL)
{
free_seat_from_device_path (manager, card_path);
free (card_path);
}
else
{
const char *fb_device_node_path;
fb_device_node_path = udev_device_get_devnode (device);
if (fb_device_node_path != NULL)
free_seat_from_device_path (manager, fb_device_node_path);
}
}
static void
scan_graphics_devices (ply_device_manager_t *manager)
{
struct udev_enumerate *fb_matches;
struct udev_list_entry *fb_entry;
ply_trace ("scanning for graphics devices");
/* graphics subsystem is for /dev/fb devices. kms drivers provide /dev/fb for backward
* compatibility, and do so at the end of their initialization, so we can be confident
* that when this subsystem is available the drm device is fully initialized */
fb_matches = udev_enumerate_new (manager->udev_context);
udev_enumerate_add_match_is_initialized(fb_matches);
udev_enumerate_add_match_subsystem (fb_matches, "graphics");
/* We only care about devices assigned to a (any) seat. Floating
* devices should be ignored. As a side-effect, this conveniently
* filters out the fbcon device which we don't care about.
*/
udev_enumerate_add_match_tag (fb_matches, "seat");
udev_enumerate_scan_devices (fb_matches);
udev_list_entry_foreach (fb_entry, udev_enumerate_get_list_entry (fb_matches))
{
struct udev_device *fb_device = NULL;
const char *fb_node;
const char *fb_path;
fb_path = udev_list_entry_get_name (fb_entry);
fb_device = udev_device_new_from_syspath (manager->udev_context, fb_path);
fb_node = udev_device_get_devnode (fb_device);
if (fb_node != NULL)
create_seat_for_udev_device (manager, fb_device);
udev_device_unref (fb_device);
}
udev_enumerate_unref (fb_matches);
}
static void
on_udev_graphics_event (ply_device_manager_t *manager)
{
struct udev_device *device;
const char *action;
device = udev_monitor_receive_device (manager->udev_monitor);
if (device == NULL)
return;
action = udev_device_get_action (device);
if (action == NULL)
return;
if (strcmp (action, "add") == 0)
create_seat_for_udev_device (manager, device);
else if (strcmp (action, "remove") == 0)
free_seat_for_udev_device (manager, device);
udev_device_unref (device);
}
static void
watch_for_udev_events (ply_device_manager_t *manager)
{
int fd;
assert (manager != NULL);
assert (manager->udev_monitor == NULL);
ply_trace ("watching for udev graphics device add and remove events");
manager->udev_monitor = udev_monitor_new_from_netlink (manager->udev_context, "udev");
/* The filter matching here mimics the matching done in scan_graphics_devices.
* See the comments in that function, for an explanation of what we're doing.
*/
udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, "graphics", NULL);
udev_monitor_filter_add_match_tag (manager->udev_monitor, "seat");
udev_monitor_enable_receiving (manager->udev_monitor);
fd = udev_monitor_get_fd (manager->udev_monitor);
ply_event_loop_watch_fd (manager->loop,
fd,
PLY_EVENT_LOOP_FD_STATUS_HAS_DATA,
(ply_event_handler_t)
on_udev_graphics_event,
NULL,
manager);
}
static void
free_seats (ply_device_manager_t *manager)
{
ply_list_node_t *node;
ply_trace ("removing seats");
node = ply_list_get_first_node (manager->seats);
while (node != NULL)
{
ply_seat_t *seat;
ply_list_node_t *next_node;
seat = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (manager->seats, node);
if (manager->seat_removed_handler != NULL)
manager->seat_removed_handler (manager->seat_event_handler_data, seat);
ply_seat_free (seat);
ply_list_remove_node (manager->seats, node);
node = next_node;
}
}
static void
free_terminal (char *device,
ply_terminal_t *terminal,
ply_device_manager_t *manager)
{
ply_hashtable_remove (manager->terminals, device);
ply_terminal_close (terminal);
ply_terminal_free (terminal);
}
static void
free_terminals (ply_device_manager_t *manager)
{
ply_hashtable_foreach (manager->terminals,
(ply_hashtable_foreach_func_t *)
free_terminal,
manager);
}
static ply_terminal_t *
get_terminal (ply_device_manager_t *manager,
const char *device_name)
{
char *full_name = NULL;
ply_terminal_t *terminal;
if (strncmp (device_name, "/dev/", strlen ("/dev/")) == 0)
full_name = strdup (device_name);
else
asprintf (&full_name, "/dev/%s", device_name);
if (strcmp (full_name, "/dev/tty0") == 0 ||
strcmp (full_name, "/dev/tty") == 0)
{
terminal = manager->local_console_terminal;
goto done;
}
terminal = ply_hashtable_lookup (manager->terminals, full_name);
if (terminal == NULL)
{
terminal = ply_terminal_new (full_name);
ply_hashtable_insert (manager->terminals,
(void *) ply_terminal_get_name (terminal),
terminal);
}
done:
free (full_name);
return terminal;
}
ply_device_manager_t *
ply_device_manager_new (const char *default_tty,
ply_device_manager_flags_t flags)
{
ply_device_manager_t *manager;
manager = calloc (1, sizeof (ply_device_manager_t));
manager->loop = NULL;
manager->terminals = ply_hashtable_new (ply_hashtable_string_hash, ply_hashtable_string_compare);
manager->local_console_terminal = ply_terminal_new (default_tty);
ply_hashtable_insert (manager->terminals,
(void *) ply_terminal_get_name (manager->local_console_terminal),
manager->local_console_terminal);
manager->seats = ply_list_new ();
manager->flags = flags;
if (!(flags & PLY_DEVICE_MANAGER_FLAGS_IGNORE_UDEV))
manager->udev_context = udev_new ();
attach_to_event_loop (manager, ply_event_loop_get_default ());
return manager;
}
void
ply_device_manager_free (ply_device_manager_t *manager)
{
ply_trace ("freeing device manager");
if (manager == NULL)
return;
free_seats (manager);
ply_list_free (manager->seats);
free_terminals (manager);
ply_hashtable_free (manager->terminals);
if (manager->udev_monitor != NULL)
udev_monitor_unref (manager->udev_monitor);
if (manager->udev_context != NULL)
udev_unref (manager->udev_context);
free (manager);
}
static int
add_consoles_from_file (ply_device_manager_t *manager,
const char *path)
{
int fd;
char contents[512] = "";
ssize_t contents_length;
int num_consoles;
const char *remaining_file_contents;
ply_trace ("opening %s", path);
fd = open (path, O_RDONLY);
if (fd < 0)
{
ply_trace ("couldn't open it: %m");
return 0;
}
ply_trace ("reading file");
contents_length = read (fd, contents, sizeof (contents) - 1);
if (contents_length <= 0)
{
ply_trace ("couldn't read it: %m");
close (fd);
return 0;
}
close (fd);
remaining_file_contents = contents;
num_consoles = 0;
while (remaining_file_contents < contents + contents_length)
{
char *console;
size_t console_length;
const char *console_device;
ply_terminal_t *terminal;
/* Advance past any leading whitespace */
remaining_file_contents += strspn (remaining_file_contents, " \n\t\v");
if (*remaining_file_contents == '\0')
{
/* There's nothing left after the whitespace, we're done */
break;
}
/* Find trailing whitespace and NUL terminate. If strcspn
* doesn't find whitespace, it gives us the length of the string
* until the next NUL byte, which we'll just overwrite with
* another NUL byte anyway. */
console_length = strcspn (remaining_file_contents, " \n\t\v");
console = strndup (remaining_file_contents, console_length);
terminal = get_terminal (manager, console);
console_device = ply_terminal_get_name (terminal);
free (console);
ply_trace ("console %s found!", console_device);
num_consoles++;
/* Move past the parsed console string, and the whitespace we
* may have found above. If we found a NUL above and not whitespace,
* then we're going to jump past the end of the buffer and the loop
* will terminate
*/
remaining_file_contents += console_length + 1;
}
return num_consoles;
}
static void
create_seat_for_terminal_and_renderer_type (ply_device_manager_t *manager,
const char *device_path,
ply_terminal_t *terminal,
ply_renderer_type_t renderer_type)
{
ply_seat_t *seat;
ply_trace ("creating seat for %s (renderer type: %u) (terminal: %s)",
device_path? : "", renderer_type, terminal? ply_terminal_get_name (terminal): "none");
seat = ply_seat_new (terminal);
if (!ply_seat_open (seat, renderer_type, device_path))
{
ply_trace ("could not create seat");
ply_seat_free (seat);
return;
}
ply_list_append_data (manager->seats, seat);
if (manager->seat_added_handler != NULL)
manager->seat_added_handler (manager->seat_event_handler_data, seat);
}
static void
create_seat_for_terminal (const char *device_path,
ply_terminal_t *terminal,
ply_device_manager_t *manager)
{
create_seat_for_terminal_and_renderer_type (manager,
device_path,
terminal,
PLY_RENDERER_TYPE_NONE);
}
static bool
create_seats_from_terminals (ply_device_manager_t *manager)
{
int num_consoles;
bool seats_created;
ply_trace ("checking for consoles");
if (manager->flags & PLY_DEVICE_MANAGER_FLAGS_IGNORE_SERIAL_CONSOLES)
{
num_consoles = 0;
ply_trace ("ignoring all consoles but default console because explicitly told to.");
}
else
{
num_consoles = add_consoles_from_file (manager, "/sys/class/tty/console/active");
if (num_consoles == 0)
ply_trace ("ignoring all consoles but default console because /sys/class/tty/console/active could not be read");
}
if (num_consoles > 1)
{
ply_trace ("serial consoles detected, managing them with details forced");
ply_hashtable_foreach (manager->terminals,
(ply_hashtable_foreach_func_t *)
create_seat_for_terminal,
manager);
seats_created = true;
}
else if (num_consoles <= 1 && (manager->flags & PLY_DEVICE_MANAGER_FLAGS_IGNORE_UDEV))
{
ply_trace ("udev disabled, managing seat right away");
create_seat_for_terminal_and_renderer_type (manager,
ply_terminal_get_name (manager->local_console_terminal),
manager->local_console_terminal,
PLY_RENDERER_TYPE_AUTO);
seats_created = true;
}
else
{
ply_trace ("will manage seat when ready");
seats_created = false;
}
return seats_created;
}
void
ply_device_manager_watch_seats (ply_device_manager_t *manager,
ply_seat_added_handler_t seat_added_handler,
ply_seat_removed_handler_t seat_removed_handler,
void *data)
{
bool seats_created;
manager->seat_added_handler = seat_added_handler;
manager->seat_removed_handler = seat_removed_handler;
manager->seat_event_handler_data = data;
/* Try to create seats for each terminal device right away, if possible
*/
seats_created = create_seats_from_terminals (manager);
/* In most cases, though, we need to create devices based on udev device topology
*/
if (!seats_created)
{
watch_for_udev_events (manager);
scan_graphics_devices (manager);
}
}
bool
ply_device_manager_has_open_seats (ply_device_manager_t *manager)
{
ply_list_node_t *node;
node = ply_list_get_first_node (manager->seats);
while (node != NULL)
{
ply_seat_t *seat;
ply_list_node_t *next_node;
seat = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (manager->seats, node);
if (ply_seat_is_open (seat))
return true;
node = next_node;
}
return false;
}
ply_list_t *
ply_device_manager_get_seats (ply_device_manager_t *manager)
{
return manager->seats;
}
ply_terminal_t *
ply_device_manager_get_default_terminal (ply_device_manager_t *manager)
{
return manager->local_console_terminal;
}
void
ply_device_manager_activate_renderers (ply_device_manager_t *manager)
{
ply_list_node_t *node;
ply_trace ("activating renderers");
node = ply_list_get_first_node (manager->seats);
while (node != NULL)
{
ply_seat_t *seat;
ply_list_node_t *next_node;
seat = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (manager->seats, node);
ply_seat_activate_renderer (seat);
node = next_node;
}
}
void
ply_device_manager_deactivate_renderers (ply_device_manager_t *manager)
{
ply_list_node_t *node;
ply_trace ("deactivating renderers");
node = ply_list_get_first_node (manager->seats);
while (node != NULL)
{
ply_seat_t *seat;
ply_list_node_t *next_node;
seat = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (manager->seats, node);
ply_seat_deactivate_renderer (seat);
node = next_node;
}
}
void
ply_device_manager_activate_keyboards (ply_device_manager_t *manager)
{
ply_list_node_t *node;
ply_trace ("activating keyboards");
node = ply_list_get_first_node (manager->seats);
while (node != NULL)
{
ply_seat_t *seat;
ply_list_node_t *next_node;
seat = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (manager->seats, node);
ply_seat_activate_keyboard (seat);
node = next_node;
}
}
void
ply_device_manager_deactivate_keyboards (ply_device_manager_t *manager)
{
ply_list_node_t *node;
ply_trace ("deactivating keyboards");
node = ply_list_get_first_node (manager->seats);
while (node != NULL)
{
ply_seat_t *seat;
ply_list_node_t *next_node;
seat = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (manager->seats, node);
ply_seat_deactivate_keyboard (seat);
node = next_node;
}
}

View file

@ -0,0 +1,56 @@
/* ply-device-manager.h - udev monitor
*
* Copyright (C) 2013 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.
*/
#ifndef PLY_DEVICE_MANAGER_H
#define PLY_DEVICE_MANAGER_H
#include <stdbool.h>
#include "ply-seat.h"
typedef enum
{
PLY_DEVICE_MANAGER_FLAGS_NONE = 0,
PLY_DEVICE_MANAGER_FLAGS_IGNORE_SERIAL_CONSOLES = 1 << 0,
PLY_DEVICE_MANAGER_FLAGS_IGNORE_UDEV = 1 << 1
} ply_device_manager_flags_t;
typedef struct _ply_device_manager ply_device_manager_t;
typedef void (* ply_seat_added_handler_t) (void *, ply_seat_t *);
typedef void (* ply_seat_removed_handler_t) (void *, ply_seat_t *);
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
ply_device_manager_t *ply_device_manager_new (const char *default_tty,
ply_device_manager_flags_t flags);
void ply_device_manager_watch_seats (ply_device_manager_t *manager,
ply_seat_added_handler_t seat_added_handler,
ply_seat_removed_handler_t seat_removed_handler,
void *data);
bool ply_device_manager_has_open_seats (ply_device_manager_t *manager);
ply_list_t *ply_device_manager_get_seats (ply_device_manager_t *manager);
void ply_device_manager_free (ply_device_manager_t *manager);
void ply_device_manager_activate_keyboards (ply_device_manager_t *manager);
void ply_device_manager_deactivate_keyboards (ply_device_manager_t *manager);
void ply_device_manager_activate_renderers (ply_device_manager_t *manager);
void ply_device_manager_deactivate_renderers (ply_device_manager_t *manager);
ply_terminal_t *ply_device_manager_get_default_terminal (ply_device_manager_t *manager);
#endif
#endif
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -49,7 +49,7 @@ struct _ply_renderer
const ply_renderer_plugin_interface_t *plugin_interface;
ply_renderer_backend_t *backend;
char *plugin_path;
ply_renderer_type_t type;
char *device_name;
ply_terminal_t *terminal;
@ -63,16 +63,15 @@ typedef const ply_renderer_plugin_interface_t *
static void ply_renderer_unload_plugin (ply_renderer_t *renderer);
ply_renderer_t *
ply_renderer_new (const char *plugin_path,
const char *device_name,
ply_terminal_t *terminal)
ply_renderer_new (ply_renderer_type_t renderer_type,
const char *device_name,
ply_terminal_t *terminal)
{
ply_renderer_t *renderer;
renderer = calloc (1, sizeof (struct _ply_renderer));
if (plugin_path != NULL)
renderer->plugin_path = strdup (plugin_path);
renderer->type = renderer_type;
if (device_name != NULL)
renderer->device_name = strdup (device_name);
@ -95,10 +94,15 @@ ply_renderer_free (ply_renderer_t *renderer)
}
free (renderer->device_name);
free (renderer->plugin_path);
free (renderer);
}
const char *
ply_renderer_get_device_name (ply_renderer_t *renderer)
{
return renderer->device_name;
}
static bool
ply_renderer_load_plugin (ply_renderer_t *renderer,
const char *module_path)
@ -258,29 +262,28 @@ ply_renderer_open (ply_renderer_t *renderer)
{
int i;
/* FIXME: at some point we may want to make this
* part more dynamic (so you don't have to edit this
* list to add a new renderer)
*/
const char *known_plugins[] =
struct
{
PLYMOUTH_PLUGIN_PATH "renderers/x11.so",
PLYMOUTH_PLUGIN_PATH "renderers/drm.so",
PLYMOUTH_PLUGIN_PATH "renderers/frame-buffer.so",
NULL
ply_renderer_type_t type;
const char *path;
} known_plugins[] =
{
{ PLY_RENDERER_TYPE_X11, PLYMOUTH_PLUGIN_PATH "renderers/x11.so" },
{ PLY_RENDERER_TYPE_DRM, PLYMOUTH_PLUGIN_PATH "renderers/drm.so" },
{ PLY_RENDERER_TYPE_FRAME_BUFFER, PLYMOUTH_PLUGIN_PATH "renderers/frame-buffer.so" },
{ PLY_RENDERER_TYPE_NONE, NULL }
};
if (renderer->plugin_path != NULL)
for (i = 0; known_plugins[i].type != PLY_RENDERER_TYPE_NONE; i++)
{
return ply_renderer_open_plugin (renderer, renderer->plugin_path);
if (renderer->type == known_plugins[i].type ||
renderer->type == PLY_RENDERER_TYPE_AUTO)
{
if (ply_renderer_open_plugin (renderer, known_plugins[i].path))
return true;
}
}
for (i = 0; known_plugins[i] != NULL; i++)
{
if (ply_renderer_open_plugin (renderer, known_plugins[i]))
return true;
}
ply_trace ("could not find suitable rendering plugin");
return false;
}

View file

@ -35,12 +35,21 @@ typedef struct _ply_renderer ply_renderer_t;
typedef struct _ply_renderer_head ply_renderer_head_t;
typedef struct _ply_renderer_input_source ply_renderer_input_source_t;
typedef enum
{
PLY_RENDERER_TYPE_NONE = -1,
PLY_RENDERER_TYPE_AUTO,
PLY_RENDERER_TYPE_DRM,
PLY_RENDERER_TYPE_FRAME_BUFFER,
PLY_RENDERER_TYPE_X11
} ply_renderer_type_t;
typedef void (* ply_renderer_input_source_handler_t) (void *user_data,
ply_buffer_t *key_buffer,
ply_renderer_input_source_t *input_source);
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
ply_renderer_t *ply_renderer_new (const char *plugin_path,
ply_renderer_t *ply_renderer_new (ply_renderer_type_t renderer_type,
const char *device_name,
ply_terminal_t *terminal);
void ply_renderer_free (ply_renderer_t *renderer);
@ -48,6 +57,7 @@ bool ply_renderer_open (ply_renderer_t *renderer);
void ply_renderer_close (ply_renderer_t *renderer);
void ply_renderer_activate (ply_renderer_t *renderer);
void ply_renderer_deactivate (ply_renderer_t *renderer);
const char *ply_renderer_get_device_name (ply_renderer_t *renderer);
ply_list_t *ply_renderer_get_heads (ply_renderer_t *renderer);
ply_pixel_buffer_t *ply_renderer_get_buffer_for_head (ply_renderer_t *renderer,
ply_renderer_head_t *head);

View file

@ -0,0 +1,365 @@
/* ply-seat.c - APIs for encapsulating a keyboard and one or more displays
*
* Copyright (C) 2013 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-seat.h"
#include <assert.h>
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "ply-boot-splash.h"
#include "ply-event-loop.h"
#include "ply-keyboard.h"
#include "ply-pixel-display.h"
#include "ply-text-display.h"
#include "ply-list.h"
#include "ply-logger.h"
#include "ply-utils.h"
struct _ply_seat
{
ply_event_loop_t *loop;
ply_boot_splash_t *splash;
ply_terminal_t *terminal;
ply_renderer_t *renderer;
ply_keyboard_t *keyboard;
ply_list_t *text_displays;
ply_list_t *pixel_displays;
uint32_t renderer_active : 1;
uint32_t keyboard_active : 1;
};
ply_seat_t *
ply_seat_new (ply_terminal_t *terminal)
{
ply_seat_t *seat;
seat = calloc (1, sizeof (ply_seat_t));
seat->loop = ply_event_loop_get_default ();
seat->terminal = terminal;
seat->text_displays = ply_list_new ();
seat->pixel_displays = ply_list_new ();
return seat;
}
static void
add_pixel_displays (ply_seat_t *seat)
{
ply_list_t *heads;
ply_list_node_t *node;
heads = ply_renderer_get_heads (seat->renderer);
ply_trace ("Adding displays for %d heads",
ply_list_get_length (heads));
node = ply_list_get_first_node (heads);
while (node != NULL)
{
ply_list_node_t *next_node;
ply_renderer_head_t *head;
ply_pixel_display_t *display;
head = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (heads, node);
display = ply_pixel_display_new (seat->renderer, head);
ply_list_append_data (seat->pixel_displays, display);
node = next_node;
}
}
static void
add_text_displays (ply_seat_t *seat)
{
ply_text_display_t *display;
display = ply_text_display_new (seat->terminal);
ply_list_append_data (seat->text_displays, display);
}
bool
ply_seat_open (ply_seat_t *seat,
ply_renderer_type_t renderer_type,
const char *device)
{
if (renderer_type != PLY_RENDERER_TYPE_NONE)
{
ply_renderer_t *renderer;
renderer = ply_renderer_new (renderer_type, device, seat->terminal);
if (!ply_renderer_open (renderer) && renderer_type != PLY_RENDERER_TYPE_AUTO)
{
ply_trace ("could not open renderer for %s", device);
ply_renderer_free (renderer);
return false;
}
seat->renderer = renderer;
seat->renderer_active = true;
}
if (seat->renderer != NULL)
{
seat->keyboard = ply_keyboard_new_for_renderer (seat->renderer);
add_pixel_displays (seat);
}
else
{
seat->keyboard = ply_keyboard_new_for_terminal (seat->terminal);
add_text_displays (seat);
}
seat->keyboard_active = true;
return true;
}
bool
ply_seat_is_open (ply_seat_t *seat)
{
return ply_list_get_length (seat->pixel_displays) > 0 ||
ply_list_get_length (seat->text_displays) > 0;
}
void
ply_seat_deactivate_keyboard (ply_seat_t *seat)
{
if (!seat->keyboard_active)
return;
seat->keyboard_active = false;
if (seat->keyboard == NULL)
return;
ply_trace ("deactivating keybord");
ply_keyboard_stop_watching_for_input (seat->keyboard);
}
void
ply_seat_deactivate_renderer (ply_seat_t *seat)
{
if (!seat->renderer_active)
return;
seat->renderer_active = false;
if (seat->renderer == NULL)
return;
ply_trace ("deactivating renderer");
ply_renderer_deactivate (seat->renderer);
}
void
ply_seat_activate_keyboard (ply_seat_t *seat)
{
if (seat->keyboard_active)
return;
if (seat->keyboard == NULL)
return;
ply_trace ("activating keyboard");
ply_keyboard_watch_for_input (seat->keyboard);
seat->keyboard_active = true;
}
void
ply_seat_activate_renderer (ply_seat_t *seat)
{
if (seat->renderer_active)
return;
if (seat->renderer == NULL)
return;
ply_trace ("activating renderer");
ply_renderer_activate (seat->renderer);
seat->renderer_active = true;
}
void
ply_seat_refresh_displays (ply_seat_t *seat)
{
ply_list_node_t *node;
node = ply_list_get_first_node (seat->pixel_displays);
while (node != NULL)
{
ply_pixel_display_t *display;
ply_list_node_t *next_node;
unsigned long width, height;
display = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (seat->pixel_displays, node);
width = ply_pixel_display_get_width (display);
height = ply_pixel_display_get_height (display);
ply_pixel_display_draw_area (display, 0, 0, width, height);
node = next_node;
}
node = ply_list_get_first_node (seat->text_displays);
while (node != NULL)
{
ply_text_display_t *display;
ply_list_node_t *next_node;
int number_of_columns, number_of_rows;
display = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (seat->text_displays, node);
number_of_columns = ply_text_display_get_number_of_columns (display);
number_of_rows = ply_text_display_get_number_of_rows (display);
ply_text_display_draw_area (display, 0, 0,
number_of_columns,
number_of_rows);
node = next_node;
}
}
void
ply_seat_close (ply_seat_t *seat)
{
if (seat->renderer == NULL)
return;
ply_trace ("destroying renderer");
ply_renderer_close (seat->renderer);
ply_renderer_free (seat->renderer);
seat->renderer = NULL;
}
void
ply_seat_set_splash (ply_seat_t *seat,
ply_boot_splash_t *splash)
{
if (seat->splash == splash)
return;
if (seat->splash != NULL)
ply_boot_splash_detach_from_seat (splash, seat);
if (splash != NULL)
ply_boot_splash_attach_to_seat (splash, seat);
seat->splash = splash;
}
static void
free_pixel_displays (ply_seat_t *seat)
{
ply_list_node_t *node;
ply_trace ("freeing %d pixel displays", ply_list_get_length (seat->pixel_displays));
node = ply_list_get_first_node (seat->pixel_displays);
while (node != NULL)
{
ply_list_node_t *next_node;
ply_pixel_display_t *display;
next_node = ply_list_get_next_node (seat->pixel_displays, node);
display = ply_list_node_get_data (node);
ply_pixel_display_free (display);
ply_list_remove_node (seat->pixel_displays, node);
node = next_node;
}
}
static void
free_text_displays (ply_seat_t *seat)
{
ply_list_node_t *node;
ply_trace ("freeing %d text displays", ply_list_get_length (seat->text_displays));
node = ply_list_get_first_node (seat->text_displays);
while (node != NULL)
{
ply_list_node_t *next_node;
ply_text_display_t *display;
next_node = ply_list_get_next_node (seat->text_displays, node);
display = ply_list_node_get_data (node);
ply_text_display_free (display);
ply_list_remove_node (seat->text_displays, node);
node = next_node;
}
}
void
ply_seat_free (ply_seat_t *seat)
{
if (seat == NULL)
return;
free_pixel_displays (seat);
free_text_displays (seat);
ply_keyboard_free (seat->keyboard);
free (seat);
}
ply_list_t *
ply_seat_get_pixel_displays (ply_seat_t *seat)
{
return seat->pixel_displays;
}
ply_list_t *
ply_seat_get_text_displays (ply_seat_t *seat)
{
return seat->text_displays;
}
ply_keyboard_t *
ply_seat_get_keyboard (ply_seat_t *seat)
{
return seat->keyboard;
}
ply_renderer_t *
ply_seat_get_renderer (ply_seat_t *seat)
{
return seat->renderer;
}
/* vim: set ts=4 sw=4 et ai ci cino={.5s,^-2,+.5s,t0,g0,e-2,n-2,p2s,(0,=.5s,:.5s */

View file

@ -0,0 +1,66 @@
/* ply-seat.h - APIs for encapsulating a keyboard and one or more displays
*
* Copyright (C) 2013 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>
*/
#ifndef PLY_SEAT_H
#define PLY_SEAT_H
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <unistd.h>
#include "ply-boot-splash.h"
#include "ply-buffer.h"
#include "ply-event-loop.h"
#include "ply-keyboard.h"
#include "ply-list.h"
#include "ply-pixel-display.h"
#include "ply-terminal.h"
#include "ply-text-display.h"
typedef struct _ply_boot_splash ply_boot_splash_t;
typedef struct _ply_seat ply_seat_t;
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
ply_seat_t *ply_seat_new (ply_terminal_t *terminal);
void ply_seat_free (ply_seat_t *seat);
bool ply_seat_open (ply_seat_t *seat,
ply_renderer_type_t renderer_type,
const char *device);
bool ply_seat_is_open (ply_seat_t *seat);
void ply_seat_deactivate_keyboard (ply_seat_t *seat);
void ply_seat_activate_keyboard (ply_seat_t *seat);
void ply_seat_deactivate_renderer (ply_seat_t *seat);
void ply_seat_activate_renderer (ply_seat_t *seat);
void ply_seat_refresh_displays (ply_seat_t *seat);
void ply_seat_close (ply_seat_t *seat);
void ply_seat_set_splash (ply_seat_t *seat,
ply_boot_splash_t *splash);
ply_list_t *ply_seat_get_pixel_displays (ply_seat_t *seat);
ply_list_t *ply_seat_get_text_displays (ply_seat_t *seat);
ply_keyboard_t *ply_seat_get_keyboard (ply_seat_t *seat);
ply_renderer_t *ply_seat_get_renderer (ply_seat_t *seat);
#endif
#endif /* PLY_SEAT_H */
/* vim: set ts=4 sw=4 et ai ci cino={.5s,^-2,+.5s,t0,g0,e-2,n-2,p2s,(0,=.5s,:.5s */

View file

@ -876,6 +876,12 @@ ply_terminal_free (ply_terminal_t *terminal)
free (terminal);
}
const char *
ply_terminal_get_name (ply_terminal_t *terminal)
{
return terminal->name;
}
int
ply_terminal_get_vt_number (ply_terminal_t *terminal)
{

View file

@ -91,6 +91,7 @@ void ply_terminal_set_mode (ply_terminal_t *terminal,
void ply_terminal_ignore_mode_changes (ply_terminal_t *terminal,
bool should_ignore);
const char *ply_terminal_get_name (ply_terminal_t *terminal);
int ply_terminal_get_vt_number (ply_terminal_t *terminal);
bool ply_terminal_activate_vt (ply_terminal_t *terminal);
bool ply_terminal_deactivate_vt (ply_terminal_t *terminal);

View file

@ -1,4 +1,3 @@
SUBDIRS = tests
INCLUDES = -I$(top_srcdir) \
-I$(srcdir) \
-DPLYMOUTH_TIME_DIRECTORY=\"$(localstatedir)/lib/plymouth/\"

View file

@ -171,34 +171,4 @@ ply_array_steal_uint32_elements (ply_array_t *array)
return data;
}
#ifdef PLY_ARRAY_ENABLE_TEST
#include <stdio.h>
int
main (int argc,
char **argv)
{
ply_array_t *array;
int i;
char **data;
array = ply_array_new (PLY_ARRAY_ELEMENT_TYPE_POINTER);
ply_array_add_pointer_element (array, "foo");
ply_array_add_pointer_element (array, "bar");
ply_array_add_pointer_element (array, "baz");
ply_array_add_pointer_element (array, "qux");
data = (char **) ply_array_get_pointer_elements (array);
for (i = 0; data[i] != NULL; i++)
{
printf ("element '%d' has data '%s'\n", i, data[i]);
i++;
}
ply_array_free (array);
return 0;
}
#endif
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -42,64 +42,4 @@ ply_bitarray_count (ply_bitarray_t *bitarray,
return count;
}
#ifdef PLY_BITARRAY_ENABLE_TEST
#include <stdio.h>
int
main (int argc,
char **argv)
{
ply_bitarray_t *bitarray;
int i, i2;
printf ("bitarray test start\n");
bitarray = ply_bitarray_new (134);
for (i=0; i<64; i++)
{
if (ply_bitarray_lookup (bitarray, i))
printf ("1");
else
printf ("0");
}
printf ("\n");
for (i=0; i<64; i++)
if ((6654654654654654654ll >> i) & 1)
ply_bitarray_set (bitarray, i);
for (i=0; i<64; i++)
{
if (ply_bitarray_lookup (bitarray, i))
printf ("1");
else
printf ("0");
}
printf ("\n");
for (i = 63; i > 0; i--)
{
if ((6654654654654654654ll >> i) & 1)
{
ply_bitarray_clear (bitarray, i);
for (i2 = 0; i2 < 64; i2++)
{
if (ply_bitarray_lookup (bitarray, i2))
printf ("1");
else
printf ("0");
}
printf ("\n");
}
}
ply_bitarray_free (bitarray);
printf ("bitarray test end\n");
return 0;
}
#endif
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -263,22 +263,4 @@ ply_buffer_clear (ply_buffer_t *buffer)
buffer->size = 0;
}
#ifdef PLY_BUFFER_ENABLE_TEST
int
main (int argc,
char **argv)
{
int exit_code;
ply_buffer_t *buffer;
exit_code = 0;
buffer = ply_buffer_new ();
ply_buffer_append (buffer, "yo yo yo\n");
ply_buffer_free (buffer);
return exit_code;
}
#endif /* PLY_BUFFER_ENABLE_TEST */
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -968,100 +968,4 @@ ply_command_parser_parse_arguments (ply_command_parser_t *parser,
return parsed_arguments;
}
#ifdef PLY_COMMAND_PARSER_ENABLE_TEST
#include <stdio.h>
#include "ply-command-parser.h"
#include "ply-event-loop.h"
#include "ply-logger.h"
static void
on_ask_for_password (ply_command_parser_t *parser,
const char *command)
{
char *prompt;
char *program;
prompt = NULL;
program = NULL;
ply_command_parser_get_command_options (parser, command, "prompt", &prompt, "command", &program, NULL);
printf ("ask for password with prompt '%s' feed result to '%s'\n", prompt, program);
free (prompt);
free (program);
}
static void
on_show_splash (ply_command_parser_t *parser,
const char *command)
{
char *plugin_name;
plugin_name = NULL;
ply_command_parser_get_command_options (parser, command, "plugin-name", &plugin_name, NULL);
printf ("show splash plugin '%s'\n", plugin_name);
free (plugin_name);
}
int
main (int argc,
char **argv)
{
ply_event_loop_t *loop;
ply_command_parser_t *parser;
bool should_help;
loop = ply_event_loop_new ();
parser = ply_command_parser_new (argv[0], "Test Program");
ply_command_parser_add_options (parser,
"help", "This help message", PLY_COMMAND_OPTION_TYPE_FLAG,
NULL);
ply_command_parser_add_command (parser,
"ask-for-password",
"Ask user for password",
(ply_command_handler_t)
on_ask_for_password, parser,
"command", "command to pipe result to", PLY_COMMAND_OPTION_TYPE_STRING,
"prompt", "string to present to user", PLY_COMMAND_OPTION_TYPE_STRING,
"output-result", "print result", PLY_COMMAND_OPTION_TYPE_BOOLEAN,
NULL);
ply_command_parser_add_command (parser,
"show-splash",
"Show splash to user",
(ply_command_handler_t)
on_show_splash, parser,
"plugin-name", "name of the plugin to run", PLY_COMMAND_OPTION_TYPE_STRING,
NULL);
if (!ply_command_parser_parse_arguments (parser, loop, argv, argc))
{
ply_error ("couldn't parse arguments");
return 1;
}
ply_command_parser_get_options (parser, "help", &should_help, NULL);
if (should_help)
{
char *usage;
usage = ply_command_parser_get_help_string (parser);
printf ("%s\n", usage);
free (usage);
return 0;
}
ply_event_loop_run (loop);
ply_command_parser_free (parser);
return 0;
}
#endif
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -1376,88 +1376,4 @@ ply_event_loop_run (ply_event_loop_t *loop)
return loop->exit_code;
}
#ifdef PLY_EVENT_LOOP_ENABLE_TEST
static ply_event_loop_t *loop;
static void
alrm_signal_handler (void)
{
write (1, "times up!\n", sizeof ("times up!\n") - 1);
ply_event_loop_exit (loop, 0);
}
static void
usr1_signal_handler (void)
{
write (1, "got sigusr1\n", sizeof ("got sigusr1\n") - 1);
}
static void
hangup_signal_handler (void)
{
write (1, "got hangup\n", sizeof ("got hangup\n") - 1);
}
static void
terminate_signal_handler (void)
{
write (1, "got terminate\n", sizeof ("got terminate\n") - 1);
ply_event_loop_exit (loop, 0);
}
static void
line_received_handler (void)
{
char line[512] = { 0 };
printf ("Received line: ");
fflush (stdout);
fgets (line, sizeof (line), stdin);
printf ("%s", line);
}
static void
on_timeout (ply_event_loop_t *loop)
{
printf ("timeout elapsed\n");
}
int
main (int argc,
char **argv)
{
int exit_code;
loop = ply_event_loop_new ();
ply_event_loop_watch_signal (loop, SIGHUP,
(ply_event_handler_t) hangup_signal_handler,
NULL);
ply_event_loop_watch_signal (loop, SIGTERM,
(ply_event_handler_t)
terminate_signal_handler, NULL);
ply_event_loop_watch_signal (loop, SIGUSR1,
(ply_event_handler_t)
usr1_signal_handler, NULL);
ply_event_loop_watch_signal (loop, SIGALRM,
(ply_event_handler_t)
alrm_signal_handler, NULL);
ply_event_loop_watch_for_timeout (loop, 2.0,
(ply_event_loop_timeout_handler_t)
on_timeout, loop);
ply_event_loop_watch_fd (loop, 0, PLY_EVENT_LOOP_FD_STATUS_HAS_DATA,
(ply_event_handler_t) line_received_handler,
(ply_event_handler_t) line_received_handler,
NULL);
alarm (5);
exit_code = ply_event_loop_run (loop);
ply_event_loop_free (loop);
return exit_code;
}
#endif /* PLY_EVENT_LOOP_ENABLE_TEST */
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -130,14 +130,6 @@ ply_hashtable_insert_internal (ply_hashtable_t *hashtable,
{
unsigned int hash_index;
int step = 0;
#ifdef PLY_HASHTABLE_ENABLE_TEST
/* Make sure the counts are synchronised with bitmap */
assert (ply_bitarray_count (hashtable->dirty_node_bitmap, hashtable->total_node_count) ==
(int) hashtable->dirty_node_count);
assert (ply_bitarray_count (hashtable->live_node_bitmap, hashtable->total_node_count) ==
(int) hashtable->live_node_count);
#endif /* PLY_HASHTABLE_ENABLE_TEST */
hash_index = hashtable->hash_func (key);
hash_index &= hashtable->total_node_count - 1;
@ -281,56 +273,10 @@ ply_hashtable_foreach (ply_hashtable_t *hashtable,
}
}
#ifdef PLY_HASHTABLE_ENABLE_TEST
#include <stdio.h>
static void
foreach_func (void *key,
void *data,
void *user_data)
{
printf ("foreach key:%s data:%s\n", (char*) key, (char*) data);
}
int
main (int argc,
char **argv)
ply_hashtable_get_size (ply_hashtable_t *hashtable)
{
ply_hashtable_t *hashtable;
int i;
const char* key[10] = {"k1", "k2", "k3", "k4", "k5", "k6", "k7", "k8", "k9", "k10"};
const char* data[10] = {"d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10"};
char* reply_key = NULL;
char* reply_data = NULL;
printf ("hashtable test start\n");
hashtable = ply_hashtable_new (ply_hashtable_string_hash, ply_hashtable_string_compare);
for (i=0; i<10; i++)
{
ply_hashtable_insert (hashtable, (void *) key[i], (void *) data[9-i]);
}
for (i=0; i<10; i++)
{
reply_data = ply_hashtable_lookup (hashtable, (void *) key[i]);
printf ("got:%s\n", reply_data);
}
for (i=0; i<10; i++)
{
ply_hashtable_remove (hashtable, (void *) key[i]);
ply_hashtable_insert (hashtable, (void *) key[i], (void *) data[i]);
}
for (i=0; i<10; i++)
{
if (ply_hashtable_lookup_full (hashtable, (void *) key[i], (void**) &reply_key, (void**) &reply_data))
printf ("got key:%s data:%s\n", reply_key, reply_data);
}
ply_hashtable_foreach (hashtable, foreach_func, NULL);
ply_hashtable_free(hashtable);
printf ("hashtable test end\n");
return 0;
return hashtable->live_node_count;
}
#endif
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -57,6 +57,8 @@ int ply_hashtable_lookup_full (ply_hashtable_t *hashtable,
void ply_hashtable_foreach (ply_hashtable_t *hashtable,
ply_hashtable_foreach_func_t func,
void *user_data);
int ply_hashtable_get_size (ply_hashtable_t *hashtable);
#endif
#endif /* PLY_HASHTABLE_H */

View file

@ -375,85 +375,4 @@ ply_list_node_get_data (ply_list_node_t *node)
return node->data;
}
#ifdef PLY_LIST_ENABLE_TEST
#include <stdio.h>
static int
compare_int_ptr (void *element_a,
void *element_b)
{
int *int_a = element_a;
int *int_b = element_b;
return *int_a - *int_b;
}
int
main (int argc,
char **argv)
{
ply_list_t *list;
ply_list_node_t *node;
int i, lastval;
int *value;
int errors;
errors = 0;
list = ply_list_new ();
ply_list_append_data (list, (void *) "foo");
ply_list_append_data (list, (void *) "bar");
ply_list_append_data (list, (void *) "baz");
ply_list_prepend_data (list, (void *) "qux");
ply_list_prepend_data (list, (void *) "quux");
ply_list_remove_data (list, (void *) "baz");
ply_list_remove_data (list, (void *) "foo");
node = ply_list_get_first_node (list);
i = 0;
while (node != NULL)
{
printf ("node '%d' has data '%s'\n", i,
(char *) ply_list_node_get_data (node));
node = ply_list_get_next_node (list, node);
i++;
}
printf ("\n");
ply_list_remove_all_nodes (list);
srandom(1);
for (i = 0; i<100; i++)
{
value = malloc (sizeof (int));
*value = random() % 100;
ply_list_append_data (list, (void *) value);
}
ply_list_sort (list, compare_int_ptr);
node = ply_list_get_first_node (list);
i = 0;
lastval = 0;
while (node != NULL)
{
value = (int *) ply_list_node_get_data (node);
if (*value < lastval)
{
printf ("ERROR: incorrect order\n");
errors = 1;
}
lastval = *value;
printf ("node '%d' has data '%d'\n", i, *value);
node = ply_list_get_next_node (list, node);
i++;
}
ply_list_free (list);
return errors;
}
#endif
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -598,26 +598,4 @@ ply_logger_is_tracing_enabled (ply_logger_t *logger)
}
#endif /* PLY_ENABLE_TRACING */
#ifdef PLY_LOGGER_ENABLE_TEST
int
main (int argc,
char **argv)
{
int exit_code;
ply_logger_t *logger;
exit_code = 0;
logger = ply_logger_new ();
ply_logger_inject (logger, "yo yo yo\n");
ply_logger_set_output_fd (logger, 1);
ply_logger_inject (logger, "yo yo yo yo\n");
ply_logger_flush (logger);
ply_logger_free (logger);
return exit_code;
}
#endif /* PLY_LOGGER_ENABLE_TEST */
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -330,75 +330,5 @@ ply_progress_status_update (ply_progress_t* progress,
}
}
#ifdef PLY_PROGRESS_ENABLE_TEST
#include <stdio.h>
int
main (int argc,
char **argv)
{
double percent;
int slowness;
double time;
int i;
const char* strings[10]={"foobar", "barfoo", "barbar", "foo", "foo", "bar", "foo", "more", "even more", "even even more"};
ply_progress_t* progress = ply_progress_new ();
progress->scalar = 1.0/5; /* Original time estimate is 5 sec*/
percent = ply_progress_get_percentage (progress);
time = ply_progress_get_time (progress);
printf("Time:%f \t Percentage: %f%%\n", time, percent*100);
srand ((int) ply_get_timestamp ());
slowness = rand () % 500000 + 50000;
for (i=0; i<2; i++)
{
usleep ((rand () % slowness+slowness));
percent = ply_progress_get_percentage (progress);
time = ply_progress_get_time (progress);
printf("Time:%f \t Percentage: %f%%\n", time, percent*100);
}
printf("Load cache\n");
ply_progress_load_cache (progress, PLYMOUTH_TIME_DIRECTORY "/boot-duration");
for (i=0; i<10; i++)
{
ply_progress_status_update (progress, strings[i]);
usleep ((rand () % slowness+slowness));
percent = ply_progress_get_percentage (progress);
time = ply_progress_get_time (progress);
printf("Time:%f \t Percentage: %f%% \tScalar:%f\n", time, percent*100, progress->scalar);
}
printf("Save and free cache\n");
ply_progress_save_cache (progress, PLYMOUTH_TIME_DIRECTORY "/boot-duration");
ply_progress_free(progress);
printf("\nManual set percentage run\n\n");
progress = ply_progress_new ();
progress->scalar = 1.0/5; /* Original time estimate is 5 sec*/
percent = ply_progress_get_percentage (progress);
time = ply_progress_get_time (progress);
printf("Time:%f \t Percentage: %f%%\n", time, percent*100);
srand ((int) ply_get_timestamp ());
for (i=0; i<12; i++)
{
ply_progress_set_percentage (progress, (double)i/12);
usleep ((rand () % slowness+slowness));
percent = ply_progress_get_percentage (progress);
time = ply_progress_get_time (progress);
printf("Time:%f \t Percentage: %f%% (%f%%)\tScalar:%f\n", time, percent*100, (double)i/12*100, progress->scalar);
}
ply_progress_free(progress);
return 0;
}
#endif /* PLY_PROGRESS_ENABLE_TEST */
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -467,141 +467,4 @@ ply_region_get_sorted_rectangle_list (ply_region_t *region)
return region->rectangle_list;
}
#ifdef PLY_REGION_ENABLE_TEST
#include <stdio.h>
#define COVER_SIZE 100
#define RECTANGLE_COUNT 1000
static void
cover_with_rect(char cover[COVER_SIZE][COVER_SIZE],
ply_rectangle_t *rectangle,
char value)
{ /* is value is not zero, the entry will be set to the value,
otherwise entry is incremented*/
unsigned long x, y;
for (y=0; y<rectangle->height; y++)
{
for (x=0; x<rectangle->width; x++)
{
if (rectangle->x + x < COVER_SIZE &&
rectangle->y + y < COVER_SIZE)
{
if (value)
cover[rectangle->y + y][rectangle->x + x] = value;
else
cover[rectangle->y + y][rectangle->x + x]++;
}
}
}
}
static int
do_test (void)
{
ply_rectangle_t rectangle;
char cover[COVER_SIZE][COVER_SIZE];
int i;
unsigned long x, y;
ply_region_t *region;
ply_list_node_t *node;
region = ply_region_new ();
for (y = 0; y < COVER_SIZE; y++)
{
for (x = 0; x < COVER_SIZE; x++)
{
cover[y][x] = 0;
}
}
for (i = 0; i < RECTANGLE_COUNT; i++)
{
rectangle.x = random() % COVER_SIZE-5;
rectangle.y = random() % COVER_SIZE-5;
rectangle.width = 1 + random() % 20;
rectangle.height = 1 + random() % 20;
printf("Adding X=%ld Y=%ld W=%ld H=%ld\n",
rectangle.x,
rectangle.y,
rectangle.width,
rectangle.height);
cover_with_rect(cover, &rectangle, 100); /* 100 means covered by origial squares */
ply_region_add_rectangle (region, &rectangle);
}
printf("Converted to:\n");
int count = 0;
ply_list_t *rectangle_list = ply_region_get_rectangle_list (region);
for (node = ply_list_get_first_node (rectangle_list);
node;
node = ply_list_get_next_node (rectangle_list, node))
{
ply_rectangle_t *small_rectangle = ply_list_node_get_data (node);
printf("Processed X=%ld Y=%ld W=%ld H=%ld\n",
small_rectangle->x,
small_rectangle->y,
small_rectangle->width,
small_rectangle->height);
cover_with_rect(cover, small_rectangle, 0);
count++;
}
printf("Rectangles in:%d out:%d\n", RECTANGLE_COUNT, count);
count=0;
for (y = 0; y < COVER_SIZE; y++)
{
printf("%03ld ", y);
for (x = 0; x < COVER_SIZE; x++)
{
if (cover[y][x] >= 100)
{
if (cover[y][x] == 100)
{
printf("-"); /* "-" means should have been covered but wasn't */
count++;
}
else
{
if (cover[y][x] == 101)
printf("O"); /* "O" means correctly covered */
else
{
printf("%d", cover[y][x] - 101);
count++; /* 1+ means covered multiple times*/
}
}
}
else
{
if (cover[y][x] == 0)
printf("o"); /* "o" means not involved*/
else
{
printf("%c", 'A' - 1 + cover[y][x]);
count++; /* A+ means covered despite being not involved*/
}
}
}
printf("\n");
}
printf("errors:%d\n", count);
return count;
}
int
main (int argc,
char **argv)
{
int i;
srandom(312);
for (i=0; i<100; i++)
{
if (do_test ()) return 1;
}
return 0;
}
#endif
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -587,57 +587,4 @@ ply_terminal_session_close_log (ply_terminal_session_t *session)
return ply_logger_close_file (session->logger);
}
#ifdef PLY_TERMINAL_SESSION_ENABLE_TEST
#include <stdio.h>
#include "ply-event-loop.h"
#include "ply-terminal-session.h"
static void
on_finished (ply_event_loop_t *loop)
{
ply_event_loop_exit (loop, 0);
}
int
main (int argc,
char **argv)
{
ply_event_loop_t *loop;
ply_terminal_session_t *session;
int exit_code;
ply_terminal_session_flags_t flags;
exit_code = 0;
loop = ply_event_loop_new ();
session = ply_terminal_session_new ((const char * const *) (argv + 1));
flags = PLY_TERMINAL_SESSION_FLAGS_RUN_IN_PARENT;
flags |= PLY_TERMINAL_SESSION_FLAGS_LOOK_IN_PATH;
ply_terminal_session_attach_to_event_loop (session, loop);
if (!ply_terminal_session_run (session, flags,
(ply_terminal_session_begin_handler_t) NULL,
(ply_terminal_session_output_handler_t) NULL,
(ply_terminal_session_hangup_handler_t)
on_finished, loop))
{
perror ("could not start terminal session");
return errno;
}
ply_terminal_session_open_log (session, "foo.log");
exit_code = ply_event_loop_run (loop);
ply_terminal_session_free (session);
return exit_code;
}
#endif /* PLY_TERMINAL_SESSION_ENABLE_TEST */
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -1,25 +0,0 @@
INCLUDES = \
-I$(top_srcdir) \
-I$(srcdir)/.. \
-I$(srcdir)
TESTS =
if ENABLE_TESTS
include $(srcdir)/ply-terminal-session-test.am
include $(srcdir)/ply-logger-test.am
include $(srcdir)/ply-array-test.am
include $(srcdir)/ply-bitarray-test.am
include $(srcdir)/ply-list-test.am
include $(srcdir)/ply-hashtable-test.am
include $(srcdir)/ply-event-loop-test.am
include $(srcdir)/ply-command-parser-test.am
include $(srcdir)/ply-progress-test.am
include $(srcdir)/ply-region.am
endif
noinst_PROGRAMS = $(TESTS)
# Our tests aren't unit tests so clear for now
TESTS =
MAINTAINERCLEANFILES = Makefile.in

View file

@ -1,16 +0,0 @@
TESTS += ply-array-test
ply_array_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_ARRAY_ENABLE_TEST
ply_array_test_LDADD = $(PLYMOUTH_LIBS)
ply_array_test_SOURCES = \
$(srcdir)/../ply-buffer.h \
$(srcdir)/../ply-buffer.c \
$(srcdir)/../ply-list.h \
$(srcdir)/../ply-list.c \
$(srcdir)/../ply-logger.h \
$(srcdir)/../ply-logger.c \
$(srcdir)/../ply-utils.h \
$(srcdir)/../ply-utils.c \
$(srcdir)/../ply-array.h \
$(srcdir)/../ply-array.c

View file

@ -1,8 +0,0 @@
TESTS += ply-bitarray-test
ply_bitarray_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_BITARRAY_ENABLE_TEST
ply_bitarray_test_LDADD = $(PLYMOUTH_LIBS)
ply_bitarray_test_SOURCES = \
$(srcdir)/../ply-bitarray.h \
$(srcdir)/../ply-bitarray.c

View file

@ -1,18 +0,0 @@
TESTS += ply-command-parser-test
ply_command_parser_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_COMMAND_PARSER_ENABLE_TEST
ply_command_parser_test_LDADD = $(PLYMOUTH_LIBS)
ply_command_parser_test_SOURCES = \
$(srcdir)/../ply-buffer.h \
$(srcdir)/../ply-buffer.c \
$(srcdir)/../ply-event-loop.h \
$(srcdir)/../ply-event-loop.c \
$(srcdir)/../ply-list.h \
$(srcdir)/../ply-list.c \
$(srcdir)/../ply-logger.h \
$(srcdir)/../ply-logger.c \
$(srcdir)/../ply-utils.h \
$(srcdir)/../ply-utils.c \
$(srcdir)/../ply-command-parser.h \
$(srcdir)/../ply-command-parser.c

View file

@ -1,14 +0,0 @@
TESTS += ply-event-loop-test
ply_event_loop_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_EVENT_LOOP_ENABLE_TEST
ply_event_loop_test_LDADD = $(PLYMOUTH_LIBS)
ply_event_loop_test_SOURCES = \
$(srcdir)/../ply-utils.h \
$(srcdir)/../ply-utils.c \
$(srcdir)/../ply-list.h \
$(srcdir)/../ply-list.c \
$(srcdir)/../ply-logger.h \
$(srcdir)/../ply-logger.c \
$(srcdir)/../ply-event-loop.h \
$(srcdir)/../ply-event-loop.c

View file

@ -1,10 +0,0 @@
TESTS += ply-hashtable-test
ply_hashtable_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_HASHTABLE_ENABLE_TEST
ply_hashtable_test_LDADD = $(PLYMOUTH_LIBS)
ply_hashtable_test_SOURCES = \
$(srcdir)/../ply-hashtable.h \
$(srcdir)/../ply-hashtable.c \
$(srcdir)/../ply-bitarray.h \
$(srcdir)/../ply-bitarray.c

View file

@ -1,8 +0,0 @@
TESTS += ply-list-test
ply_list_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_LIST_ENABLE_TEST
ply_list_test_LDADD = $(PLYMOUTH_LIBS)
ply_list_test_SOURCES = \
$(srcdir)/../ply-list.h \
$(srcdir)/../ply-list.c

View file

@ -1,12 +0,0 @@
TESTS += ply-logger-test
ply_logger_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_LOGGER_ENABLE_TEST
ply_logger_test_LDADD = $(PLYMOUTH_LIBS)
ply_logger_test_SOURCES = \
$(srcdir)/../ply-list.h \
$(srcdir)/../ply-list.c \
$(srcdir)/../ply-utils.h \
$(srcdir)/../ply-utils.c \
$(srcdir)/../ply-logger.h \
$(srcdir)/../ply-logger.c

View file

@ -1,15 +0,0 @@
TESTS += ply-progress-test
ply_progress_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_PROGRESS_ENABLE_TEST \
-DPLYMOUTH_TIME_DIRECTORY=\"$(localstatedir)/lib/plymouth/\"
ply_progress_test_LDADD = $(PLYMOUTH_LIBS)
ply_progress_test_SOURCES = \
$(srcdir)/../ply-progress.h \
$(srcdir)/../ply-progress.c \
$(srcdir)/../ply-list.h \
$(srcdir)/../ply-list.c \
$(srcdir)/../ply-logger.h \
$(srcdir)/../ply-logger.c \
$(srcdir)/../ply-utils.h \
$(srcdir)/../ply-utils.c

View file

@ -1,12 +0,0 @@
TESTS += ply-region-test
ply_region_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_REGION_ENABLE_TEST
ply_region_test_LDADD = $(PLYMOUTH_LIBS)
ply_region_test_SOURCES = \
$(srcdir)/../ply-region.h \
$(srcdir)/../ply-region.c \
$(srcdir)/../ply-rectangle.h \
$(srcdir)/../ply-rectangle.c \
$(srcdir)/../ply-list.h \
$(srcdir)/../ply-list.c

View file

@ -1,18 +0,0 @@
TESTS += ply-terminal-session-test
ply_terminal_session_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_TERMINAL_SESSION_ENABLE_TEST
ply_terminal_session_test_LDADD = $(PLYMOUTH_LIBS)
ply_terminal_session_test_SOURCES = \
$(srcdir)/../ply-utils.h \
$(srcdir)/../ply-utils.c \
$(srcdir)/../ply-buffer.h \
$(srcdir)/../ply-buffer.c \
$(srcdir)/../ply-logger.h \
$(srcdir)/../ply-logger.c \
$(srcdir)/../ply-list.h \
$(srcdir)/../ply-list.c \
$(srcdir)/../ply-event-loop.h \
$(srcdir)/../ply-event-loop.c \
$(srcdir)/../ply-terminal-session.h \
$(srcdir)/../ply-terminal-session.c

File diff suppressed because it is too large Load diff

View file

@ -522,6 +522,9 @@ open_device (ply_renderer_backend_t *backend)
if (!load_driver (backend))
return false;
if (backend->terminal == NULL)
return true;
if (!ply_terminal_open (backend->terminal))
{
ply_trace ("could not open terminal: %m");
@ -550,10 +553,11 @@ close_device (ply_renderer_backend_t *backend)
free_heads (backend);
ply_terminal_stop_watching_for_active_vt_change (backend->terminal,
(ply_terminal_active_vt_changed_handler_t)
on_active_vt_changed,
backend);
if (backend->terminal != NULL)
ply_terminal_stop_watching_for_active_vt_change (backend->terminal,
(ply_terminal_active_vt_changed_handler_t)
on_active_vt_changed,
backend);
unload_driver (backend);
}
@ -888,10 +892,17 @@ map_to_device (ply_renderer_backend_t *backend)
node = next_node;
}
if (ply_terminal_is_active (backend->terminal))
activate (backend);
if (backend->terminal != NULL)
{
if (ply_terminal_is_active (backend->terminal))
activate (backend);
else
ply_terminal_activate_vt (backend->terminal);
}
else
ply_terminal_activate_vt (backend->terminal);
{
activate (backend);
}
return head_mapped;
}
@ -1019,8 +1030,11 @@ reset_scan_out_buffer_if_needed (ply_renderer_backend_t *backend,
drmModeCrtc *controller;
bool did_reset = false;
if (!ply_terminal_is_active (backend->terminal))
return false;
if (backend->terminal != NULL)
{
if (!ply_terminal_is_active (backend->terminal))
return false;
}
controller = drmModeGetCrtc (backend->device_fd, head->controller_id);
@ -1054,8 +1068,11 @@ flush_head (ply_renderer_backend_t *backend,
if (!backend->is_active)
return;
ply_terminal_set_mode (backend->terminal, PLY_TERMINAL_MODE_GRAPHICS);
ply_terminal_set_unbuffered_input (backend->terminal);
if (backend->terminal != NULL)
{
ply_terminal_set_mode (backend->terminal, PLY_TERMINAL_MODE_GRAPHICS);
ply_terminal_set_unbuffered_input (backend->terminal);
}
pixel_buffer = head->pixel_buffer;
updated_region = ply_pixel_buffer_get_updated_areas (pixel_buffer);
areas_to_flush = ply_region_get_sorted_rectangle_list (updated_region);
@ -1163,6 +1180,9 @@ open_input_source (ply_renderer_backend_t *backend,
assert (backend != NULL);
assert (has_input_source (backend, input_source));
if (backend->terminal == NULL)
return false;
terminal_fd = ply_terminal_get_fd (backend->terminal);
input_source->backend = backend;
@ -1193,6 +1213,9 @@ close_input_source (ply_renderer_backend_t *backend,
assert (backend != NULL);
assert (has_input_source (backend, input_source));
if (backend->terminal == NULL)
return;
ply_event_loop_stop_watching_fd (backend->loop, input_source->terminal_input_watch);
input_source->terminal_input_watch = NULL;
input_source->backend = NULL;

View file

@ -351,6 +351,9 @@ open_device (ply_renderer_backend_t *backend)
return false;
}
if (backend->terminal == NULL)
return true;
if (!ply_terminal_open (backend->terminal))
{
ply_trace ("could not open terminal: %m");
@ -376,10 +379,11 @@ static void
close_device (ply_renderer_backend_t *backend)
{
ply_terminal_stop_watching_for_active_vt_change (backend->terminal,
(ply_terminal_active_vt_changed_handler_t)
on_active_vt_changed,
backend);
if (backend->terminal != NULL)
ply_terminal_stop_watching_for_active_vt_change (backend->terminal,
(ply_terminal_active_vt_changed_handler_t)
on_active_vt_changed,
backend);
uninitialize_head (backend, &backend->head);
close (backend->device_fd);
@ -546,15 +550,22 @@ map_to_device (ply_renderer_backend_t *backend)
return false;
}
if (ply_terminal_is_active (backend->terminal))
if (backend->terminal != NULL)
{
ply_trace ("already on right vt, activating");
activate (backend);
if (ply_terminal_is_active (backend->terminal))
{
ply_trace ("already on right vt, activating");
activate (backend);
}
else
{
ply_trace ("on wrong vt, changing vts");
ply_terminal_activate_vt (backend->terminal);
}
}
else
{
ply_trace ("on wrong vt, changing vts");
ply_terminal_activate_vt (backend->terminal);
activate (backend);
}
return true;
@ -590,8 +601,11 @@ flush_head (ply_renderer_backend_t *backend,
if (!backend->is_active)
return;
ply_terminal_set_mode (backend->terminal, PLY_TERMINAL_MODE_GRAPHICS);
ply_terminal_set_unbuffered_input (backend->terminal);
if (backend->terminal != NULL)
{
ply_terminal_set_mode (backend->terminal, PLY_TERMINAL_MODE_GRAPHICS);
ply_terminal_set_unbuffered_input (backend->terminal);
}
pixel_buffer = head->pixel_buffer;
updated_region = ply_pixel_buffer_get_updated_areas (pixel_buffer);
areas_to_flush = ply_region_get_sorted_rectangle_list (updated_region);
@ -685,6 +699,9 @@ open_input_source (ply_renderer_backend_t *backend,
assert (backend != NULL);
assert (has_input_source (backend, input_source));
if (backend->terminal == NULL)
return false;
terminal_fd = ply_terminal_get_fd (backend->terminal);
input_source->backend = backend;
@ -715,6 +732,9 @@ close_input_source (ply_renderer_backend_t *backend,
assert (backend != NULL);
assert (has_input_source (backend, input_source));
if (backend->terminal == NULL)
return;
ply_event_loop_stop_watching_fd (backend->loop, input_source->terminal_input_watch);
input_source->terminal_input_watch = NULL;
input_source->backend = NULL;

View file

@ -831,183 +831,4 @@ ply_boot_server_attach_to_event_loop (ply_boot_server_t *server,
server);
}
#ifdef PLY_BOOT_SERVER_ENABLE_TEST
#include <stdio.h>
#include "ply-event-loop.h"
#include "ply-boot-server.h"
static void
on_update (ply_event_loop_t *loop,
const char *status)
{
printf ("new status is '%s'\n", status);
}
static void
on_newroot (ply_event_loop_t *loop)
{
printf ("got newroot request\n");
}
static void
on_system_initialized (ply_event_loop_t *loop)
{
printf ("got sysinit done request\n");
}
static void
on_show_splash (ply_event_loop_t *loop)
{
printf ("got show splash request\n");
}
static void
on_hide_splash (ply_event_loop_t *loop)
{
printf ("got hide splash request\n");
}
static void
on_deactivate (ply_event_loop_t *loop)
{
printf ("got deactivate request\n");
}
static void
on_reactivate (ply_event_loop_t *loop)
{
printf ("got reactivate request\n");
}
static void
on_quit (ply_event_loop_t *loop)
{
printf ("got quit request, quiting...\n");
ply_event_loop_exit (loop, 0);
}
static void
on_error (ply_event_loop_t *loop)
{
printf ("got error starting service\n");
}
static char *
on_ask_for_password (ply_event_loop_t *loop)
{
printf ("got password request, returning 'password'...\n");
return strdup ("password");
}
static void
on_ask_question (ply_event_loop_t *loop)
{
printf ("got question request\n");
return;
}
static void
on_display_message (ply_event_loop_t *loop)
{
printf ("got display message request\n");
return;
}
static void
on_hide_message (ply_event_loop_t *loop)
{
printf ("got hide message request\n");
return;
}
static void
on_watch_for_keystroke (ply_event_loop_t *loop)
{
printf ("got keystroke request\n");
return;
}
static void
on_progress_pause (ply_event_loop_t *loop)
{
printf ("got progress pause request\n");
return;
}
static void
on_progress_unpause (ply_event_loop_t *loop)
{
printf ("got progress unpause request\n");
return;
}
static void
on_ignore_keystroke (ply_event_loop_t *loop)
{
printf ("got keystroke ignore request\n");
return;
}
static bool
on_has_active_vt (ply_event_loop_t *loop)
{
printf ("got has_active vt? request\n");
return true;
}
int
main (int argc,
char **argv)
{
ply_event_loop_t *loop;
ply_boot_server_t *server;
int exit_code;
exit_code = 0;
loop = ply_event_loop_new ();
server = ply_boot_server_new ((ply_boot_server_update_handler_t) on_update,
(ply_boot_server_change_mode_handler_t) on_change_mode,
(ply_boot_server_system_update_handler_t) on_system_update,
(ply_boot_server_ask_for_password_handler_t) on_ask_for_password,
(ply_boot_server_ask_question_handler_t) on_ask_question,
(ply_boot_server_display_message_handler_t) on_display_message,
(ply_boot_server_hide_message_handler_t) on_hide_message,
(ply_boot_server_watch_for_keystroke_handler_t) on_watch_for_keystroke,
(ply_boot_server_ignore_keystroke_handler_t) on_ignore_keystroke,
(ply_boot_server_progress_pause_handler_t) on_progress_pause,
(ply_boot_server_progress_unpause_handler_t) on_progress_unpause,
(ply_boot_server_show_splash_handler_t) on_show_splash,
(ply_boot_server_hide_splash_handler_t) on_hide_splash,
(ply_boot_server_newroot_handler_t) on_newroot,
(ply_boot_server_system_initialized_handler_t) on_system_initialized,
(ply_boot_server_error_handler_t) on_error,
(ply_boot_server_deactivate_handler_t) on_deactivate,
(ply_boot_server_reactivate_handler_t) on_reactivate,
(ply_boot_server_quit_handler_t) on_quit,
(ply_boot_server_has_active_vt_handler_t) on_has_active_vt,
loop);
if (!ply_boot_server_listen (server))
{
perror ("could not start boot status daemon");
return errno;
}
ply_boot_server_attach_to_event_loop (server, loop);
exit_code = ply_event_loop_run (loop);
ply_boot_server_free (server);
return exit_code;
}
#endif /* PLY_BOOT_SERVER_ENABLE_TEST */
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -1,18 +0,0 @@
INCLUDES = \
-I$(top_srcdir) \
-I$(srcdir)/.. \
-I$(srcdir)/../libply \
-I$(srcdir)/../libply-splash-core \
-I$(srcdir)
TESTS =
if ENABLE_TESTS
include $(srcdir)/ply-boot-server-test.am
include $(srcdir)/ply-boot-splash-test.am
endif
noinst_PROGRAMS = $(TESTS)
# our tests aren't unit tests, so clear for now
TESTS =
MAINTAINERCLEANFILES = Makefile.in

View file

@ -1,8 +0,0 @@
TESTS += ply-boot-server-test
ply_boot_server_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_BOOT_SERVER_ENABLE_TEST
ply_boot_server_test_LDADD = $(PLYMOUTH_LIBS) ../libply/libply.la
ply_boot_server_test_SOURCES = \
$(srcdir)/../ply-boot-server.h \
$(srcdir)/../ply-boot-server.c

View file

@ -1,25 +0,0 @@
TESTS += ply-boot-splash-test
ply_boot_splash_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_BOOT_SPLASH_ENABLE_TEST \
-DPLYMOUTH_TIME_DIRECTORY=\"/var/lib/plymouth\" \
-DPLYMOUTH_PLUGIN_PATH=\"$(PLYMOUTH_PLUGIN_PATH)\" \
-DPLYMOUTH_THEME_PATH=\"$(PLYMOUTH_THEME_PATH)/\"
ply_boot_splash_test_LDADD = $(PLYMOUTH_LIBS) ../libply/libply.la
ply_boot_splash_test_SOURCES = \
$(srcdir)/../libply-splash-core/ply-boot-splash-plugin.h \
$(srcdir)/../libply-splash-core/ply-keyboard.h \
$(srcdir)/../libply-splash-core/ply-keyboard.c \
$(srcdir)/../libply-splash-core/ply-pixel-buffer.h \
$(srcdir)/../libply-splash-core/ply-pixel-buffer.c \
$(srcdir)/../libply-splash-core/ply-pixel-display.h \
$(srcdir)/../libply-splash-core/ply-pixel-display.c \
$(srcdir)/../libply-splash-core/ply-renderer.h \
$(srcdir)/../libply-splash-core/ply-renderer.c \
$(srcdir)/../libply-splash-core/ply-terminal.h \
$(srcdir)/../libply-splash-core/ply-terminal.c \
$(srcdir)/../libply-splash-core/ply-text-display.h \
$(srcdir)/../libply-splash-core/ply-text-display.c \
$(srcdir)/../libply-splash-core/ply-boot-splash.h \
$(srcdir)/../libply-splash-core/ply-boot-splash.c

View file

@ -8,7 +8,7 @@ ConditionKernelCommandLine=!plymouth.enable=0
[Service]
ExecStart=@PLYMOUTH_DAEMON_DIR@/plymouthd --mode=boot --pid-file=@plymouthruntimedir@/pid --attach-to-session
ExecStartPost=-@UDEVADM@ settle --timeout=30 --exit-if-exists=/sys/class/drm/card0/dev ; -@UDEVADM@ settle --timeout=30 --exit-if-exists=/sys/class/graphics/fb0/dev ; -@PLYMOUTH_CLIENT_DIR@/plymouth show-splash
ExecStartPost=-@PLYMOUTH_CLIENT_DIR@/plymouth show-splash
Type=forking
KillMode=none
SendSIGKILL=no