diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..25b6be7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/plymouth-0.8.9.tar.bz2 diff --git a/.plymouth.metadata b/.plymouth.metadata new file mode 100644 index 0000000..cac76f3 --- /dev/null +++ b/.plymouth.metadata @@ -0,0 +1 @@ +69382b5353ea26410dfc546898e59f48350b8023 SOURCES/plymouth-0.8.9.tar.bz2 diff --git a/SOURCES/0001-Revert-Make-boot.log-world-readable-by-default.patch b/SOURCES/0001-Revert-Make-boot.log-world-readable-by-default.patch new file mode 100644 index 0000000..d85ea20 --- /dev/null +++ b/SOURCES/0001-Revert-Make-boot.log-world-readable-by-default.patch @@ -0,0 +1,287 @@ +From a2c6a448d38a5150c593ca388eea8537ec0489ee Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 11 May 2017 11:10:36 -0400 +Subject: [PATCH] Revert "Make boot.log world readable by default" + +This reverts commit fc5cd88767db61805519fef53182386ba56c6405. +--- + src/libply/ply-logger.c | 16 ++-------------- + src/libply/ply-logger.h | 5 ++--- + src/libply/ply-terminal-session.c | 2 +- + 3 files changed, 5 insertions(+), 18 deletions(-) + +diff --git a/src/libply/ply-logger.c b/src/libply/ply-logger.c +index dfd5c0a..6f25801 100644 +--- a/src/libply/ply-logger.c ++++ b/src/libply/ply-logger.c +@@ -292,84 +292,72 @@ ply_logger_free_filters (ply_logger_t *logger) + next_node = ply_list_get_next_node (logger->filters, node); + free (filter); + node = next_node; + } + + ply_list_free (logger->filters); + } + + void + ply_logger_free (ply_logger_t *logger) + { + if (logger == NULL) + return; + + if (logger->output_fd >= 0) + { + if (ply_logger_is_logging (logger)) + ply_logger_flush (logger); + close (logger->output_fd); + } + + ply_logger_free_filters (logger); + + free (logger->filename); + free (logger->buffer); + free (logger); + } + + bool + ply_logger_open_file (ply_logger_t *logger, +- const char *filename, +- bool world_readable) ++ const char *filename) + { + int fd; +- mode_t mode; + + assert (logger != NULL); + assert (filename != NULL); + +- if (world_readable) +- mode = 0644; +- else +- mode = 0600; +- +- fd = open (filename, PLY_LOGGER_OPEN_FLAGS, mode); ++ fd = open (filename, PLY_LOGGER_OPEN_FLAGS, 0600); + + if (fd < 0) + return false; + +- if (fchmod (fd, mode) < 0) { +- close (fd); +- return false; +- } +- + ply_logger_set_output_fd (logger, fd); + + free (logger->filename); + + logger->filename = strdup (filename); + + return true; + } + + void + ply_logger_close_file (ply_logger_t *logger) + { + assert (logger != NULL); + + if (logger->output_fd < 0) + return; + + close (logger->output_fd); + ply_logger_set_output_fd (logger, -1); + } + + void + ply_logger_set_output_fd (ply_logger_t *logger, + int fd) + { + assert (logger != NULL); + + logger->output_fd = fd; + } + +diff --git a/src/libply/ply-logger.h b/src/libply/ply-logger.h +index 596bed5..fc25db9 100644 +--- a/src/libply/ply-logger.h ++++ b/src/libply/ply-logger.h +@@ -19,120 +19,119 @@ + */ + #ifndef PLY_LOGGER_H + #define PLY_LOGGER_H + + #include + #include + #include + #include + #include + #include + + typedef struct _ply_logger ply_logger_t; + + typedef enum + { + PLY_LOGGER_FLUSH_POLICY_WHEN_ASKED = 0, + PLY_LOGGER_FLUSH_POLICY_EVERY_TIME + } ply_logger_flush_policy_t; + + typedef void (* ply_logger_filter_handler_t) (void *user_data, + const void *in_bytes, + size_t in_size, + void **out_bytes, + size_t *out_size, + ply_logger_t *logger); + + #ifndef PLY_HIDE_FUNCTION_DECLARATIONS + ply_logger_t *ply_logger_new (void); + void ply_logger_free (ply_logger_t *logger); + bool ply_logger_open_file (ply_logger_t *logger, +- const char *filename, +- bool world_readable); ++ const char *filename); + void ply_logger_close_file (ply_logger_t *logger); + void ply_logger_set_output_fd (ply_logger_t *logger, + int fd); + int ply_logger_get_output_fd (ply_logger_t *logger); + bool ply_logger_flush (ply_logger_t *logger); + void ply_logger_set_flush_policy (ply_logger_t *logger, + ply_logger_flush_policy_t policy); + ply_logger_flush_policy_t ply_logger_get_flush_policy (ply_logger_t *logger); + void ply_logger_toggle_logging (ply_logger_t *logger); + bool ply_logger_is_logging (ply_logger_t *logger); + void ply_logger_inject_bytes (ply_logger_t *logger, + const void *bytes, + size_t number_of_bytes); + void ply_logger_add_filter (ply_logger_t *logger, + ply_logger_filter_handler_t filter_handler, + void *user_data); + #define ply_logger_inject(logger, format, args...) \ + ply_logger_inject_with_non_literal_format_string (logger, \ + format "", ##args) + __attribute__((__format__ (__printf__, 2, 3))) + void ply_logger_inject_with_non_literal_format_string (ply_logger_t *logger, + const char *format, ...); + + ply_logger_t *ply_logger_get_default (void); + ply_logger_t *ply_logger_get_error_default (void); + + /* tracing is a debugging facility that incurs a hefty performance hit on the + * program, so we conditionally compile support for it + */ + #ifdef PLY_ENABLE_TRACING + void ply_logger_toggle_tracing (ply_logger_t *logger); + bool ply_logger_is_tracing_enabled (ply_logger_t *logger); + + #define ply_logger_trace(logger, format, args...) \ + do \ + { \ + int _old_errno; \ + _old_errno = errno; \ + if (ply_logger_is_tracing_enabled (logger)) \ + { \ + ply_logger_flush (logger); \ + errno = _old_errno; \ + ply_logger_inject (logger, \ + "[%s:%d] %45.45s:" format "\r\n", \ + __FILE__, __LINE__, __func__, ##args); \ + ply_logger_flush (logger); \ + errno = _old_errno; \ + } \ + } \ + while (0) + #else + #define ply_logger_trace(logger, format, args...) + #define ply_logger_toggle_tracing(logger) + #define ply_logger_is_tracing_enabled(logger) (false) + #endif /* PLY_ENABLE_TRACING */ + + /* convenience macros + */ + #define ply_open_log_file(filename) \ +- ply_logger_open_file (ply_logger_get_default (), filename, false) ++ ply_logger_open_file (ply_logger_get_default (), filename) + #define ply_close_log_file() \ + ply_logger_close_file (ply_logger_get_default ()) + #define ply_flush_log() \ + ply_logger_flush (ply_logger_get_default ()) + #define ply_free_log() \ + ply_logger_free (ply_logger_get_default ()) + #define ply_log(format, args...) \ + ply_logger_inject (ply_logger_get_default (), format "\n", ##args) + #define ply_log_without_new_line(format, args...) \ + ply_logger_inject (ply_logger_get_default (), format, ##args) + #define ply_error(format, args...) \ + ply_logger_inject (ply_logger_get_error_default (), format "\n", ##args) + #define ply_error_without_new_line(format, args...) \ + ply_logger_inject (ply_logger_get_error_default (), format, ##args) + #define ply_free_error_log() \ + ply_logger_free (ply_logger_get_error_default ()) + + #define ply_toggle_tracing() \ + ply_logger_toggle_tracing (ply_logger_get_error_default ()) + #define ply_is_tracing() \ + ply_logger_is_tracing_enabled (ply_logger_get_error_default ()) + #define ply_trace(format, args...) \ + ply_logger_trace (ply_logger_get_error_default (), format, ##args) + + #endif + + #endif /* PLY_LOGGER_H */ + /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ +diff --git a/src/libply/ply-terminal-session.c b/src/libply/ply-terminal-session.c +index 143eed6..50ddd28 100644 +--- a/src/libply/ply-terminal-session.c ++++ b/src/libply/ply-terminal-session.c +@@ -542,48 +542,48 @@ ply_terminal_session_start_logging (ply_terminal_session_t *session) + } + + static void + ply_terminal_session_stop_logging (ply_terminal_session_t *session) + { + assert (session != NULL); + assert (session->logger != NULL); + + ply_trace ("stopping logging of incoming console messages"); + if (ply_logger_is_logging (session->logger)) + ply_logger_toggle_logging (session->logger); + + if (session->loop != NULL && + session->fd_watch != NULL) + ply_event_loop_stop_watching_fd (session->loop, + session->fd_watch); + session->fd_watch = NULL; + } + + bool + ply_terminal_session_open_log (ply_terminal_session_t *session, + const char *filename) + { + bool log_is_opened; + + assert (session != NULL); + assert (filename != NULL); + assert (session->logger != NULL); + + ply_save_errno (); +- log_is_opened = ply_logger_open_file (session->logger, filename, true); ++ log_is_opened = ply_logger_open_file (session->logger, filename); + if (log_is_opened) + ply_logger_flush (session->logger); + ply_restore_errno (); + + return log_is_opened; + } + + void + ply_terminal_session_close_log (ply_terminal_session_t *session) + { + assert (session != NULL); + assert (session->logger != NULL); + + return ply_logger_close_file (session->logger); + } + + /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ +-- +2.12.2 + diff --git a/SOURCES/0001-Revert-Recreate-boot-log-at-each-boot-instead-of-app.patch b/SOURCES/0001-Revert-Recreate-boot-log-at-each-boot-instead-of-app.patch new file mode 100644 index 0000000..b9c607e --- /dev/null +++ b/SOURCES/0001-Revert-Recreate-boot-log-at-each-boot-instead-of-app.patch @@ -0,0 +1,148 @@ +From 3edbaf6559eb81243326ebe79dc53b0759809a68 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 24 Mar 2017 15:31:51 -0400 +Subject: [PATCH] Revert "Recreate boot log at each boot instead of appending" + +This reverts commit 9abbd88835a181cda1427d61d92ef5685ad8a81b. +--- + src/libply/ply-logger.c | 2 +- + src/libply/ply-terminal-session.c | 5 ++--- + 2 files changed, 3 insertions(+), 4 deletions(-) + +diff --git a/src/libply/ply-logger.c b/src/libply/ply-logger.c +index 740c30e..dfd5c0a 100644 +--- a/src/libply/ply-logger.c ++++ b/src/libply/ply-logger.c +@@ -13,61 +13,61 @@ + * 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 + */ + #include "config.h" + #include "ply-logger.h" + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include "ply-utils.h" + #include "ply-list.h" + + #ifndef PLY_LOGGER_OPEN_FLAGS +-#define PLY_LOGGER_OPEN_FLAGS (O_WRONLY | O_TRUNC | O_CREAT | O_NOFOLLOW | O_CLOEXEC) ++#define PLY_LOGGER_OPEN_FLAGS (O_WRONLY | O_APPEND | O_CREAT | O_NOFOLLOW | O_CLOEXEC) + #endif + + #ifndef PLY_LOGGER_MAX_INJECTION_SIZE + #define PLY_LOGGER_MAX_INJECTION_SIZE 4096 + #endif + + #ifndef PLY_LOGGER_MAX_BUFFER_CAPACITY + #define PLY_LOGGER_MAX_BUFFER_CAPACITY (8 * 4096) + #endif + + typedef struct + { + ply_logger_filter_handler_t handler; + void *user_data; + } ply_logger_filter_t; + + struct _ply_logger + { + int output_fd; + char *filename; + + char *buffer; + size_t buffer_size; + size_t buffer_capacity; + + ply_logger_flush_policy_t flush_policy; + ply_list_t *filters; + + uint32_t is_enabled : 1; + uint32_t tracing_is_enabled : 1; +diff --git a/src/libply/ply-terminal-session.c b/src/libply/ply-terminal-session.c +index 379035c..143eed6 100644 +--- a/src/libply/ply-terminal-session.c ++++ b/src/libply/ply-terminal-session.c +@@ -531,60 +531,59 @@ ply_terminal_session_start_logging (ply_terminal_session_t *session) + + assert (session_fd >= 0); + + session->fd_watch = ply_event_loop_watch_fd (session->loop, + session_fd, + PLY_EVENT_LOOP_FD_STATUS_HAS_DATA, + (ply_event_handler_t) + ply_terminal_session_on_new_data, + (ply_event_handler_t) + ply_terminal_session_on_hangup, + session); + } + + static void + ply_terminal_session_stop_logging (ply_terminal_session_t *session) + { + assert (session != NULL); + assert (session->logger != NULL); + + ply_trace ("stopping logging of incoming console messages"); + if (ply_logger_is_logging (session->logger)) + ply_logger_toggle_logging (session->logger); + + if (session->loop != NULL && + session->fd_watch != NULL) + ply_event_loop_stop_watching_fd (session->loop, + session->fd_watch); + session->fd_watch = NULL; + } + +-bool ++bool + ply_terminal_session_open_log (ply_terminal_session_t *session, + const char *filename) + { + bool log_is_opened; + + assert (session != NULL); + assert (filename != NULL); + assert (session->logger != NULL); + + ply_save_errno (); +- unlink (filename); + log_is_opened = ply_logger_open_file (session->logger, filename, true); + if (log_is_opened) + ply_logger_flush (session->logger); + ply_restore_errno (); + + return log_is_opened; + } + +-void ++void + ply_terminal_session_close_log (ply_terminal_session_t *session) + { + assert (session != NULL); + assert (session->logger != NULL); + + return ply_logger_close_file (session->logger); + } + + /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ +-- +2.12.2 + diff --git a/SOURCES/0001-boot-splash-handle-update-coming-in-after-splash-is-.patch b/SOURCES/0001-boot-splash-handle-update-coming-in-after-splash-is-.patch new file mode 100644 index 0000000..8cd73b8 --- /dev/null +++ b/SOURCES/0001-boot-splash-handle-update-coming-in-after-splash-is-.patch @@ -0,0 +1,110 @@ +From 4cb71a45b448dd8008242a5de122771c4e6d1c36 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Thu, 29 Aug 2019 09:21:57 -0400 +Subject: [PATCH] boot-splash: handle update coming in after splash is unloaded + +In some scenario i don't quite understand, involving plymouthd +getting updated while it's running, the boot splash can get unloaded +while its progress timeout remains active, leading to crash. + +This commit protects against such a crash. +--- + src/libply-splash-core/ply-boot-splash.c | 21 +++++++++++++-------- + 1 file changed, 13 insertions(+), 8 deletions(-) + +diff --git a/src/libply-splash-core/ply-boot-splash.c b/src/libply-splash-core/ply-boot-splash.c +index 664acc3..267136a 100644 +--- a/src/libply-splash-core/ply-boot-splash.c ++++ b/src/libply-splash-core/ply-boot-splash.c +@@ -412,75 +412,80 @@ ply_boot_splash_free (ply_boot_splash_t *splash) + + if (splash->module_handle != NULL) + { + ply_boot_splash_unset_keyboard (splash); + + remove_pixel_displays (splash); + ply_list_free (splash->pixel_displays); + + remove_text_displays (splash); + ply_list_free (splash->text_displays); + + ply_boot_splash_unload (splash); + } + + if (splash->idle_trigger != NULL) + ply_trigger_free (splash->idle_trigger); + + free (splash->theme_path); + free (splash->plugin_dir); + free (splash); + } + + static void + ply_boot_splash_update_progress (ply_boot_splash_t *splash) + { + double percentage=0.0; + double time=0.0; + + assert (splash != NULL); + ++ if (splash->plugin_interface == NULL) ++ return; ++ + if (splash->progress) + { + percentage = ply_progress_get_percentage(splash->progress); + time = ply_progress_get_time(splash->progress); + } + + if (splash->plugin_interface->on_boot_progress != NULL) +- splash->plugin_interface->on_boot_progress (splash->plugin, +- time, +- percentage); +- +- ply_event_loop_watch_for_timeout (splash->loop, +- 1.0 / UPDATES_PER_SECOND, +- (ply_event_loop_timeout_handler_t) +- ply_boot_splash_update_progress, splash); ++ { ++ splash->plugin_interface->on_boot_progress (splash->plugin, ++ time, ++ percentage); ++ ++ ply_event_loop_watch_for_timeout (splash->loop, ++ 1.0 / UPDATES_PER_SECOND, ++ (ply_event_loop_timeout_handler_t) ++ ply_boot_splash_update_progress, splash); ++ } + } + + void + ply_boot_splash_attach_progress (ply_boot_splash_t *splash, + ply_progress_t *progress) + { + assert (splash != NULL); + assert (progress != NULL); + assert (splash->progress == NULL); + splash->progress = progress; + } + + + bool + ply_boot_splash_show (ply_boot_splash_t *splash, + ply_boot_splash_mode_t mode) + { + assert (splash != NULL); + assert (mode != PLY_BOOT_SPLASH_MODE_INVALID); + assert (splash->module_handle != NULL); + assert (splash->loop != NULL); + assert (splash->plugin_interface != NULL); + assert (splash->plugin != NULL); + assert (splash->plugin_interface->show_splash_screen != NULL); + + if (splash->mode == mode) + { + ply_trace ("already set same splash screen mode"); + return true; + } +-- +2.21.0 + diff --git a/SOURCES/0001-device-manager-fall-back-to-text-mode-if-graphical-d.patch b/SOURCES/0001-device-manager-fall-back-to-text-mode-if-graphical-d.patch new file mode 100644 index 0000000..74e076a --- /dev/null +++ b/SOURCES/0001-device-manager-fall-back-to-text-mode-if-graphical-d.patch @@ -0,0 +1,411 @@ +From 6cffa8daaca920f1d57da40d93ff112f5f096ae9 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Tue, 7 Nov 2017 13:49:30 -0500 +Subject: [PATCH] device-manager: fall back to text mode if graphical devices + fail + +Right now we assume if we find a /dev/dri/card0 that it will work. +That may not be true. The proprietary nvidia driver, for instance, +provides /dev/dri/card0 but disables modesetting by default. + +This commit makes sure we fall back to text mode if /dev/dri/card0 +is insufficient for our needs. +--- + src/libply-splash-core/ply-device-manager.c | 25 ++++++++++++++----------- + 1 file changed, 14 insertions(+), 11 deletions(-) + +diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c +index 14d7616..3a2db06 100644 +--- a/src/libply-splash-core/ply-device-manager.c ++++ b/src/libply-splash-core/ply-device-manager.c +@@ -14,61 +14,61 @@ + * + * 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 + #include + #include + #include + #include + #include + #include + #include + #include + + #include + + #include "ply-logger.h" + #include "ply-event-loop.h" + #include "ply-hashtable.h" + #include "ply-list.h" + #include "ply-utils.h" + + #define SUBSYSTEM_DRM "drm" + #define SUBSYSTEM_FRAME_BUFFER "graphics" + +-static void create_devices_for_terminal_and_renderer_type (ply_device_manager_t *manager, ++static bool create_devices_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_hashtable_t *renderers; + ply_terminal_t *local_console_terminal; + ply_list_t *keyboards; + ply_list_t *text_displays; + ply_list_t *pixel_displays; + struct udev *udev_context; + struct udev_queue *udev_queue; + int udev_queue_fd; + ply_fd_watch_t *udev_queue_fd_watch; + struct udev_monitor *udev_monitor; + + ply_keyboard_added_handler_t keyboard_added_handler; + ply_keyboard_removed_handler_t keyboard_removed_handler; + ply_pixel_display_added_handler_t pixel_display_added_handler; + ply_pixel_display_removed_handler_t pixel_display_removed_handler; + ply_text_display_added_handler_t text_display_added_handler; + ply_text_display_removed_handler_t text_display_removed_handler; + void *event_handler_data; + + uint32_t local_console_managed : 1; + uint32_t local_console_is_text : 1; + uint32_t serial_consoles_detected : 1; +@@ -134,110 +134,112 @@ fb_device_has_drm_device (ply_device_manager_t *manager, + + /* 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 && drm_device_in_use (manager, card_node)) + has_drm_device = true; + else + ply_trace ("no card node!"); + + udev_device_unref (card_device); + } + else + { + ply_trace ("no card entry!"); + } + + udev_enumerate_unref (card_matches); + return has_drm_device; + } + +-static void ++static bool + create_devices_for_udev_device (ply_device_manager_t *manager, + struct udev_device *device) + { + const char *device_path; ++ bool created = false; + + device_path = udev_device_get_devnode (device); + + if (device_path != NULL) + { + const char *subsystem; + + ply_renderer_type_t renderer_type = PLY_RENDERER_TYPE_NONE; + + subsystem = udev_device_get_subsystem (device); + ply_trace ("device subsystem is %s", subsystem); + + if (subsystem != NULL && strcmp (subsystem, SUBSYSTEM_DRM) == 0) + { + ply_trace ("found DRM device %s", device_path); + renderer_type = PLY_RENDERER_TYPE_DRM; + } + else if (strcmp (subsystem, SUBSYSTEM_FRAME_BUFFER) == 0) + { + ply_trace ("found frame buffer device %s", device_path); + if (!fb_device_has_drm_device (manager, device)) + { + renderer_type = PLY_RENDERER_TYPE_FRAME_BUFFER; + } + else + { + ply_trace ("ignoring, since there's a DRM device associated with it"); + } + } + + if (renderer_type != PLY_RENDERER_TYPE_NONE) + { + ply_terminal_t *terminal = NULL; + + if (!manager->local_console_managed) + { + terminal = manager->local_console_terminal; + } + +- create_devices_for_terminal_and_renderer_type (manager, +- device_path, +- terminal, +- renderer_type); ++ created = create_devices_for_terminal_and_renderer_type (manager, ++ device_path, ++ terminal, ++ renderer_type); + } + } ++ return created; + } + + static void + free_displays_for_renderer (ply_device_manager_t *manager, + ply_renderer_t *renderer) + { + ply_list_node_t *node; + + node = ply_list_get_first_node (manager->pixel_displays); + while (node != NULL) + { + ply_list_node_t *next_node; + ply_pixel_display_t *display; + ply_renderer_t *display_renderer; + + display = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (manager->pixel_displays, node); + display_renderer = ply_pixel_display_get_renderer (display); + + if (display_renderer == renderer) + { + if (manager->pixel_display_removed_handler != NULL) + manager->pixel_display_removed_handler (manager->event_handler_data, display); + + ply_pixel_display_free (display); + ply_list_remove_node (manager->pixel_displays, node); + } + + node = next_node; + } +@@ -300,62 +302,61 @@ create_devices_for_subsystem (ply_device_manager_t *manager, + const char *path; + + path = udev_list_entry_get_name (entry); + + if (path == NULL) + { + ply_trace ("path was null!"); + continue; + } + + ply_trace ("found device %s", path); + + device = udev_device_new_from_syspath (manager->udev_context, path); + + /* if device isn't fully initialized, we'll get an add event later + */ + if (udev_device_get_is_initialized (device)) + { + ply_trace ("device is initialized"); + + /* We only care about devices assigned to a (any) seat. Floating + * devices should be ignored. + */ + if (udev_device_has_tag (device, "seat")) + { + const char *node; + node = udev_device_get_devnode (device); + if (node != NULL) + { + ply_trace ("found node %s", node); +- found_device = true; +- create_devices_for_udev_device (manager, device); ++ found_device = create_devices_for_udev_device (manager, device); + } + } + else + { + ply_trace ("device doesn't have a seat tag"); + } + } + else + { + ply_trace ("it's not initialized"); + } + + udev_device_unref (device); + } + + udev_enumerate_unref (matches); + + return found_device; + } + + static void + on_udev_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; + +@@ -655,137 +656,139 @@ create_pixel_displays_for_renderer (ply_device_manager_t *manager, + node = next_node; + } + } + + static void + create_text_displays_for_terminal (ply_device_manager_t *manager, + ply_terminal_t *terminal) + { + ply_text_display_t *display; + + if (!ply_terminal_is_open (terminal)) + { + if (!ply_terminal_open (terminal)) + { + ply_trace ("could not add terminal %s: %m", + ply_terminal_get_name (terminal)); + return; + } + } + + ply_trace ("adding text display for terminal %s", + ply_terminal_get_name (terminal)); + + display = ply_text_display_new (terminal); + ply_list_append_data (manager->text_displays, display); + + if (manager->text_display_added_handler != NULL) + manager->text_display_added_handler (manager->event_handler_data, display); + } + +-static void ++static bool + create_devices_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_renderer_t *renderer = NULL; + ply_keyboard_t *keyboard = NULL; + + renderer = ply_hashtable_lookup (manager->renderers, (void *) device_path); + + if (renderer != NULL) + { + ply_trace ("ignoring device %s since it's already managed", + device_path); +- return; ++ return true; + } + + ply_trace ("creating devices for %s (renderer type: %u) (terminal: %s)", + device_path? : "", renderer_type, terminal? ply_terminal_get_name (terminal): "none"); + + if (renderer_type != PLY_RENDERER_TYPE_NONE) + { + renderer = ply_renderer_new (renderer_type, device_path, terminal); + + if (!ply_renderer_open (renderer)) + { + ply_trace ("could not open renderer for %s", device_path); + ply_renderer_free (renderer); + renderer = NULL; + if (renderer_type != PLY_RENDERER_TYPE_AUTO) +- return; ++ return false; + } + } + + if (renderer != NULL) + { + keyboard = ply_keyboard_new_for_renderer (renderer); + ply_list_append_data (manager->keyboards, keyboard); + + if (manager->keyboard_added_handler != NULL) + manager->keyboard_added_handler (manager->event_handler_data, keyboard); + + ply_hashtable_insert (manager->renderers, strdup (device_path), renderer); + create_pixel_displays_for_renderer (manager, renderer); + + if (manager->renderers_activated) + { + ply_trace ("activating renderer"); + ply_renderer_activate (renderer); + } + } + else if (terminal != NULL) + { + keyboard = ply_keyboard_new_for_terminal (terminal); + ply_list_append_data (manager->keyboards, keyboard); + + if (manager->keyboard_added_handler != NULL) + manager->keyboard_added_handler (manager->event_handler_data, keyboard); + } + + if (terminal != NULL) + { + create_text_displays_for_terminal (manager, terminal); + + if (terminal == manager->local_console_terminal) + { + manager->local_console_is_text = renderer == NULL; + manager->local_console_managed = true; + } + } + + if (keyboard != NULL && manager->keyboards_activated) + { + ply_trace ("activating keyboards"); + ply_keyboard_watch_for_input (keyboard); + } ++ ++ return true; + } + + static void + create_devices_for_terminal (const char *device_path, + ply_terminal_t *terminal, + ply_device_manager_t *manager) + { + create_devices_for_terminal_and_renderer_type (manager, + device_path, + terminal, + PLY_RENDERER_TYPE_NONE); + } + static bool + create_devices_from_terminals (ply_device_manager_t *manager) + { + bool has_serial_consoles; + + ply_trace ("checking for consoles"); + + if (manager->flags & PLY_DEVICE_MANAGER_FLAGS_IGNORE_SERIAL_CONSOLES) + { + has_serial_consoles = false; + ply_trace ("ignoring all consoles but default console because explicitly told to."); + } + else + { + has_serial_consoles = add_consoles_from_file (manager, "/sys/class/tty/console/active"); + } + + if (has_serial_consoles) +-- +2.14.3 + diff --git a/SOURCES/0001-ply-device-manager-Fix-race-causing-undesired-creati.patch b/SOURCES/0001-ply-device-manager-Fix-race-causing-undesired-creati.patch new file mode 100644 index 0000000..6285d86 --- /dev/null +++ b/SOURCES/0001-ply-device-manager-Fix-race-causing-undesired-creati.patch @@ -0,0 +1,246 @@ +From f76757f9dd63407686b24c98e5c2290502bcbb93 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 26 Mar 2019 15:10:28 -0400 +Subject: [PATCH] ply-device-manager: Fix race causing undesired creation of + non-gfx devs + +On systems with working drm/kms devices we still sometimes see: +"Creating non-graphical devices, since there's no suitable graphics hardware" +in the logs (and actually create non-gfx devices). + +This is caused by a race where the create_devices_from_udev timeout handler +runs just after the pivot-root, just at the time when the "udev trigger" +from the real root is done. + +This causes create_devices_for_subsystem() to hit the "it's not initialized" +code-path for all drm and fb devices, even though before (from the initrd) +drm-devices where already setup successfully. + +One way of solving this would be to stop the timer as soon as we successfully +enumerate the first drm device. But we need the timer to enumerate fb devices +so on machines where some outputs only have a fbdev driver (corner case) this +would break support for those outputs. + +Instead this commit moves the found_drm_device and found_fb_device to the +global manager state and sets them from create_devices_for_udev_device(). +This way they will be set when we check them from the create_devices_from_udev +timeout handler even if create_devices_for_subsystem skips over the devices +because of the udev trigger race. + +Signed-off-by: Hans de Goede +--- + src/libply-splash-core/ply-device-manager.c | 19 +- + 1 files changed, 63 insertions(+), 60 deletions(-) + +diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c +index 3a2db06..b6437c5 100644 +--- a/src/libply-splash-core/ply-device-manager.c ++++ b/src/libply-splash-core/ply-device-manager.c +@@ -47,60 +47,63 @@ static bool create_devices_for_terminal_and_renderer_type (ply_device_manager_t + 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_hashtable_t *renderers; + ply_terminal_t *local_console_terminal; + ply_list_t *keyboards; + ply_list_t *text_displays; + ply_list_t *pixel_displays; + struct udev *udev_context; + struct udev_queue *udev_queue; + int udev_queue_fd; + ply_fd_watch_t *udev_queue_fd_watch; + struct udev_monitor *udev_monitor; + + ply_keyboard_added_handler_t keyboard_added_handler; + ply_keyboard_removed_handler_t keyboard_removed_handler; + ply_pixel_display_added_handler_t pixel_display_added_handler; + ply_pixel_display_removed_handler_t pixel_display_removed_handler; + ply_text_display_added_handler_t text_display_added_handler; + ply_text_display_removed_handler_t text_display_removed_handler; + void *event_handler_data; + + uint32_t local_console_managed : 1; + uint32_t local_console_is_text : 1; + uint32_t serial_consoles_detected : 1; + uint32_t renderers_activated : 1; + uint32_t keyboards_activated : 1; ++ ++ uint32_t found_drm_device : 1; ++ uint32_t found_fb_device : 1; + }; + + 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 + drm_device_in_use (ply_device_manager_t *manager, + const char *device_path) + { + ply_renderer_t *renderer; +@@ -183,60 +186,68 @@ create_devices_for_udev_device (ply_device_manager_t *manager, + { + ply_trace ("found DRM device %s", device_path); + renderer_type = PLY_RENDERER_TYPE_DRM; + } + else if (strcmp (subsystem, SUBSYSTEM_FRAME_BUFFER) == 0) + { + ply_trace ("found frame buffer device %s", device_path); + if (!fb_device_has_drm_device (manager, device)) + { + renderer_type = PLY_RENDERER_TYPE_FRAME_BUFFER; + } + else + { + ply_trace ("ignoring, since there's a DRM device associated with it"); + } + } + + if (renderer_type != PLY_RENDERER_TYPE_NONE) + { + ply_terminal_t *terminal = NULL; + + if (!manager->local_console_managed) + { + terminal = manager->local_console_terminal; + } + + created = create_devices_for_terminal_and_renderer_type (manager, + device_path, + terminal, + renderer_type); ++ ++ if (created) ++ { ++ if (renderer_type == PLY_RENDERER_TYPE_DRM) ++ manager->found_drm_device = 1; ++ if (renderer_type == PLY_RENDERER_TYPE_FRAME_BUFFER) ++ manager->found_fb_device = 1; ++ } + } + } + return created; + } + + static void + free_displays_for_renderer (ply_device_manager_t *manager, + ply_renderer_t *renderer) + { + ply_list_node_t *node; + + node = ply_list_get_first_node (manager->pixel_displays); + while (node != NULL) + { + ply_list_node_t *next_node; + ply_pixel_display_t *display; + ply_renderer_t *display_renderer; + + display = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (manager->pixel_displays, node); + display_renderer = ply_pixel_display_get_renderer (display); + + if (display_renderer == renderer) + { + if (manager->pixel_display_removed_handler != NULL) + manager->pixel_display_removed_handler (manager->event_handler_data, display); + + ply_pixel_display_free (display); + ply_list_remove_node (manager->pixel_displays, node); + } +@@ -782,68 +793,66 @@ create_devices_from_terminals (ply_device_manager_t *manager) + ply_trace ("checking for consoles"); + + if (manager->flags & PLY_DEVICE_MANAGER_FLAGS_IGNORE_SERIAL_CONSOLES) + { + has_serial_consoles = false; + ply_trace ("ignoring all consoles but default console because explicitly told to."); + } + else + { + has_serial_consoles = add_consoles_from_file (manager, "/sys/class/tty/console/active"); + } + + if (has_serial_consoles) + { + ply_trace ("serial consoles detected, managing them with details forced"); + manager->serial_consoles_detected = true; + + ply_hashtable_foreach (manager->terminals, + (ply_hashtable_foreach_func_t *) + create_devices_for_terminal, + manager); + return true; + } + + return false; + } + + static void + create_devices_from_udev (ply_device_manager_t *manager) + { +- bool found_drm_device, found_fb_device; +- + ply_trace ("Looking for devices from udev"); + +- found_drm_device = create_devices_for_subsystem (manager, SUBSYSTEM_DRM); +- found_fb_device = create_devices_for_subsystem (manager, SUBSYSTEM_FRAME_BUFFER); ++ create_devices_for_subsystem (manager, SUBSYSTEM_DRM); ++ create_devices_for_subsystem (manager, SUBSYSTEM_FRAME_BUFFER); + +- if (found_drm_device || found_fb_device) ++ if (manager->found_drm_device || manager->found_fb_device) + return; + + ply_trace ("Creating non-graphical devices, since there's no suitable graphics hardware"); + create_devices_for_terminal_and_renderer_type (manager, + ply_terminal_get_name (manager->local_console_terminal), + manager->local_console_terminal, + PLY_RENDERER_TYPE_NONE); + } + + static void + create_fallback_devices (ply_device_manager_t *manager) + { + create_devices_for_terminal_and_renderer_type (manager, + ply_terminal_get_name (manager->local_console_terminal), + manager->local_console_terminal, + PLY_RENDERER_TYPE_AUTO); + } + + static void + on_udev_queue_changed (ply_device_manager_t *manager) + { + + if (!udev_queue_get_queue_is_empty (manager->udev_queue)) + return; + + ply_trace ("udev coldplug complete"); + ply_event_loop_stop_watching_fd (manager->loop, manager->udev_queue_fd_watch); + manager->udev_queue_fd_watch = NULL; + udev_queue_unref (manager->udev_queue); + +-- +2.20.1 + diff --git a/SOURCES/activate-new-renderers.patch b/SOURCES/activate-new-renderers.patch new file mode 100644 index 0000000..21f9389 --- /dev/null +++ b/SOURCES/activate-new-renderers.patch @@ -0,0 +1,2176 @@ +From 14bdb7cadcfb2d3aac54b89b91217ef58abd8377 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 24 Sep 2015 09:21:18 -0400 +Subject: [PATCH 1/6] device-manager: activate new renderers after adding to + renderers list + +When a new renderer gets created, we should activate it, if the device +manager is already active. + +At the moment we call create_pixel_displays_for_renderer which would +implicitly activate it (from a callback), except we call it one line +too early, so the renderer isn't in the list of known renderers yet. + +This commit swaps the two lines and also adds an explicit renderer +activation for clarity. For symmetry it makes the same change to +keyboards that it makes to renderers. +--- + src/libply-splash-core/ply-device-manager.c | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c +index f09448a..14d7616 100644 +--- a/src/libply-splash-core/ply-device-manager.c ++++ b/src/libply-splash-core/ply-device-manager.c +@@ -45,60 +45,62 @@ static void create_devices_for_terminal_and_renderer_type (ply_device_manager_t + 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_hashtable_t *renderers; + ply_terminal_t *local_console_terminal; + ply_list_t *keyboards; + ply_list_t *text_displays; + ply_list_t *pixel_displays; + struct udev *udev_context; + struct udev_queue *udev_queue; + int udev_queue_fd; + ply_fd_watch_t *udev_queue_fd_watch; + struct udev_monitor *udev_monitor; + + ply_keyboard_added_handler_t keyboard_added_handler; + ply_keyboard_removed_handler_t keyboard_removed_handler; + ply_pixel_display_added_handler_t pixel_display_added_handler; + ply_pixel_display_removed_handler_t pixel_display_removed_handler; + ply_text_display_added_handler_t text_display_added_handler; + ply_text_display_removed_handler_t text_display_removed_handler; + void *event_handler_data; + + uint32_t local_console_managed : 1; + uint32_t local_console_is_text : 1; + uint32_t serial_consoles_detected : 1; ++ uint32_t renderers_activated : 1; ++ uint32_t keyboards_activated : 1; + }; + + 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 + drm_device_in_use (ply_device_manager_t *manager, + const char *device_path) + { + ply_renderer_t *renderer; +@@ -696,85 +698,92 @@ create_devices_for_terminal_and_renderer_type (ply_device_manager_t *manager, + ply_trace ("ignoring device %s since it's already managed", + device_path); + return; + } + + ply_trace ("creating devices for %s (renderer type: %u) (terminal: %s)", + device_path? : "", renderer_type, terminal? ply_terminal_get_name (terminal): "none"); + + if (renderer_type != PLY_RENDERER_TYPE_NONE) + { + renderer = ply_renderer_new (renderer_type, device_path, terminal); + + if (!ply_renderer_open (renderer)) + { + ply_trace ("could not open renderer for %s", device_path); + ply_renderer_free (renderer); + renderer = NULL; + if (renderer_type != PLY_RENDERER_TYPE_AUTO) + return; + } + } + + if (renderer != NULL) + { + keyboard = ply_keyboard_new_for_renderer (renderer); + ply_list_append_data (manager->keyboards, keyboard); + + if (manager->keyboard_added_handler != NULL) + manager->keyboard_added_handler (manager->event_handler_data, keyboard); + +- create_pixel_displays_for_renderer (manager, renderer); + ply_hashtable_insert (manager->renderers, strdup (device_path), renderer); ++ create_pixel_displays_for_renderer (manager, renderer); ++ ++ if (manager->renderers_activated) ++ { ++ ply_trace ("activating renderer"); ++ ply_renderer_activate (renderer); ++ } + } + else if (terminal != NULL) + { + keyboard = ply_keyboard_new_for_terminal (terminal); + ply_list_append_data (manager->keyboards, keyboard); + + if (manager->keyboard_added_handler != NULL) + manager->keyboard_added_handler (manager->event_handler_data, keyboard); + } + + if (terminal != NULL) + { + create_text_displays_for_terminal (manager, terminal); + + if (terminal == manager->local_console_terminal) + { + manager->local_console_is_text = renderer == NULL; + manager->local_console_managed = true; + } + } + +- if (keyboard != NULL) ++ if (keyboard != NULL && manager->keyboards_activated) + { ++ ply_trace ("activating keyboards"); + ply_keyboard_watch_for_input (keyboard); + } + } + + static void + create_devices_for_terminal (const char *device_path, + ply_terminal_t *terminal, + ply_device_manager_t *manager) + { + create_devices_for_terminal_and_renderer_type (manager, + device_path, + terminal, + PLY_RENDERER_TYPE_NONE); + } + static bool + create_devices_from_terminals (ply_device_manager_t *manager) + { + bool has_serial_consoles; + + ply_trace ("checking for consoles"); + + if (manager->flags & PLY_DEVICE_MANAGER_FLAGS_IGNORE_SERIAL_CONSOLES) + { + has_serial_consoles = false; + ply_trace ("ignoring all consoles but default console because explicitly told to."); + } + else + { + has_serial_consoles = add_consoles_from_file (manager, "/sys/class/tty/console/active"); + } +@@ -946,91 +955,98 @@ ply_device_manager_get_text_displays (ply_device_manager_t *manager) + } + + ply_terminal_t * + ply_device_manager_get_default_terminal (ply_device_manager_t *manager) + { + return manager->local_console_terminal; + } + + bool + ply_device_manager_has_serial_consoles (ply_device_manager_t *manager) + { + return manager->serial_consoles_detected; + } + + static void + activate_renderer (char *device_path, + ply_renderer_t *renderer, + ply_device_manager_t *manager) + { + ply_renderer_activate (renderer); + } + + void + ply_device_manager_activate_renderers (ply_device_manager_t *manager) + { + ply_trace ("activating renderers"); + ply_hashtable_foreach (manager->renderers, + (ply_hashtable_foreach_func_t *) + activate_renderer, + manager); ++ ++ manager->renderers_activated = true; + } + + static void + deactivate_renderer (char *device_path, + ply_renderer_t *renderer, + ply_device_manager_t *manager) + { + ply_renderer_deactivate (renderer); + } + + void + ply_device_manager_deactivate_renderers (ply_device_manager_t *manager) + { + ply_trace ("deactivating renderers"); + ply_hashtable_foreach (manager->renderers, + (ply_hashtable_foreach_func_t *) + deactivate_renderer, + manager); ++ manager->renderers_activated = false; + } + + 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->keyboards); + while (node != NULL) + { + ply_keyboard_t *keyboard; + ply_list_node_t *next_node; + + keyboard = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (manager->keyboards, node); + + ply_keyboard_watch_for_input (keyboard); + + node = next_node; + } ++ ++ manager->keyboards_activated = true; + } + + 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->keyboards); + while (node != NULL) + { + ply_keyboard_t *keyboard; + ply_list_node_t *next_node; + + keyboard = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (manager->keyboards, node); + + ply_keyboard_stop_watching_for_input (keyboard); + + node = next_node; + } ++ ++ manager->keyboards_activated = false; + } +-- +2.5.0 + + +From 61ca85cd95de1e467e4996a5563c5f77221e569f Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 24 Sep 2015 15:53:01 -0400 +Subject: [PATCH 2/6] plugins: unset draw handler when freeing view + +If the view is freed, we definitely shouldn't draw +the view's display anymore. +--- + src/plugins/splash/fade-throbber/plugin.c | 4 ++-- + src/plugins/splash/space-flares/plugin.c | 4 ++-- + src/plugins/splash/throbgress/plugin.c | 4 ++-- + src/plugins/splash/two-step/plugin.c | 3 ++- + 4 files changed, 8 insertions(+), 7 deletions(-) + +diff --git a/src/plugins/splash/fade-throbber/plugin.c b/src/plugins/splash/fade-throbber/plugin.c +index 4af6cae..7b097c0 100644 +--- a/src/plugins/splash/fade-throbber/plugin.c ++++ b/src/plugins/splash/fade-throbber/plugin.c +@@ -240,60 +240,62 @@ free_stars (view_t *view) + + static void detach_from_event_loop (ply_boot_splash_plugin_t *plugin); + + static view_t * + view_new (ply_boot_splash_plugin_t *plugin, + ply_pixel_display_t *display) + { + view_t *view; + + view = calloc (1, sizeof (view_t)); + view->plugin = plugin; + view->display = display; + + view->entry = ply_entry_new (plugin->image_dir); + view->stars = ply_list_new (); + view->label = ply_label_new (); + + view->message_label = ply_label_new (); + + return view; + } + + static void + view_free (view_t *view) + { + + ply_entry_free (view->entry); + ply_label_free (view->message_label); + free_stars (view); + ++ ply_pixel_display_set_draw_handler (view->display, NULL, NULL); ++ + free (view); + } + + static bool + view_load (view_t *view) + { + ply_trace ("loading entry"); + if (!ply_entry_load (view->entry)) + return false; + + return true; + } + + static bool + load_views (ply_boot_splash_plugin_t *plugin) + { + ply_list_node_t *node; + bool view_loaded; + + view_loaded = false; + node = ply_list_get_first_node (plugin->views); + + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + +@@ -753,62 +755,60 @@ add_pixel_display (ply_boot_splash_plugin_t *plugin, + ply_pixel_display_t *display) + { + view_t *view; + + view = view_new (plugin, display); + + ply_pixel_display_set_draw_handler (view->display, + (ply_pixel_display_draw_handler_t) + on_draw, view); + + ply_list_append_data (plugin->views, view); + } + + static void + remove_pixel_display (ply_boot_splash_plugin_t *plugin, + ply_pixel_display_t *display) + { + ply_list_node_t *node; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + view_t *view; + ply_list_node_t *next_node; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + if (view->display == display) + { +- +- ply_pixel_display_set_draw_handler (view->display, NULL, NULL); + view_free (view); + ply_list_remove_node (plugin->views, node); + return; + } + + node = next_node; + } + } + + static bool + show_splash_screen (ply_boot_splash_plugin_t *plugin, + ply_event_loop_t *loop, + ply_buffer_t *boot_buffer, + ply_boot_splash_mode_t mode) + { + assert (plugin != NULL); + assert (plugin->logo_image != NULL); + + plugin->loop = loop; + plugin->mode = mode; + + ply_trace ("loading logo image"); + if (!ply_image_load (plugin->logo_image)) + return false; + + ply_trace ("loading star image"); + if (!ply_image_load (plugin->star_image)) + return false; + + ply_trace ("loading lock image"); +diff --git a/src/plugins/splash/space-flares/plugin.c b/src/plugins/splash/space-flares/plugin.c +index e31dce8..45863ff 100644 +--- a/src/plugins/splash/space-flares/plugin.c ++++ b/src/plugins/splash/space-flares/plugin.c +@@ -210,60 +210,62 @@ static view_t * + view_new (ply_boot_splash_plugin_t *plugin, + ply_pixel_display_t *display) + { + view_t *view; + + view = calloc (1, sizeof (view_t)); + view->plugin = plugin; + view->display = display; + + view->entry = ply_entry_new (plugin->image_dir); + view->label = ply_label_new (); + view->message_label = ply_label_new (); + + view->sprites = ply_list_new (); + + return view; + } + + static void view_free_sprites (view_t *view); + + static void + view_free (view_t *view) + { + + ply_entry_free (view->entry); + ply_label_free (view->label); + ply_label_free (view->message_label); + view_free_sprites (view); + ply_list_free (view->sprites); + ++ ply_pixel_display_set_draw_handler (view->display, NULL, NULL); ++ + ply_image_free (view->scaled_background_image); + + free (view); + } + + static void + free_views (ply_boot_splash_plugin_t *plugin) + { + ply_list_node_t *node; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + view_free (view); + + node = next_node; + } + + ply_list_free (plugin->views); + plugin->views = NULL; + } + + static bool + view_load (view_t *view) +@@ -1428,62 +1430,60 @@ add_pixel_display (ply_boot_splash_plugin_t *plugin, + ply_pixel_display_t *display) + { + view_t *view; + + view = view_new (plugin, display); + + ply_pixel_display_set_draw_handler (view->display, + (ply_pixel_display_draw_handler_t) + on_draw, view); + + ply_list_append_data (plugin->views, view); + } + + static void + remove_pixel_display (ply_boot_splash_plugin_t *plugin, + ply_pixel_display_t *display) + { + ply_list_node_t *node; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + view_t *view; + ply_list_node_t *next_node; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + if (view->display == display) + { +- +- ply_pixel_display_set_draw_handler (view->display, NULL, NULL); + view_free (view); + ply_list_remove_node (plugin->views, node); + return; + } + + node = next_node; + } + } + + static void + view_setup_scene (view_t *view) + { + ply_boot_splash_plugin_t *plugin; + sprite_t *sprite; + int i; + int x, y; + int width = 360; + int height = 460; + unsigned long screen_width, screen_height; + + plugin = view->plugin; + + screen_width = ply_pixel_display_get_width (view->display); + screen_height = ply_pixel_display_get_height (view->display); + + { + star_bg_t* star_bg; + if (view->scaled_background_image) + ply_image_free (view->scaled_background_image); + view->scaled_background_image = ply_image_resize (plugin->logo_image, screen_width, screen_height); +diff --git a/src/plugins/splash/throbgress/plugin.c b/src/plugins/splash/throbgress/plugin.c +index fba809b..d669a74 100644 +--- a/src/plugins/splash/throbgress/plugin.c ++++ b/src/plugins/splash/throbgress/plugin.c +@@ -115,60 +115,62 @@ static void become_idle (ply_boot_splash_plugin_t *plugin, + static view_t * + view_new (ply_boot_splash_plugin_t *plugin, + ply_pixel_display_t *display) + { + view_t *view; + + view = calloc (1, sizeof (view_t)); + view->plugin = plugin; + view->display = display; + + view->entry = ply_entry_new (plugin->image_dir); + view->throbber = ply_throbber_new (plugin->image_dir, + "throbber-"); + view->progress_bar = ply_progress_bar_new (); + view->label = ply_label_new (); + view->message_label = ply_label_new (); + + return view; + } + + static void + view_free (view_t *view) + { + + ply_entry_free (view->entry); + ply_throbber_free (view->throbber); + ply_progress_bar_free (view->progress_bar); + ply_label_free (view->label); + ply_label_free (view->message_label); + ++ ply_pixel_display_set_draw_handler (view->display, NULL, NULL); ++ + free (view); + } + + static void + free_views (ply_boot_splash_plugin_t *plugin) + { + ply_list_node_t *node; + + node = ply_list_get_first_node (plugin->views); + + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + view_free (view); + ply_list_remove_node (plugin->views, node); + + node = next_node; + } + + ply_list_free (plugin->views); + plugin->views = NULL; + } + + static bool + view_load (view_t *view) +@@ -631,62 +633,60 @@ add_pixel_display (ply_boot_splash_plugin_t *plugin, + view_t *view; + + ply_trace ("adding pixel display to plugin"); + view = view_new (plugin, display); + + ply_pixel_display_set_draw_handler (view->display, + (ply_pixel_display_draw_handler_t) + on_draw, view); + + ply_list_append_data (plugin->views, view); + } + + static void + remove_pixel_display (ply_boot_splash_plugin_t *plugin, + ply_pixel_display_t *display) + { + ply_list_node_t *node; + + ply_trace ("removing pixel display from plugin"); + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + view_t *view; + ply_list_node_t *next_node; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + if (view->display == display) + { +- +- ply_pixel_display_set_draw_handler (view->display, NULL, NULL); + view_free (view); + ply_list_remove_node (plugin->views, node); + return; + } + + node = next_node; + } + } + + static bool + show_splash_screen (ply_boot_splash_plugin_t *plugin, + ply_event_loop_t *loop, + ply_buffer_t *boot_buffer, + ply_boot_splash_mode_t mode) + { + assert (plugin != NULL); + assert (plugin->logo_image != NULL); + + plugin->loop = loop; + plugin->mode = mode; + + ply_trace ("loading logo image"); + if (!ply_image_load (plugin->logo_image)) + return false; + + ply_trace ("loading lock image"); + if (!ply_image_load (plugin->lock_image)) + return false; + + ply_trace ("loading box image"); +diff --git a/src/plugins/splash/two-step/plugin.c b/src/plugins/splash/two-step/plugin.c +index f48b41e..0253aac 100644 +--- a/src/plugins/splash/two-step/plugin.c ++++ b/src/plugins/splash/two-step/plugin.c +@@ -155,60 +155,62 @@ view_new (ply_boot_splash_plugin_t *plugin, + + view->entry = ply_entry_new (plugin->animation_dir); + view->end_animation = ply_animation_new (plugin->animation_dir, + "animation-"); + view->progress_animation = ply_progress_animation_new (plugin->animation_dir, + "progress-"); + + view->throbber = ply_throbber_new (plugin->animation_dir, + "throbber-"); + ply_progress_animation_set_transition (view->progress_animation, + plugin->transition, + plugin->transition_duration); + + view->label = ply_label_new (); + view->message_label = ply_label_new (); + + return view; + } + + static void + view_free (view_t *view) + { + + ply_entry_free (view->entry); + ply_animation_free (view->end_animation); + ply_progress_animation_free (view->progress_animation); + ply_throbber_free (view->throbber); + ply_label_free (view->label); + ply_label_free (view->message_label); + ++ ply_pixel_display_set_draw_handler (view->display, NULL, NULL); ++ + if (view->background_image != NULL) + ply_image_free (view->background_image); + + free (view); + } + + static bool + view_load (view_t *view) + { + unsigned long screen_width, screen_height; + ply_boot_splash_plugin_t *plugin; + + plugin = view->plugin; + + screen_width = ply_pixel_display_get_width (view->display); + screen_height = ply_pixel_display_get_height (view->display); + + if (plugin->background_tile_image != NULL) + { + ply_trace ("tiling background to %lux%lu", screen_width, screen_height); + view->background_image = ply_image_tile (plugin->background_tile_image, screen_width, screen_height); + } + + if (plugin->watermark_image != NULL) + { + view->watermark_area.width = ply_image_get_width (plugin->watermark_image); + view->watermark_area.height = ply_image_get_height (plugin->watermark_image); + view->watermark_area.x = screen_width * plugin->watermark_horizontal_alignment - ply_image_get_width (plugin->watermark_image) * plugin->watermark_horizontal_alignment; + view->watermark_area.y = screen_height * plugin->watermark_vertical_alignment - ply_image_get_height (plugin->watermark_image) * plugin->watermark_vertical_alignment; + } +@@ -993,61 +995,60 @@ add_pixel_display (ply_boot_splash_plugin_t *plugin, + view_t *view; + + ply_trace ("adding pixel display to plugin"); + view = view_new (plugin, display); + + ply_pixel_display_set_draw_handler (view->display, + (ply_pixel_display_draw_handler_t) + on_draw, view); + ply_list_append_data (plugin->views, view); + } + + static void + remove_pixel_display (ply_boot_splash_plugin_t *plugin, + ply_pixel_display_t *display) + { + ply_list_node_t *node; + + ply_trace ("removing pixel display from plugin"); + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + view_t *view; + ply_list_node_t *next_node; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + if (view->display == display) + { + +- ply_pixel_display_set_draw_handler (view->display, NULL, NULL); + view_free (view); + ply_list_remove_node (plugin->views, node); + return; + } + + node = next_node; + } + } + + static bool + show_splash_screen (ply_boot_splash_plugin_t *plugin, + ply_event_loop_t *loop, + ply_buffer_t *boot_buffer, + ply_boot_splash_mode_t mode) + { + assert (plugin != NULL); + + plugin->loop = loop; + plugin->mode = mode; + + ply_trace ("loading lock image"); + if (!ply_image_load (plugin->lock_image)) + return false; + + ply_trace ("loading box image"); + if (!ply_image_load (plugin->box_image)) + return false; + + if (plugin->corner_image != NULL) + { +-- +2.5.0 + + +From b849b3edc60cac8d1c1f7a66d103768abdb71666 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 24 Sep 2015 15:55:08 -0400 +Subject: [PATCH 3/6] plugins: free views that can't load + +Trying to use an unloaded view can lead to crashes. +If a view can't be loaded, free it right away. +--- + src/plugins/splash/fade-throbber/plugin.c | 9 ++++++++- + src/plugins/splash/space-flares/plugin.c | 9 ++++++++- + src/plugins/splash/throbgress/plugin.c | 9 ++++++++- + src/plugins/splash/two-step/plugin.c | 9 ++++++++- + 4 files changed, 32 insertions(+), 4 deletions(-) + +diff --git a/src/plugins/splash/fade-throbber/plugin.c b/src/plugins/splash/fade-throbber/plugin.c +index 7b097c0..953186d 100644 +--- a/src/plugins/splash/fade-throbber/plugin.c ++++ b/src/plugins/splash/fade-throbber/plugin.c +@@ -273,61 +273,68 @@ view_free (view_t *view) + } + + static bool + view_load (view_t *view) + { + ply_trace ("loading entry"); + if (!ply_entry_load (view->entry)) + return false; + + return true; + } + + static bool + load_views (ply_boot_splash_plugin_t *plugin) + { + ply_list_node_t *node; + bool view_loaded; + + view_loaded = false; + node = ply_list_get_first_node (plugin->views); + + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + if (view_load (view)) +- view_loaded = true; ++ { ++ view_loaded = true; ++ } ++ else ++ { ++ ply_list_remove_node (plugin->views, node); ++ view_free (view); ++ } + + node = next_node; + } + + return view_loaded; + } + + static void + view_redraw (view_t *view) + { + unsigned long screen_width, screen_height; + + screen_width = ply_pixel_display_get_width (view->display); + screen_height = ply_pixel_display_get_height (view->display); + + ply_pixel_display_draw_area (view->display, 0, 0, + screen_width, screen_height); + } + + static void + redraw_views (ply_boot_splash_plugin_t *plugin) + { + ply_list_node_t *node; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + +diff --git a/src/plugins/splash/space-flares/plugin.c b/src/plugins/splash/space-flares/plugin.c +index 45863ff..b18f39f 100644 +--- a/src/plugins/splash/space-flares/plugin.c ++++ b/src/plugins/splash/space-flares/plugin.c +@@ -268,61 +268,68 @@ free_views (ply_boot_splash_plugin_t *plugin) + } + + static bool + view_load (view_t *view) + { + ply_trace ("loading entry"); + if (!ply_entry_load (view->entry)) + return false; + + return true; + } + + static bool + load_views (ply_boot_splash_plugin_t *plugin) + { + ply_list_node_t *node; + bool view_loaded; + + view_loaded = false; + node = ply_list_get_first_node (plugin->views); + + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + if (view_load (view)) +- view_loaded = true; ++ { ++ view_loaded = true; ++ } ++ else ++ { ++ ply_list_remove_node (plugin->views, node); ++ view_free (view); ++ } + + node = next_node; + } + + return view_loaded; + } + + static void + view_redraw (view_t *view) + { + unsigned long screen_width, screen_height; + + screen_width = ply_pixel_display_get_width (view->display); + screen_height = ply_pixel_display_get_height (view->display); + + ply_pixel_display_draw_area (view->display, 0, 0, + screen_width, screen_height); + } + + static void + redraw_views (ply_boot_splash_plugin_t *plugin) + { + ply_list_node_t *node; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + +diff --git a/src/plugins/splash/throbgress/plugin.c b/src/plugins/splash/throbgress/plugin.c +index d669a74..e3ce91b 100644 +--- a/src/plugins/splash/throbgress/plugin.c ++++ b/src/plugins/splash/throbgress/plugin.c +@@ -177,61 +177,68 @@ view_load (view_t *view) + { + ply_trace ("loading entry"); + if (!ply_entry_load (view->entry)) + return false; + + ply_trace ("loading throbber"); + if (!ply_throbber_load (view->throbber)) + return false; + + return true; + } + + static bool + load_views (ply_boot_splash_plugin_t *plugin) + { + ply_list_node_t *node; + bool view_loaded; + + view_loaded = false; + node = ply_list_get_first_node (plugin->views); + + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + if (view_load (view)) +- view_loaded = true; ++ { ++ view_loaded = true; ++ } ++ else ++ { ++ ply_list_remove_node (plugin->views, node); ++ view_free (view); ++ } + + node = next_node; + } + + return view_loaded; + } + + static void + view_redraw (view_t *view) + { + unsigned long screen_width, screen_height; + + screen_width = ply_pixel_display_get_width (view->display); + screen_height = ply_pixel_display_get_height (view->display); + + ply_pixel_display_draw_area (view->display, 0, 0, + screen_width, screen_height); + } + + static void + redraw_views (ply_boot_splash_plugin_t *plugin) + { + ply_list_node_t *node; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + +diff --git a/src/plugins/splash/two-step/plugin.c b/src/plugins/splash/two-step/plugin.c +index 0253aac..4612e3f 100644 +--- a/src/plugins/splash/two-step/plugin.c ++++ b/src/plugins/splash/two-step/plugin.c +@@ -257,61 +257,68 @@ view_load (view_t *view) + ply_throbber_free (view->throbber); + view->throbber = NULL; + } + } + else + { + ply_trace ("this theme has no throbber\n"); + } + + return true; + } + + static bool + load_views (ply_boot_splash_plugin_t *plugin) + { + ply_list_node_t *node; + bool view_loaded; + + view_loaded = false; + node = ply_list_get_first_node (plugin->views); + + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + if (view_load (view)) +- view_loaded = true; ++ { ++ view_loaded = true; ++ } ++ else ++ { ++ ply_list_remove_node (plugin->views, node); ++ view_free (view); ++ } + + node = next_node; + } + + return view_loaded; + } + + static void + view_redraw (view_t *view) + { + unsigned long screen_width, screen_height; + + screen_width = ply_pixel_display_get_width (view->display); + screen_height = ply_pixel_display_get_height (view->display); + + ply_pixel_display_draw_area (view->display, 0, 0, + screen_width, screen_height); + } + + static void + redraw_views (ply_boot_splash_plugin_t *plugin) + { + ply_list_node_t *node; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + +-- +2.5.0 + + +From a790e8d26d81b978ed2d90a5730c717af9dc673b Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 24 Sep 2015 15:57:59 -0400 +Subject: [PATCH 4/6] plugins: load view of hot plugged displays immediately + +If we're already chugging along, and a new display +gets added make sure to load the view associated with +that display right away. + +Using an unloaded view can lead to crashes. +--- + src/plugins/splash/fade-throbber/plugin.c | 18 ++++++++++++++++-- + src/plugins/splash/space-flares/plugin.c | 13 +++++++++++-- + src/plugins/splash/text/plugin.c | 3 +++ + src/plugins/splash/throbgress/plugin.c | 13 +++++++++++-- + src/plugins/splash/tribar/plugin.c | 7 ++++++- + src/plugins/splash/two-step/plugin.c | 12 +++++++++++- + 6 files changed, 58 insertions(+), 8 deletions(-) + +diff --git a/src/plugins/splash/fade-throbber/plugin.c b/src/plugins/splash/fade-throbber/plugin.c +index 953186d..946a732 100644 +--- a/src/plugins/splash/fade-throbber/plugin.c ++++ b/src/plugins/splash/fade-throbber/plugin.c +@@ -76,60 +76,61 @@ typedef struct + } star_t; + + typedef struct + { + ply_boot_splash_plugin_t *plugin; + ply_pixel_display_t *display; + ply_list_t *stars; + ply_entry_t *entry; + ply_label_t *label; + ply_label_t *message_label; + ply_rectangle_t lock_area; + double logo_opacity; + } view_t; + + struct _ply_boot_splash_plugin + { + ply_event_loop_t *loop; + ply_boot_splash_mode_t mode; + ply_image_t *logo_image; + ply_image_t *star_image; + ply_image_t *lock_image; + char *image_dir; + ply_list_t *views; + + ply_boot_splash_display_type_t state; + + double start_time; + double now; + + uint32_t is_animating : 1; ++ uint32_t is_visible : 1; + }; + + ply_boot_splash_plugin_interface_t *ply_boot_splash_plugin_get_interface (void); + + static void + view_show_prompt (view_t *view, + const char *prompt) + { + ply_boot_splash_plugin_t *plugin; + int x, y; + int entry_width, entry_height; + + assert (view != NULL); + + plugin = view->plugin; + + if (ply_entry_is_hidden (view->entry)) + { + unsigned long screen_width, screen_height; + + screen_width = ply_pixel_display_get_width (view->display); + screen_height = ply_pixel_display_get_height (view->display); + + view->lock_area.width = ply_image_get_width (plugin->lock_image); + view->lock_area.height = ply_image_get_height (plugin->lock_image); + + entry_width = ply_entry_get_width (view->entry); + entry_height = ply_entry_get_height (view->entry); + + x = screen_width / 2.0 - (view->lock_area.width + entry_width) / 2.0 + view->lock_area.width; +@@ -741,62 +742,71 @@ on_draw (view_t *view, + int width, + int height) + { + ply_boot_splash_plugin_t *plugin; + + plugin = view->plugin; + + draw_background (view, pixel_buffer, x, y, width, height); + + if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_NORMAL) + draw_normal_view (view, pixel_buffer, x, y, width, height); + else + draw_prompt_view (view, pixel_buffer, x, y, width, height); + + ply_label_draw_area (view->message_label, + pixel_buffer, + x, y, width, height); + } + + static void + add_pixel_display (ply_boot_splash_plugin_t *plugin, + ply_pixel_display_t *display) + { + view_t *view; + + view = view_new (plugin, display); + + ply_pixel_display_set_draw_handler (view->display, + (ply_pixel_display_draw_handler_t) + on_draw, view); +- +- ply_list_append_data (plugin->views, view); ++ if (plugin->is_visible) ++ { ++ if (view_load (view)) ++ ply_list_append_data (plugin->views, view); ++ else ++ view_free (view); ++ } ++ else ++ { ++ ply_list_append_data (plugin->views, view); ++ } + } + + static void + remove_pixel_display (ply_boot_splash_plugin_t *plugin, + ply_pixel_display_t *display) + { + ply_list_node_t *node; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + view_t *view; + ply_list_node_t *next_node; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + if (view->display == display) + { + view_free (view); + ply_list_remove_node (plugin->views, node); + return; + } + + node = next_node; + } + } + + static bool + show_splash_screen (ply_boot_splash_plugin_t *plugin, +@@ -805,60 +815,62 @@ show_splash_screen (ply_boot_splash_plugin_t *plugin, + ply_boot_splash_mode_t mode) + { + assert (plugin != NULL); + assert (plugin->logo_image != NULL); + + plugin->loop = loop; + plugin->mode = mode; + + ply_trace ("loading logo image"); + if (!ply_image_load (plugin->logo_image)) + return false; + + ply_trace ("loading star image"); + if (!ply_image_load (plugin->star_image)) + return false; + + ply_trace ("loading lock image"); + if (!ply_image_load (plugin->lock_image)) + return false; + + ply_event_loop_watch_for_exit (loop, (ply_event_loop_exit_handler_t) + detach_from_event_loop, + plugin); + + if (!load_views (plugin)) + { + ply_trace ("couldn't load views"); + return false; + } + ++ plugin->is_visible = true; ++ + ply_trace ("starting boot animation"); + start_animation (plugin); + + return true; + } + + static void + view_add_star (view_t *view) + { + ply_boot_splash_plugin_t *plugin; + ply_rectangle_t logo_area; + star_t *star; + unsigned int x, y; + unsigned int width, height; + unsigned long screen_width, screen_height; + ply_list_node_t *node; + + assert (view != NULL); + + plugin = view->plugin; + + screen_width = ply_pixel_display_get_width (view->display); + screen_height = ply_pixel_display_get_height (view->display); + width = ply_image_get_width (plugin->logo_image); + height = ply_image_get_height (plugin->logo_image); + logo_area.x = (screen_width / 2) - (width / 2); + logo_area.y = (screen_height / 2) - (height / 2); + logo_area.width = width; + logo_area.height = height; + +@@ -944,60 +956,62 @@ update_status (ply_boot_splash_plugin_t *plugin, + static void + show_message (ply_boot_splash_plugin_t *plugin, + const char *message) + { + ply_trace ("Showing message '%s'", message); + ply_list_node_t *node; + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + ply_label_set_text (view->message_label, message); + ply_label_show (view->message_label, view->display, 10, 10); + + ply_pixel_display_draw_area (view->display, 10, 10, + ply_label_get_width (view->message_label), + ply_label_get_height(view->message_label)); + node = next_node; + } + } + + static void + hide_splash_screen (ply_boot_splash_plugin_t *plugin, + ply_event_loop_t *loop) + { + assert (plugin != NULL); + ++ plugin->is_visible = false; ++ + if (plugin->loop != NULL) + { + stop_animation (plugin); + + ply_event_loop_stop_watching_for_exit (plugin->loop, (ply_event_loop_exit_handler_t) + detach_from_event_loop, + plugin); + detach_from_event_loop (plugin); + } + } + + static void + show_password_prompt (ply_boot_splash_plugin_t *plugin, + const char *text, + int number_of_bullets) + { + ply_list_node_t *node; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + view_show_prompt (view, text); + ply_entry_set_bullet_count (view->entry, number_of_bullets); + +diff --git a/src/plugins/splash/space-flares/plugin.c b/src/plugins/splash/space-flares/plugin.c +index b18f39f..9e53617 100644 +--- a/src/plugins/splash/space-flares/plugin.c ++++ b/src/plugins/splash/space-flares/plugin.c +@@ -1416,62 +1416,71 @@ draw_background (view_t *view, + image_area.width = ply_image_get_width(plugin->star_image); + image_area.height = ply_image_get_height(plugin->star_image); + + + ply_pixel_buffer_fill_with_argb32_data_with_clip (pixel_buffer, + &image_area, &area, + ply_image_get_data (plugin->star_image)); + + image_area.x = 20; + image_area.y = 20; + image_area.width = ply_image_get_width(plugin->logo_image); + image_area.height = ply_image_get_height(plugin->logo_image); + + + ply_pixel_buffer_fill_with_argb32_data_with_clip (pixel_buffer, + &image_area, &area, + ply_image_get_data (plugin->logo_image)); + } + + static void + add_pixel_display (ply_boot_splash_plugin_t *plugin, + ply_pixel_display_t *display) + { + view_t *view; + + view = view_new (plugin, display); + + ply_pixel_display_set_draw_handler (view->display, + (ply_pixel_display_draw_handler_t) + on_draw, view); +- +- ply_list_append_data (plugin->views, view); ++ if (plugin->is_visible) ++ { ++ if (view_load (view)) ++ ply_list_append_data (plugin->views, view); ++ else ++ view_free (view); ++ } ++ else ++ { ++ ply_list_append_data (plugin->views, view); ++ } + } + + static void + remove_pixel_display (ply_boot_splash_plugin_t *plugin, + ply_pixel_display_t *display) + { + ply_list_node_t *node; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + view_t *view; + ply_list_node_t *next_node; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + if (view->display == display) + { + view_free (view); + ply_list_remove_node (plugin->views, node); + return; + } + + node = next_node; + } + } + + static void + view_setup_scene (view_t *view) +diff --git a/src/plugins/splash/text/plugin.c b/src/plugins/splash/text/plugin.c +index fb97c14..69125a2 100644 +--- a/src/plugins/splash/text/plugin.c ++++ b/src/plugins/splash/text/plugin.c +@@ -458,60 +458,63 @@ stop_animation (ply_boot_splash_plugin_t *plugin) + + static void + on_draw (view_t *view, + ply_terminal_t *terminal, + int x, + int y, + int width, + int height) + { + ply_text_display_clear_screen (view->display); + } + + static void + add_text_display (ply_boot_splash_plugin_t *plugin, + ply_text_display_t *display) + { + view_t *view; + ply_terminal_t *terminal; + + view = view_new (plugin, display); + + terminal = ply_text_display_get_terminal (view->display); + if (ply_terminal_open (terminal)) + ply_terminal_activate_vt (terminal); + + ply_text_display_set_draw_handler (view->display, + (ply_text_display_draw_handler_t) + on_draw, view); + + ply_list_append_data (plugin->views, view); ++ ++ if (plugin->is_animating) ++ view_start_animation (view); + } + + static void + remove_text_display (ply_boot_splash_plugin_t *plugin, + ply_text_display_t *display) + { + ply_list_node_t *node; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + view_t *view; + ply_list_node_t *next_node; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + if (view->display == display) + { + ply_text_display_set_draw_handler (view->display, + NULL, NULL); + view_free (view); + ply_list_remove_node (plugin->views, node); + return; + } + + node = next_node; + } + } + +diff --git a/src/plugins/splash/throbgress/plugin.c b/src/plugins/splash/throbgress/plugin.c +index e3ce91b..c4d0555 100644 +--- a/src/plugins/splash/throbgress/plugin.c ++++ b/src/plugins/splash/throbgress/plugin.c +@@ -618,62 +618,71 @@ on_draw (view_t *view, + lock_data = ply_image_get_data (plugin->lock_image); + ply_pixel_buffer_fill_with_argb32_data (pixel_buffer, + &view->lock_area, + lock_data); + } + else + { + draw_logo (view, pixel_buffer); + ply_throbber_draw_area (view->throbber, + pixel_buffer, x, y, width, height); + ply_progress_bar_draw_area (view->progress_bar, + pixel_buffer, x, y, width, height); + } + ply_label_draw_area (view->message_label, + pixel_buffer, + x, y, width, height); + } + + static void + add_pixel_display (ply_boot_splash_plugin_t *plugin, + ply_pixel_display_t *display) + { + view_t *view; + + ply_trace ("adding pixel display to plugin"); + view = view_new (plugin, display); + + ply_pixel_display_set_draw_handler (view->display, + (ply_pixel_display_draw_handler_t) + on_draw, view); +- +- ply_list_append_data (plugin->views, view); ++ if (plugin->is_visible) ++ { ++ if (view_load (view)) ++ ply_list_append_data (plugin->views, view); ++ else ++ view_free (view); ++ } ++ else ++ { ++ ply_list_append_data (plugin->views, view); ++ } + } + + static void + remove_pixel_display (ply_boot_splash_plugin_t *plugin, + ply_pixel_display_t *display) + { + ply_list_node_t *node; + + ply_trace ("removing pixel display from plugin"); + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + view_t *view; + ply_list_node_t *next_node; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + if (view->display == display) + { + view_free (view); + ply_list_remove_node (plugin->views, node); + return; + } + + node = next_node; + } + } + + static bool +diff --git a/src/plugins/splash/tribar/plugin.c b/src/plugins/splash/tribar/plugin.c +index 4458bad..5b89cc3 100644 +--- a/src/plugins/splash/tribar/plugin.c ++++ b/src/plugins/splash/tribar/plugin.c +@@ -461,60 +461,63 @@ stop_animation (ply_boot_splash_plugin_t *plugin) + + static void + on_draw (view_t *view, + ply_terminal_t *terminal, + int x, + int y, + int width, + int height) + { + ply_text_display_clear_screen (view->display); + } + + static void + add_text_display (ply_boot_splash_plugin_t *plugin, + ply_text_display_t *display) + { + view_t *view; + ply_terminal_t *terminal; + + view = view_new (plugin, display); + + terminal = ply_text_display_get_terminal (view->display); + if (ply_terminal_open (terminal)) + ply_terminal_activate_vt (terminal); + + ply_text_display_set_draw_handler (view->display, + (ply_text_display_draw_handler_t) + on_draw, view); + + ply_list_append_data (plugin->views, view); ++ ++ if (plugin->is_animating) ++ view_start_animation (view); + } + + static void + remove_text_display (ply_boot_splash_plugin_t *plugin, + ply_text_display_t *display) + { + ply_list_node_t *node; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + view_t *view; + ply_list_node_t *next_node; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + if (view->display == display) + { + ply_text_display_set_draw_handler (view->display, + NULL, NULL); + view_free (view); + ply_list_remove_node (plugin->views, node); + return; + } + + node = next_node; + } + } + +@@ -545,61 +548,63 @@ update_status (ply_boot_splash_plugin_t *plugin, + assert (plugin != NULL); + + ply_trace ("status update"); + } + + static void + on_boot_progress (ply_boot_splash_plugin_t *plugin, + double duration, + double percent_done) + { + ply_list_node_t *node; + double total_duration; + + total_duration = duration / percent_done; + + /* Fun made-up smoothing function to make the growth asymptotic: + * fraction(time,estimate)=1-2^(-(time^1.45)/estimate) */ + percent_done = 1.0 - pow (2.0, -pow (duration, 1.45) / total_duration) * (1.0 - percent_done); + + node = ply_list_get_first_node (plugin->views); + + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + ply_text_progress_bar_set_percent_done (view->progress_bar, percent_done); +- ply_text_progress_bar_draw (view->progress_bar); ++ ++ if (plugin->is_animating) ++ ply_text_progress_bar_draw (view->progress_bar); + + node = next_node; + } + } + + static void + hide_splash_screen (ply_boot_splash_plugin_t *plugin, + ply_event_loop_t *loop) + { + assert (plugin != NULL); + + ply_trace ("hiding splash screen"); + + if (plugin->loop != NULL) + { + stop_animation (plugin); + + ply_event_loop_stop_watching_for_exit (plugin->loop, + (ply_event_loop_exit_handler_t) + detach_from_event_loop, + plugin); + detach_from_event_loop (plugin); + } + + hide_views (plugin); + ply_show_new_kernel_messages (true); + } + + static void + display_normal (ply_boot_splash_plugin_t *plugin) +diff --git a/src/plugins/splash/two-step/plugin.c b/src/plugins/splash/two-step/plugin.c +index 4612e3f..a1d1f00 100644 +--- a/src/plugins/splash/two-step/plugin.c ++++ b/src/plugins/splash/two-step/plugin.c +@@ -980,61 +980,71 @@ on_draw (view_t *view, + + if (view->throbber != NULL) + sprite_height = MAX (ply_throbber_get_height (view->throbber), + sprite_height); + + image_area.width = ply_image_get_width (plugin->header_image); + image_area.height = ply_image_get_height (plugin->header_image); + image_area.x = screen_area.width / 2.0 - image_area.width / 2.0; + image_area.y = plugin->animation_vertical_alignment * screen_area.height - sprite_height / 2.0 - image_area.height; + + ply_pixel_buffer_fill_with_argb32_data (pixel_buffer, &image_area, ply_image_get_data (plugin->header_image)); + } + } + ply_label_draw_area (view->message_label, + pixel_buffer, + x, y, width, height); + } + + static void + add_pixel_display (ply_boot_splash_plugin_t *plugin, + ply_pixel_display_t *display) + { + view_t *view; + + ply_trace ("adding pixel display to plugin"); + view = view_new (plugin, display); + + ply_pixel_display_set_draw_handler (view->display, + (ply_pixel_display_draw_handler_t) + on_draw, view); +- ply_list_append_data (plugin->views, view); ++ if (plugin->is_visible) ++ { ++ if (view_load (view)) ++ ply_list_append_data (plugin->views, view); ++ else ++ view_free (view); ++ } ++ else ++ { ++ ply_list_append_data (plugin->views, view); ++ } + } + + static void + remove_pixel_display (ply_boot_splash_plugin_t *plugin, + ply_pixel_display_t *display) + { + ply_list_node_t *node; + + ply_trace ("removing pixel display from plugin"); + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + view_t *view; + ply_list_node_t *next_node; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + if (view->display == display) + { + + view_free (view); + ply_list_remove_node (plugin->views, node); + return; + } + + node = next_node; + } + } + +-- +2.5.0 + + +From 3dc6d04a80329bb97e574c2785f79a684bfdc41b Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 9 Oct 2015 12:46:49 -0400 +Subject: [PATCH 5/6] details: update new views with current boot buffer + +if a view is added after the splash is shown, make sure +to update the view with the current contents of the boot +buffer. +--- + src/plugins/splash/details/plugin.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +diff --git a/src/plugins/splash/details/plugin.c b/src/plugins/splash/details/plugin.c +index aff2f1c..6ddd654 100644 +--- a/src/plugins/splash/details/plugin.c ++++ b/src/plugins/splash/details/plugin.c +@@ -49,61 +49,61 @@ + #include "ply-text-display.h" + #include "ply-trigger.h" + #include "ply-utils.h" + + #include + + #define CLEAR_LINE_SEQUENCE "\033[2K\r" + + typedef enum { + PLY_BOOT_SPLASH_DISPLAY_NORMAL, + PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY, + PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY + } ply_boot_splash_display_type_t; + + typedef struct + { + ply_boot_splash_plugin_t *plugin; + ply_text_display_t *display; + } view_t; + + ply_boot_splash_plugin_interface_t *ply_boot_splash_plugin_get_interface (void); + static void detach_from_event_loop (ply_boot_splash_plugin_t *plugin); + + struct _ply_boot_splash_plugin + { + ply_event_loop_t *loop; + ply_boot_splash_mode_t mode; + ply_list_t *views; + ply_boot_splash_display_type_t state; + ply_list_t *messages; +- ++ ply_buffer_t *boot_buffer; + }; + + static view_t * + view_new (ply_boot_splash_plugin_t *plugin, + ply_text_display_t *display) + { + view_t *view; + + view = calloc (1, sizeof (view_t)); + view->plugin = plugin; + view->display = display; + + return view; + } + + static void + view_free (view_t *view) + { + free (view); + } + + static void + free_views (ply_boot_splash_plugin_t *plugin) + { + ply_list_node_t *node; + + node = ply_list_get_first_node (plugin->views); + + while (node != NULL) + { +@@ -217,108 +217,119 @@ write_on_views (ply_boot_splash_plugin_t *plugin, + + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + view_write (view, text, number_of_bytes); + + node = next_node; + } + + } + + static void + add_text_display (ply_boot_splash_plugin_t *plugin, + ply_text_display_t *display) + { + view_t *view; + ply_terminal_t *terminal; + + view = view_new (plugin, display); + + terminal = ply_text_display_get_terminal (view->display); + if (ply_terminal_open (terminal)) + ply_terminal_activate_vt (terminal); + + ply_list_append_data (plugin->views, view); ++ ++ if (plugin->boot_buffer != NULL) ++ { ++ size_t size; ++ const char *bytes; ++ ++ size = ply_buffer_get_size (plugin->boot_buffer); ++ bytes = ply_buffer_get_bytes (plugin->boot_buffer); ++ view_write (view, bytes, size); ++ } + } + + static void + remove_text_display (ply_boot_splash_plugin_t *plugin, + ply_text_display_t *display) + { + ply_list_node_t *node; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + view_t *view; + ply_list_node_t *next_node; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + if (view->display == display) + { + ply_list_remove_node (plugin->views, node); + return; + } + + node = next_node; + } + } + + static bool + show_splash_screen (ply_boot_splash_plugin_t *plugin, + ply_event_loop_t *loop, + ply_buffer_t *boot_buffer, + ply_boot_splash_mode_t mode) + { + size_t size; + + assert (plugin != NULL); + + plugin->loop = loop; + plugin->mode = mode; + + ply_event_loop_watch_for_exit (loop, (ply_event_loop_exit_handler_t) + detach_from_event_loop, + plugin); + + if (boot_buffer) + { +- size = ply_buffer_get_size (boot_buffer); ++ plugin->boot_buffer = boot_buffer; + ++ size = ply_buffer_get_size (boot_buffer); + write_on_views (plugin, ply_buffer_get_bytes (boot_buffer), size); + } + + return true; + } + + static void + update_status (ply_boot_splash_plugin_t *plugin, + const char *status) + { + assert (plugin != NULL); + + ply_trace ("status update"); + } + + static void + on_boot_output (ply_boot_splash_plugin_t *plugin, + const char *output, + size_t size) + { + ply_trace ("writing '%s' to all views (%d bytes)", + output, (int) size); + write_on_views (plugin, output, size); + } + + static void + hide_splash_screen (ply_boot_splash_plugin_t *plugin, + ply_event_loop_t *loop) + { + assert (plugin != NULL); +-- +2.5.0 + + +From 07864d66b30aa37908df83495d3bffc681fb34d3 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 9 Oct 2015 12:48:17 -0400 +Subject: [PATCH 6/6] main: make sure to reshow prompts when new display is + added + +When a display is added, we need to tell the splash plugin +to redisplay any pending questions, so those questions show +up on the new display. +--- + src/main.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/main.c b/src/main.c +index 875dd1a..7c4ea3c 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -1022,89 +1022,92 @@ on_keyboard_removed (state_t *state, + (ply_keyboard_escape_handler_t) + on_escape_pressed); + ply_trace ("no longer listening for backspace"); + ply_keyboard_remove_backspace_handler (keyboard, + (ply_keyboard_backspace_handler_t) + on_backspace); + ply_trace ("no longer listening for enter"); + ply_keyboard_remove_enter_handler (keyboard, + (ply_keyboard_enter_handler_t) + on_enter); + + if (state->boot_splash != NULL) + ply_boot_splash_unset_keyboard (state->boot_splash); + } + + static void + on_pixel_display_added (state_t *state, + ply_pixel_display_t *display) + { + if (state->is_shown) + { + if (state->boot_splash == NULL) + { + ply_trace ("pixel display added before splash loaded, so loading splash now"); + show_splash (state); + } + else + { + ply_trace ("pixel display added after splash loaded, so attaching to splash"); + ply_boot_splash_add_pixel_display (state->boot_splash, display); ++ update_display (state); + } + } + } + + static void + on_pixel_display_removed (state_t *state, + ply_pixel_display_t *display) + { + if (state->boot_splash == NULL) + return; + + ply_boot_splash_remove_pixel_display (state->boot_splash, display); + } + + static void + on_text_display_added (state_t *state, + ply_text_display_t *display) + { + if (state->is_shown) + { + if (state->boot_splash == NULL) + { + ply_trace ("text display added before splash loaded, so loading splash now"); + show_splash (state); + } + else + { + ply_trace ("text display added after splash loaded, so attaching to splash"); + ply_boot_splash_add_text_display (state->boot_splash, display); ++ ++ update_display (state); + } + } + } + + static void + on_text_display_removed (state_t *state, + ply_text_display_t *display) + { + if (state->boot_splash == NULL) + return; + + ply_boot_splash_remove_text_display (state->boot_splash, display); + } + + static void + load_devices (state_t *state, + ply_device_manager_flags_t flags) + { + state->device_manager = ply_device_manager_new (state->default_tty, flags); + state->local_console_terminal = ply_device_manager_get_default_terminal (state->device_manager); + + ply_device_manager_watch_devices (state->device_manager, + (ply_keyboard_added_handler_t) + on_keyboard_added, + (ply_keyboard_removed_handler_t) + on_keyboard_removed, + (ply_pixel_display_added_handler_t) + on_pixel_display_added, + (ply_pixel_display_removed_handler_t) + on_pixel_display_removed, +-- +2.5.0 + diff --git a/SOURCES/always-add-text-splash.patch b/SOURCES/always-add-text-splash.patch new file mode 100644 index 0000000..bd4298e --- /dev/null +++ b/SOURCES/always-add-text-splash.patch @@ -0,0 +1,86 @@ +From ccff8a426babb9a34e64b0024ce4d651c1ca25e5 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 17 Jan 2014 12:51:24 -0500 +Subject: [PATCH] seat: always add text displays when opening seat + +At the moment we add pixel displays if we can, or +text displays if we can't add pixel displays. + +We need to always add text displays, otherwise, the +text splash won't work when explicitly configured by +the user. +--- + src/libply-splash-core/ply-seat.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libply-splash-core/ply-seat.c b/src/libply-splash-core/ply-seat.c +index 0900346..d9c7a2b 100644 +--- a/src/libply-splash-core/ply-seat.c ++++ b/src/libply-splash-core/ply-seat.c +@@ -110,62 +110,62 @@ 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); + } ++ add_text_displays (seat); + + ply_keyboard_watch_for_input (seat->keyboard); + 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 +-- +1.8.3.1 + diff --git a/SOURCES/boot-duration b/SOURCES/boot-duration new file mode 100644 index 0000000..7fe728c --- /dev/null +++ b/SOURCES/boot-duration @@ -0,0 +1,39 @@ +0.222:RCkernelparam +0.223:RChostname +0.238:RCmountfs +0.275:RCswap +0.330:microcode_ctl +0.357:cpuspeed +0.365:ip6tables +0.380:iptables +0.385:isdn +0.504:auditd +0.508:restorecond +0.523:rsyslog +0.530:irqbalance +0.533:rpcbind +0.549:nfslock +0.561:mdmonitor +0.563:rpcidmapd +0.578:rpcgssd +0.579:messagebus +0.580:fuse +0.594:netfs +0.600:acpid +0.611:haldaemon +0.660:pcscd +0.691:udev-post +0.703:portreserve +0.712:setroubleshoot +0.749:bluetooth +0.738:sshd +0.763:ntpd +0.807:sendmail +0.876:crond +0.902:kerneloops +0.907:smolt +0.915:atd +0.927:avahi-daemon +0.941:cups +0.983:anacron +0.992:local diff --git a/SOURCES/bootlog b/SOURCES/bootlog new file mode 100644 index 0000000..9be1a64 --- /dev/null +++ b/SOURCES/bootlog @@ -0,0 +1,8 @@ +/var/log/boot.log +{ + missingok + daily + copytruncate + rotate 7 + notifempty +} diff --git a/SOURCES/charge.plymouth b/SOURCES/charge.plymouth new file mode 100644 index 0000000..801058b --- /dev/null +++ b/SOURCES/charge.plymouth @@ -0,0 +1,15 @@ +[Plymouth Theme] +Name=Charge +Description=A theme that features a spinner and subtle watermark. The Red Hat Enterprise Linux default theme. +ModuleName=two-step + +[two-step] +ImageDir=/usr/share/plymouth/themes/charge +HorizontalAlignment=.5 +VerticalAlignment=.75 +WatermarkHorizontalAlignment=1.0 +WatermarkVerticalAlignment=0.0 +Transition=none +TransitionDuration=0.0 +BackgroundStartColor=0x2e3436 +BackgroundEndColor=0x2e3436 diff --git a/SOURCES/colors.patch b/SOURCES/colors.patch new file mode 100644 index 0000000..149d164 --- /dev/null +++ b/SOURCES/colors.patch @@ -0,0 +1,16 @@ +diff -up plymouth-0.8.4/src/plugins/splash/tribar/plugin.c.colors plymouth-0.8.4/src/plugins/splash/text/plugin.c +--- plymouth-0.8.4/src/plugins/splash/tribar/plugin.c.colors 2012-03-20 11:26:05.343149459 -0400 ++++ plymouth-0.8.4/src/plugins/splash/tribar/plugin.c 2012-03-20 11:26:41.943521354 -0400 +@@ -183,10 +183,10 @@ view_start_animation (view_t *view) + 0xffffff); + ply_terminal_set_color_hex_value (terminal, + PLY_TERMINAL_COLOR_BLUE, +- 0x0073B3); ++ 0xc6bdd2); + ply_terminal_set_color_hex_value (terminal, + PLY_TERMINAL_COLOR_BROWN, +- 0x00457E); ++ 0x4e376b); + + ply_text_display_set_background_color (view->display, + PLY_TERMINAL_COLOR_BLACK); diff --git a/SOURCES/cursor-fix.patch b/SOURCES/cursor-fix.patch new file mode 100644 index 0000000..e483d71 --- /dev/null +++ b/SOURCES/cursor-fix.patch @@ -0,0 +1,526 @@ +From b96ff001587de11eaf98ace71b196cc5ab4cf007 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 14 Jul 2014 08:04:54 -0400 +Subject: [PATCH 1/5] seat: be a little more forgiving in the case there's no + open terminal + +We can end up in a situation where a seat object doesn't have a terminal +associated with it. In that case we shouldn't crash, but continue on +with no input available for that seat. + +https://bugs.freedesktop.org/show_bug.cgi?id=80553 +--- + src/libply-splash-core/ply-seat.c | 23 +++++++++++++++++++---- + 1 file changed, 19 insertions(+), 4 deletions(-) + +diff --git a/src/libply-splash-core/ply-seat.c b/src/libply-splash-core/ply-seat.c +index 2ac8bf7..cd7e5bc 100644 +--- a/src/libply-splash-core/ply-seat.c ++++ b/src/libply-splash-core/ply-seat.c +@@ -127,68 +127,83 @@ ply_seat_open (ply_seat_t *seat, + 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)) + { + ply_trace ("could not open renderer for %s", device); + ply_renderer_free (renderer); + + seat->renderer = NULL; + seat->renderer_active = false; + + if (renderer_type != PLY_RENDERER_TYPE_AUTO) + return false; + } + else + { + 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 ++ else if (seat->terminal != NULL) + { + seat->keyboard = ply_keyboard_new_for_terminal (seat->terminal); + } +- add_text_displays (seat); + +- ply_keyboard_watch_for_input (seat->keyboard); +- seat->keyboard_active = true; ++ if (seat->terminal != NULL) ++ { ++ add_text_displays (seat); ++ } ++ else ++ { ++ ply_trace ("not adding text display for seat, since seat has no associated terminal"); ++ } ++ ++ if (seat->keyboard != NULL) ++ { ++ ply_keyboard_watch_for_input (seat->keyboard); ++ seat->keyboard_active = true; ++ } ++ else ++ { ++ ply_trace ("not watching seat for input"); ++ } + + 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) +-- +2.3.7 + + +From b5ed92bc2efd0b52e901a67ea8e5afa809ca3598 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 3 Jul 2015 09:29:39 -0400 +Subject: [PATCH 2/5] main: show cursor on crash + +--- + src/main.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/main.c b/src/main.c +index 77fa96f..db5c281 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -2051,66 +2051,69 @@ on_error_message (ply_buffer_t *debug_buffer, + { + ply_buffer_append_bytes (debug_buffer, bytes, number_of_bytes); + } + + static void + dump_debug_buffer_to_file (void) + { + int fd; + const char *bytes; + size_t size; + + fd = open (debug_buffer_path, + O_WRONLY | O_CREAT | O_TRUNC, 0600); + + if (fd < 0) + return; + + size = ply_buffer_get_size (debug_buffer); + bytes = ply_buffer_get_bytes (debug_buffer); + ply_write (fd, bytes, size); + close (fd); + } + + #include + #include + static void + on_crash (int signum) + { + struct termios term_attributes; + int fd; ++ static const char *show_cursor_sequence = "\033[?25h"; + + fd = open ("/dev/tty1", O_RDWR | O_NOCTTY); + if (fd < 0) fd = open ("/dev/hvc0", O_RDWR | O_NOCTTY); + + ioctl (fd, KDSETMODE, KD_TEXT); + ++ write (fd, show_cursor_sequence, sizeof (show_cursor_sequence) - 1); ++ + tcgetattr (fd, &term_attributes); + + term_attributes.c_iflag |= BRKINT | IGNPAR | ICRNL | IXON; + term_attributes.c_oflag |= OPOST; + term_attributes.c_lflag |= ECHO | ICANON | ISIG | IEXTEN; + + tcsetattr (fd, TCSAFLUSH, &term_attributes); + + close (fd); + + if (debug_buffer != NULL) + { + dump_debug_buffer_to_file (); + sleep (30); + } + + if (pid_file != NULL) + { + unlink (pid_file); + free (pid_file); + pid_file = NULL; + } + + signal (signum, SIG_DFL); + raise(signum); + } + + static void + write_pid_file (const char *filename) + { +-- +2.3.7 + + +From 4278596f4f5a6856aff50e97b7c0ff05aed67372 Mon Sep 17 00:00:00 2001 +From: Frederic Crozat +Date: Thu, 12 Jun 2014 15:01:37 +0200 +Subject: [PATCH 3/5] device-manager: only call ply_terminal_free + +ply_terminal_free will call ply_terminal_close anyway and is guarded +against NULL terminal (ply_terminal_close is not). +--- + src/libply-splash-core/ply-device-manager.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c +index 8f5360c..17607f4 100644 +--- a/src/libply-splash-core/ply-device-manager.c ++++ b/src/libply-splash-core/ply-device-manager.c +@@ -415,61 +415,60 @@ 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 || + strcmp (full_name, ply_terminal_get_name (manager->local_console_terminal)) == 0) + { + terminal = manager->local_console_terminal; + +-- +2.3.7 + + +From e7048fdd1a40ed683fc706a40816cc490a693ba9 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 7 Jan 2015 16:24:57 -0500 +Subject: [PATCH 4/5] device-manager: try fb device if drm device failed + +If the drm device failed to work, then fall back to the fb device. + +Right now, we ignore fb devices that have associated drm devices. + +This may fix vmwgfx. +--- + src/libply-splash-core/ply-device-manager.c | 39 ++++++++++++++++++++++++++++- + 1 file changed, 38 insertions(+), 1 deletion(-) + +diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c +index 17607f4..cc153e2 100644 +--- a/src/libply-splash-core/ply-device-manager.c ++++ b/src/libply-splash-core/ply-device-manager.c +@@ -88,95 +88,132 @@ attach_to_event_loop (ply_device_manager_t *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 bool ++drm_device_in_use (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) ++ { ++ return true; ++ } ++ } ++ } ++ ++ node = next_node; ++ } ++ ++ return false; ++} ++ ++static bool + fb_device_has_drm_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; + bool has_drm_device = false; + + /* 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); + + ply_trace ("trying to find associated drm node for fb device (path: %s)", 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) ++ if (card_node != NULL && drm_device_in_use (manager, card_node)) + has_drm_device = true; + else + ply_trace ("no card node!"); + + udev_device_unref (card_device); + } + else + { + ply_trace ("no card entry!"); + } + + udev_enumerate_unref (card_matches); + return has_drm_device; + } + + static void + create_seat_for_udev_device (ply_device_manager_t *manager, + struct udev_device *device) + { + bool for_local_console; + const char *device_path; + ply_terminal_t *terminal = NULL; + + for_local_console = device_is_for_local_console (manager, device); + + ply_trace ("device is for local console: %s", for_local_console? "yes" : "no"); + + if (for_local_console) + terminal = manager->local_console_terminal; + +-- +2.3.7 + + +From b9989b912fb394c00d3d4740eb72a25f80a8bc71 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 3 Jul 2015 10:38:47 -0400 +Subject: [PATCH 5/5] device-manager: don't try to load graphical splash after + using text splash + +We only support loading one splash at a time at the moment, so this +commit makes sure we don't load a graphical splash after already loading +a text splash +--- + src/libply-splash-core/ply-device-manager.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c +index cc153e2..a7890d0 100644 +--- a/src/libply-splash-core/ply-device-manager.c ++++ b/src/libply-splash-core/ply-device-manager.c +@@ -379,61 +379,69 @@ create_seats_for_subsystem (ply_device_manager_t *manager, + return found_device; + } + + static void + on_udev_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); + + ply_trace ("got %s event for device %s", action, udev_device_get_sysname (device)); + + if (action == NULL) + return; + + if (strcmp (action, "add") == 0) + { + const char *subsystem; + bool coldplug_complete = manager->udev_queue_fd_watch == NULL; + + subsystem = udev_device_get_subsystem (device); + + if (strcmp (subsystem, SUBSYSTEM_DRM) == 0 || + coldplug_complete) + { +- create_seat_for_udev_device (manager, device); ++ ply_list_t *local_pixel_displays = NULL; ++ ++ if (manager->local_console_seat != NULL) ++ local_pixel_displays = ply_seat_get_pixel_displays (manager->local_console_seat); ++ ++ if (coldplug_complete && manager->local_console_seat != NULL && local_pixel_displays == NULL) ++ ply_trace ("ignoring since we're already using text splash for local console"); ++ else ++ create_seat_for_udev_device (manager, device); + } + else + { + ply_trace ("ignoring since we only handle subsystem %s devices after coldplug completes", subsystem); + } + } + 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"); + + udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, SUBSYSTEM_DRM, NULL); + udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, SUBSYSTEM_FRAME_BUFFER, NULL); + udev_monitor_filter_add_match_tag (manager->udev_monitor, "seat"); + udev_monitor_enable_receiving (manager->udev_monitor); + +-- +2.3.7 + diff --git a/SOURCES/dont-block-show-splash.patch b/SOURCES/dont-block-show-splash.patch new file mode 100644 index 0000000..8f34363 --- /dev/null +++ b/SOURCES/dont-block-show-splash.patch @@ -0,0 +1,575 @@ +From a54df38f86a534b28c1b664bc283e9b8d17be8a1 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 16 Jan 2014 15:44:50 -0500 +Subject: [PATCH 1/2] main: don't rely on show_trigger to cancel show delay + +We're going to be getting rid of show_trigger in a subsequent +commit, so this commit changes the code to use the is_shown +flag instead. +--- + src/main.c | 29 ++++++++++++++++------------- + 1 file changed, 16 insertions(+), 13 deletions(-) + +diff --git a/src/main.c b/src/main.c +index bbd74f9..d9032a5 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -482,74 +482,77 @@ show_default_splash (state_t *state) + + static void + cancel_pending_delayed_show (state_t *state) + { + bool has_open_seats; + + if (isnan (state->splash_delay)) + return; + + ply_event_loop_stop_watching_for_timeout (state->loop, + (ply_event_loop_timeout_handler_t) + show_splash, + state); + state->splash_delay = NAN; + has_open_seats = ply_device_manager_has_open_seats (state->device_manager); + + if (state->is_shown && has_open_seats) + { + ply_trace ("splash delay cancelled, showing splash immediately"); + show_splash (state); + } + } + + static void + on_ask_for_password (state_t *state, + const char *prompt, + ply_trigger_t *answer) + { + ply_entry_trigger_t *entry_trigger; + +- /* Waiting to be shown, boot splash will +- * arrive shortly so just sit tight +- */ +- if (state->show_trigger != NULL) +- { +- ply_trace ("splash still coming up, waiting a bit"); +- cancel_pending_delayed_show (state); +- } +- else if (state->boot_splash == NULL) ++ if (state->boot_splash == NULL) + { +- /* No splash, client will have to get password */ +- ply_trace ("no splash loaded, replying immediately with no password"); +- ply_trigger_pull (answer, NULL); +- return; ++ /* Waiting to be shown, boot splash will ++ * arrive shortly so just sit tight ++ */ ++ if (state->is_shown) ++ { ++ ply_trace ("splash still coming up, waiting a bit"); ++ cancel_pending_delayed_show (state); ++ } ++ else ++ { ++ /* No splash, client will have to get password */ ++ ply_trace ("no splash loaded, replying immediately with no password"); ++ ply_trigger_pull (answer, NULL); ++ return; ++ } + } + + entry_trigger = calloc (1, sizeof (ply_entry_trigger_t)); + entry_trigger->type = PLY_ENTRY_TRIGGER_TYPE_PASSWORD; + entry_trigger->prompt = prompt; + entry_trigger->trigger = answer; + ply_trace ("queuing password request with boot splash"); + ply_list_append_data (state->entry_triggers, entry_trigger); + update_display (state); + } + + static void + on_ask_question (state_t *state, + const char *prompt, + ply_trigger_t *answer) + { + ply_entry_trigger_t *entry_trigger; + + entry_trigger = calloc (1, sizeof (ply_entry_trigger_t)); + entry_trigger->type = PLY_ENTRY_TRIGGER_TYPE_QUESTION; + entry_trigger->prompt = prompt; + entry_trigger->trigger = answer; + ply_trace ("queuing question with boot splash"); + ply_list_append_data (state->entry_triggers, entry_trigger); + update_display (state); + } + + static void + on_display_message (state_t *state, + const char *message) +-- +1.8.3.1 + + +From cdff09d1a2297501f294141182d8d8efcaf6fff3 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 16 Jan 2014 15:38:05 -0500 +Subject: [PATCH 2/2] Revert "boot-server: defer show-splash reply until splash + shown" + +This reverts commit 126345af8704a9b10481657d79d66cbea93e1647. + +If plymouth show-splash blocks until the splash screen is shown, +then systemd-ask-for-password-plymouth will block for 5 seconds +before asking for the password (which would have canceled the 5 +second delay if it weren't for the dependency on plymouth-start.service) +--- + src/main.c | 12 +----------- + src/ply-boot-server.c | 28 +--------------------------- + src/ply-boot-server.h | 1 - + 3 files changed, 2 insertions(+), 39 deletions(-) + +diff --git a/src/main.c b/src/main.c +index d9032a5..db1fd0a 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -74,61 +74,60 @@ typedef struct + const char *keys; + ply_trigger_t *trigger; + } ply_keystroke_watch_t; + + typedef struct + { + enum {PLY_ENTRY_TRIGGER_TYPE_PASSWORD, + PLY_ENTRY_TRIGGER_TYPE_QUESTION} + type; + const char *prompt; + ply_trigger_t *trigger; + } ply_entry_trigger_t; + + typedef struct + { + ply_event_loop_t *loop; + ply_boot_server_t *boot_server; + ply_boot_splash_t *boot_splash; + ply_terminal_session_t *session; + ply_buffer_t *boot_buffer; + ply_progress_t *progress; + ply_list_t *keystroke_triggers; + ply_list_t *entry_triggers; + ply_buffer_t *entry_buffer; + ply_list_t *messages; + ply_command_parser_t *command_parser; + ply_mode_t mode; + ply_terminal_t *local_console_terminal; + ply_device_manager_t *device_manager; + +- ply_trigger_t *show_trigger; + ply_trigger_t *deactivate_trigger; + ply_trigger_t *quit_trigger; + + double start_time; + double splash_delay; + + char kernel_command_line[PLY_MAX_COMMAND_LINE_SIZE]; + uint32_t kernel_command_line_is_set : 1; + uint32_t no_boot_log : 1; + uint32_t showing_details : 1; + uint32_t system_initialized : 1; + uint32_t is_redirected : 1; + uint32_t is_attached : 1; + uint32_t should_be_attached : 1; + uint32_t should_retain_splash : 1; + uint32_t is_inactive : 1; + uint32_t is_shown : 1; + uint32_t should_force_details : 1; + + char *override_splash_path; + char *system_default_splash_path; + char *distribution_default_splash_path; + const char *default_tty; + + int number_of_errors; + } state_t; + + static void show_splash (state_t *state); + static ply_boot_splash_t *load_built_in_theme (state_t *state); + static ply_boot_splash_t *load_theme (state_t *state, +@@ -848,85 +847,83 @@ plymouth_should_show_default_splash (state_t *state) + + if (command_line_has_argument (state->kernel_command_line, "splash=verbose")) + { + ply_trace ("no default splash because kernel command line has option \"splash=verbose\""); + return false; + } + + if (command_line_has_argument (state->kernel_command_line, "rhgb")) + { + ply_trace ("using default splash because kernel command line has option \"rhgb\""); + return true; + } + + if (command_line_has_argument (state->kernel_command_line, "splash")) + { + ply_trace ("using default splash because kernel command line has option \"splash\""); + return true; + } + + if (command_line_has_argument (state->kernel_command_line, "splash=silent")) + { + ply_trace ("using default splash because kernel command line has option \"splash=slient\""); + return true; + } + + ply_trace ("no default splash because kernel command line lacks \"splash\" or \"rhgb\""); + return false; + } + + static void +-on_show_splash (state_t *state, +- ply_trigger_t *show_trigger) ++on_show_splash (state_t *state) + { + bool has_open_seats; + + if (state->is_shown) + { + ply_trace ("show splash called while already shown"); + return; + } + + if (state->is_inactive) + { + ply_trace ("show splash called while inactive"); + return; + } + + if (plymouth_should_ignore_show_splash_calls (state)) + { + ply_trace ("show splash called while ignoring show splash calls"); + dump_details_and_quit_splash (state); + return; + } + +- state->show_trigger = show_trigger; + state->is_shown = true; + has_open_seats = ply_device_manager_has_open_seats (state->device_manager); + + if (!state->is_attached && state->should_be_attached && has_open_seats) + attach_to_running_session (state); + + if (has_open_seats) + { + ply_trace ("at least one seat already open, so loading splash"); + show_splash (state); + } + else + { + ply_trace ("no seats available to show splash on, waiting..."); + } + } + + static void + on_seat_removed (state_t *state, + ply_seat_t *seat) + { + ply_keyboard_t *keyboard; + + keyboard = ply_seat_get_keyboard (seat); + + ply_trace ("no longer listening for keystrokes"); + ply_keyboard_remove_input_handler (keyboard, + (ply_keyboard_input_handler_t) + on_keyboard_input); + ply_trace ("no longer listening for escape"); +@@ -960,67 +957,60 @@ show_splash (state_t *state) + running_time = now - state->start_time; + if (state->splash_delay > running_time) + { + double time_left = state->splash_delay - running_time; + + ply_trace ("delaying show splash for %lf seconds", + time_left); + ply_event_loop_stop_watching_for_timeout (state->loop, + (ply_event_loop_timeout_handler_t) + show_splash, + state); + ply_event_loop_watch_for_timeout (state->loop, + time_left, + (ply_event_loop_timeout_handler_t) + show_splash, + state); + return; + } + } + + if (plymouth_should_show_default_splash (state)) + { + show_default_splash (state); + state->showing_details = false; + } + else + { + show_detailed_splash (state); + state->showing_details = true; + } +- +- if (state->show_trigger != NULL) +- { +- ply_trace ("telling boot server about completed show operation"); +- ply_trigger_pull (state->show_trigger, NULL); +- state->show_trigger = NULL; +- } + } + + static void + on_seat_added (state_t *state, + ply_seat_t *seat) + { + ply_keyboard_t *keyboard; + + if (state->is_shown) + { + if (state->boot_splash == NULL) + { + ply_trace ("seat added before splash loaded, so loading splash now"); + show_splash (state); + } + else + { + ply_trace ("seat added after splash loaded, so attaching to splash"); + ply_boot_splash_attach_to_seat (state->boot_splash, seat); + } + } + + keyboard = ply_seat_get_keyboard (seat); + + ply_trace ("listening for keystrokes"); + ply_keyboard_add_input_handler (keyboard, + (ply_keyboard_input_handler_t) + on_keyboard_input, state); + ply_trace ("listening for escape"); + ply_keyboard_add_escape_handler (keyboard, +diff --git a/src/ply-boot-server.c b/src/ply-boot-server.c +index 78c9c52..3e67bfb 100644 +--- a/src/ply-boot-server.c ++++ b/src/ply-boot-server.c +@@ -283,72 +283,60 @@ ply_boot_connection_send_answer (ply_boot_connection_t *connection, + { + size = strlen (answer); + + if (!ply_write (connection->fd, + PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER, + strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER)) || + !ply_write_uint32 (connection->fd, + size) || + !ply_write (connection->fd, + answer, size)) + ply_trace ("could not finish writing answer: %m"); + + } + + } + + static void + ply_boot_connection_on_password_answer (ply_boot_connection_t *connection, + const char *password) + { + ply_trace ("got password answer"); + + ply_boot_connection_send_answer (connection, password); + if (password != NULL) + ply_list_append_data (connection->server->cached_passwords, + strdup (password)); + + } + + static void +-ply_boot_connection_on_splash_shown (ply_boot_connection_t *connection) +-{ +- ply_trace ("shown"); +- if (!ply_write (connection->fd, +- PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK, +- strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK))) +- { +- ply_trace ("could not finish writing deactivate reply: %m"); +- } +-} +- +-static void + ply_boot_connection_on_deactivated (ply_boot_connection_t *connection) + { + ply_trace ("deactivated"); + if (!ply_write (connection->fd, + PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK, + strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK))) + { + ply_trace ("could not finish writing deactivate reply: %m"); + } + } + + static void + ply_boot_connection_on_quit_complete (ply_boot_connection_t *connection) + { + ply_trace ("quit complete"); + if (!ply_write (connection->fd, + PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK, + strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK))) + { + ply_trace ("could not finish writing quit reply: %m"); + } + } + + static void + ply_boot_connection_on_question_answer (ply_boot_connection_t *connection, + const char *answer) + { + ply_trace ("got question answer: %s", answer); + ply_boot_connection_send_answer (connection, answer); + } +@@ -462,77 +450,63 @@ ply_boot_connection_on_request (ply_boot_connection_t *connection) + ply_error ("failed to parse percentage %s", argument); + value = 0; + } + + ply_trace ("got system-update notification %li%%", value); + if (!ply_write (connection->fd, + PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK, + strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK))) + ply_trace ("could not finish writing update reply: %m"); + + if (server->system_update_handler != NULL) + server->system_update_handler (server->user_data, value, server); + free (argument); + free (command); + return; + } + else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_SYSTEM_INITIALIZED) == 0) + { + ply_trace ("got system initialized notification"); + if (server->system_initialized_handler != NULL) + server->system_initialized_handler (server->user_data, server); + } + else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_ERROR) == 0) + { + ply_trace ("got error notification"); + if (server->error_handler != NULL) + server->error_handler (server->user_data, server); + } + else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_SHOW_SPLASH) == 0) + { +- ply_trigger_t *show_trigger; +- + ply_trace ("got show splash request"); +- +- show_trigger = ply_trigger_new (NULL); +- +- ply_trigger_add_handler (show_trigger, +- (ply_trigger_handler_t) +- ply_boot_connection_on_splash_shown, +- connection); +- + if (server->show_splash_handler != NULL) +- server->show_splash_handler (server->user_data, show_trigger, server); +- +- free (argument); +- free (command); +- return; ++ server->show_splash_handler (server->user_data, server); + } + else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_HIDE_SPLASH) == 0) + { + ply_trace ("got hide splash request"); + if (server->hide_splash_handler != NULL) + server->hide_splash_handler (server->user_data, server); + } + else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_DEACTIVATE) == 0) + { + ply_trigger_t *deactivate_trigger; + + ply_trace ("got deactivate request"); + + deactivate_trigger = ply_trigger_new (NULL); + + ply_trigger_add_handler (deactivate_trigger, + (ply_trigger_handler_t) + ply_boot_connection_on_deactivated, + connection); + + if (server->deactivate_handler != NULL) + server->deactivate_handler (server->user_data, deactivate_trigger, server); + + free (argument); + free (command); + return; + } + else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_REACTIVATE) == 0) + { + ply_trace ("got reactivate request"); +diff --git a/src/ply-boot-server.h b/src/ply-boot-server.h +index 4436be8..b885a81 100644 +--- a/src/ply-boot-server.h ++++ b/src/ply-boot-server.h +@@ -22,61 +22,60 @@ + #ifndef PLY_BOOT_SERVER_H + #define PLY_BOOT_SERVER_H + + #include + #include + #include + + #include "ply-trigger.h" + #include "ply-boot-protocol.h" + #include "ply-event-loop.h" + + typedef struct _ply_boot_server ply_boot_server_t; + + typedef void (* ply_boot_server_update_handler_t) (void *user_data, + const char *status, + ply_boot_server_t *server); + + typedef void (* ply_boot_server_change_mode_handler_t) (void *user_data, + const char *mode, + ply_boot_server_t *server); + + typedef void (* ply_boot_server_system_update_handler_t) (void *user_data, + int progress, + ply_boot_server_t *server); + + typedef void (* ply_boot_server_newroot_handler_t) (void *user_data, + const char *root_dir, + ply_boot_server_t *server); + + typedef void (* ply_boot_server_show_splash_handler_t) (void *user_data, +- ply_trigger_t *show_trigger, + ply_boot_server_t *server); + + typedef void (* ply_boot_server_hide_splash_handler_t) (void *user_data, + ply_boot_server_t *server); + + typedef void (* ply_boot_server_password_answer_handler_t) (void *answer_data, + const char *password, + ply_boot_server_t *server); + typedef void (* ply_boot_server_ask_for_password_handler_t) (void *user_data, + const char *prompt, + ply_trigger_t *answer, + ply_boot_server_t *server); + typedef void (* ply_boot_server_question_answer_handler_t) (void *answer_data, + const char *answer, + ply_boot_server_t *server); + typedef void (* ply_boot_server_ask_question_handler_t) (void *user_data, + const char *prompt, + ply_trigger_t *answer, + ply_boot_server_t *server); + typedef void (* ply_boot_server_display_message_handler_t) (void *user_data, + const char *message, + ply_boot_server_t *server); + typedef void (* ply_boot_server_hide_message_handler_t) (void *user_data, + const char *message, + ply_boot_server_t *server); + typedef void (* ply_boot_server_watch_for_keystroke_handler_t) (void *user_data, + const char *keys, + ply_trigger_t *answer, + ply_boot_server_t *server); + typedef void (* ply_boot_server_ignore_keystroke_handler_t) (void *user_data, +-- +1.8.3.1 + diff --git a/SOURCES/ensure-output-gets-terminal.patch b/SOURCES/ensure-output-gets-terminal.patch new file mode 100644 index 0000000..87e4301 --- /dev/null +++ b/SOURCES/ensure-output-gets-terminal.patch @@ -0,0 +1,5207 @@ +From 6283d0a786d7fec368d33dfeb25c0342cc5168ec Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 22 Jul 2015 10:05:51 -0400 +Subject: [PATCH 1/8] renderer: track activeness + +Right now, ply-seat has to handle tracking +renderer activeness on its own. This commit +moves activeness tracking to ply-renderer +directly. +--- + src/libply-splash-core/ply-renderer.c | 30 ++++++++++++++++++++++++++---- + src/libply-splash-core/ply-renderer.h | 1 + + src/libply-splash-core/ply-seat.c | 15 --------------- + 3 files changed, 27 insertions(+), 19 deletions(-) + +diff --git a/src/libply-splash-core/ply-renderer.c b/src/libply-splash-core/ply-renderer.c +index 04a99ce..3d9aa43 100644 +--- a/src/libply-splash-core/ply-renderer.c ++++ b/src/libply-splash-core/ply-renderer.c +@@ -28,60 +28,61 @@ + #include + #include + #include + #include + #include + #include + #include + #include + + #include "ply-renderer-plugin.h" + #include "ply-buffer.h" + #include "ply-terminal.h" + #include "ply-event-loop.h" + #include "ply-list.h" + #include "ply-logger.h" + #include "ply-utils.h" + + struct _ply_renderer + { + ply_event_loop_t *loop; + ply_module_handle_t *module_handle; + const ply_renderer_plugin_interface_t *plugin_interface; + ply_renderer_backend_t *backend; + + ply_renderer_type_t type; + char *device_name; + ply_terminal_t *terminal; + + uint32_t input_source_is_open : 1; + uint32_t is_mapped : 1; ++ uint32_t is_active : 1; + }; + + typedef const ply_renderer_plugin_interface_t * + (* get_backend_interface_function_t) (void); + + static void ply_renderer_unload_plugin (ply_renderer_t *renderer); + + ply_renderer_t * + 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)); + + renderer->type = renderer_type; + + if (device_name != NULL) + renderer->device_name = strdup (device_name); + + renderer->terminal = terminal; + + return renderer; + } + + void + ply_renderer_free (ply_renderer_t *renderer) + { + if (renderer == NULL) +@@ -247,95 +248,116 @@ ply_renderer_open_plugin (ply_renderer_t *renderer, + if (!ply_renderer_query_device (renderer)) + { + ply_trace ("could not query rendering device for plugin %s", + plugin_path); + ply_renderer_close_device (renderer); + ply_renderer_unload_plugin (renderer); + return false; + } + + ply_trace ("opened renderer plugin %s", plugin_path); + return true; + } + + bool + ply_renderer_open (ply_renderer_t *renderer) + { + int i; + + struct + { + 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 } + }; + ++ renderer->is_active = false; + for (i = 0; known_plugins[i].type != PLY_RENDERER_TYPE_NONE; i++) + { + 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; ++ { ++ renderer->is_active = true; ++ goto out; ++ } + } + } + + ply_trace ("could not find suitable rendering plugin"); +- return false; ++ ++out: ++ return renderer->is_active; + } + + void + ply_renderer_close (ply_renderer_t *renderer) + { + ply_renderer_unmap_from_device (renderer); + ply_renderer_close_device (renderer); ++ renderer->is_active = false; + } + + void + ply_renderer_activate (ply_renderer_t *renderer) + { + assert (renderer->plugin_interface != NULL); + +- return renderer->plugin_interface->activate (renderer->backend); ++ if (renderer->is_active) ++ return; ++ ++ renderer->plugin_interface->activate (renderer->backend); ++ renderer->is_active = true; + } + + void + ply_renderer_deactivate (ply_renderer_t *renderer) + { + assert (renderer->plugin_interface != NULL); + +- return renderer->plugin_interface->deactivate (renderer->backend); ++ if (!renderer->is_active) ++ return; ++ ++ renderer->plugin_interface->deactivate (renderer->backend); ++ renderer->is_active = false; ++} ++ ++bool ++ply_renderer_is_active (ply_renderer_t *renderer) ++{ ++ return renderer->is_active; + } + + ply_list_t * + ply_renderer_get_heads (ply_renderer_t *renderer) + { + assert (renderer->plugin_interface != NULL); + + return renderer->plugin_interface->get_heads (renderer->backend); + } + + ply_pixel_buffer_t * + ply_renderer_get_buffer_for_head (ply_renderer_t *renderer, + ply_renderer_head_t *head) + { + assert (renderer != NULL); + assert (renderer->plugin_interface != NULL); + assert (head != NULL); + + return renderer->plugin_interface->get_buffer_for_head (renderer->backend, + head); + } + + void + ply_renderer_flush_head (ply_renderer_t *renderer, + ply_renderer_head_t *head) + { + assert (renderer != NULL); + assert (renderer->plugin_interface != NULL); + assert (head != NULL); + +diff --git a/src/libply-splash-core/ply-renderer.h b/src/libply-splash-core/ply-renderer.h +index 3d48341..a47174a 100644 +--- a/src/libply-splash-core/ply-renderer.h ++++ b/src/libply-splash-core/ply-renderer.h +@@ -30,52 +30,53 @@ + #include "ply-pixel-buffer.h" + #include "ply-terminal.h" + #include "ply-utils.h" + + 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 (ply_renderer_type_t renderer_type, + const char *device_name, + ply_terminal_t *terminal); + void ply_renderer_free (ply_renderer_t *renderer); + 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); ++bool ply_renderer_is_active (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); + + void ply_renderer_flush_head (ply_renderer_t *renderer, + ply_renderer_head_t *head); + + ply_renderer_input_source_t *ply_renderer_get_input_source (ply_renderer_t *renderer); + bool ply_renderer_open_input_source (ply_renderer_t *renderer, + ply_renderer_input_source_t *input_source); + void ply_renderer_set_handler_for_input_source (ply_renderer_t *renderer, + ply_renderer_input_source_t *input_source, + ply_renderer_input_source_handler_t handler, + void *user_data); + + void ply_renderer_close_input_source (ply_renderer_t *renderer, + ply_renderer_input_source_t *input_source); + #endif + + #endif /* PLY_RENDERER_H */ + /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ +diff --git a/src/libply-splash-core/ply-seat.c b/src/libply-splash-core/ply-seat.c +index cd7e5bc..4635889 100644 +--- a/src/libply-splash-core/ply-seat.c ++++ b/src/libply-splash-core/ply-seat.c +@@ -22,61 +22,60 @@ + #include "config.h" + #include "ply-seat.h" + + #include + #include + #include + #include + #include + #include + + #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); +@@ -108,70 +107,66 @@ add_text_displays (ply_seat_t *seat) + { + ply_trace ("could not add terminal %s: %m", + ply_terminal_get_name (seat->terminal)); + return; + } + } + + ply_trace ("adding text display for terminal %s", + ply_terminal_get_name (seat->terminal)); + + 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)) + { + ply_trace ("could not open renderer for %s", device); + ply_renderer_free (renderer); + +- seat->renderer = NULL; +- seat->renderer_active = false; +- + if (renderer_type != PLY_RENDERER_TYPE_AUTO) + return false; + } + else + { + 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 if (seat->terminal != NULL) + { + seat->keyboard = ply_keyboard_new_for_terminal (seat->terminal); + } + + if (seat->terminal != NULL) + { + add_text_displays (seat); + } + else + { + ply_trace ("not adding text display for seat, since seat has no associated terminal"); + } + + if (seat->keyboard != NULL) + { + ply_keyboard_watch_for_input (seat->keyboard); + seat->keyboard_active = true; + } + else + { +@@ -179,100 +174,90 @@ ply_seat_open (ply_seat_t *seat, + } + + 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; +-- +2.3.7 + + +From fb294aa5fc8ea8236ce91617a229daad9251a2f8 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 22 Jul 2015 10:05:51 -0400 +Subject: [PATCH 2/8] keyboard: track activeness + +Right now, ply-seat has to handle tracking +keyboard activeness on its own. This commit +moves activeness tracking to ply-keyboard +directly. +--- + src/libply-splash-core/ply-keyboard.c | 23 ++++++++++++++++++++--- + src/libply-splash-core/ply-keyboard.h | 1 + + src/libply-splash-core/ply-seat.c | 13 ------------- + 3 files changed, 21 insertions(+), 16 deletions(-) + +diff --git a/src/libply-splash-core/ply-keyboard.c b/src/libply-splash-core/ply-keyboard.c +index 624f906..e2fd814 100644 +--- a/src/libply-splash-core/ply-keyboard.c ++++ b/src/libply-splash-core/ply-keyboard.c +@@ -65,60 +65,62 @@ typedef enum + typedef struct + { + ply_terminal_t *terminal; + ply_buffer_t *key_buffer; + } ply_keyboard_terminal_provider_t; + + typedef struct + { + ply_renderer_t *renderer; + ply_renderer_input_source_t *input_source; + } ply_keyboard_renderer_provider_t; + + typedef union { + ply_keyboard_renderer_provider_t *if_renderer; + ply_keyboard_terminal_provider_t *if_terminal; + } ply_keyboard_provider_t; + + struct _ply_keyboard + { + ply_event_loop_t *loop; + + ply_keyboard_provider_type_t provider_type; + ply_keyboard_provider_t provider; + + ply_buffer_t *line_buffer; + + ply_list_t *keyboard_input_handler_list; + ply_list_t *backspace_handler_list; + ply_list_t *escape_handler_list; + ply_list_t *enter_handler_list; ++ ++ uint32_t is_active : 1; + }; + + static bool ply_keyboard_watch_for_terminal_input (ply_keyboard_t *keyboard); + + ply_keyboard_t * + ply_keyboard_new_for_terminal (ply_terminal_t *terminal) + { + ply_keyboard_t *keyboard; + + keyboard = calloc (1, sizeof (ply_keyboard_t)); + keyboard->line_buffer = ply_buffer_new (); + keyboard->keyboard_input_handler_list = ply_list_new (); + keyboard->backspace_handler_list = ply_list_new (); + keyboard->escape_handler_list = ply_list_new (); + keyboard->enter_handler_list = ply_list_new (); + keyboard->provider_type = PLY_KEYBOARD_PROVIDER_TYPE_TERMINAL; + keyboard->provider.if_terminal = calloc (1, sizeof (ply_keyboard_terminal_provider_t)); + keyboard->provider.if_terminal->terminal = terminal; + keyboard->provider.if_terminal->key_buffer = ply_buffer_new (); + + keyboard->loop = ply_event_loop_get_default (); + + return keyboard; + } + + ply_keyboard_t * + ply_keyboard_new_for_renderer (ply_renderer_t *renderer) + { + ply_keyboard_t *keyboard; + ply_renderer_input_source_t *input_source; +@@ -303,135 +305,150 @@ on_key_event (ply_keyboard_t *keyboard, + + static bool + ply_keyboard_watch_for_renderer_input (ply_keyboard_t *keyboard) + { + assert (keyboard != NULL); + + if (!ply_renderer_open_input_source (keyboard->provider.if_renderer->renderer, + keyboard->provider.if_renderer->input_source)) + return false; + + ply_renderer_set_handler_for_input_source (keyboard->provider.if_renderer->renderer, + keyboard->provider.if_renderer->input_source, + (ply_renderer_input_source_handler_t) + on_key_event, + keyboard); + return true; + } + + static void + ply_keyboard_stop_watching_for_renderer_input (ply_keyboard_t *keyboard) + { + ply_renderer_set_handler_for_input_source (keyboard->provider.if_renderer->renderer, + keyboard->provider.if_renderer->input_source, + (ply_renderer_input_source_handler_t) + NULL, NULL); + + ply_renderer_close_input_source (keyboard->provider.if_renderer->renderer, + keyboard->provider.if_renderer->input_source); + } + ++bool ++ply_keyboard_is_active (ply_keyboard_t *keyboard) ++{ ++ return keyboard->is_active; ++} ++ + static void + on_terminal_data (ply_keyboard_t *keyboard) + { + int terminal_fd; + + terminal_fd = ply_terminal_get_fd (keyboard->provider.if_terminal->terminal); + ply_buffer_append_from_fd (keyboard->provider.if_terminal->key_buffer, + terminal_fd); + on_key_event (keyboard, keyboard->provider.if_terminal->key_buffer); + } + + static bool + ply_keyboard_watch_for_terminal_input (ply_keyboard_t *keyboard) + { + int terminal_fd; + + assert (keyboard != NULL); + + terminal_fd = ply_terminal_get_fd (keyboard->provider.if_terminal->terminal); + + if (terminal_fd < 0 || !ply_terminal_is_open (keyboard->provider.if_terminal->terminal)) + { + ply_trace ("terminal associated with keyboard isn't open"); + return false; + } + + ply_terminal_watch_for_input (keyboard->provider.if_terminal->terminal, + (ply_terminal_input_handler_t) on_terminal_data, + keyboard); + + return true; + } + + static void + ply_keyboard_stop_watching_for_terminal_input (ply_keyboard_t *keyboard) + { + ply_terminal_stop_watching_for_input (keyboard->provider.if_terminal->terminal, + (ply_terminal_input_handler_t) + on_terminal_data, + keyboard); + } + + bool + ply_keyboard_watch_for_input (ply_keyboard_t *keyboard) + { + assert (keyboard != NULL); + ++ if (keyboard->is_active) ++ return true; ++ + switch (keyboard->provider_type) + { + case PLY_KEYBOARD_PROVIDER_TYPE_RENDERER: +- return ply_keyboard_watch_for_renderer_input (keyboard); ++ keyboard->is_active = ply_keyboard_watch_for_renderer_input (keyboard); ++ break; + + case PLY_KEYBOARD_PROVIDER_TYPE_TERMINAL: +- return ply_keyboard_watch_for_terminal_input (keyboard); ++ keyboard->is_active = ply_keyboard_watch_for_terminal_input (keyboard); ++ break; + } + +- return false; ++ return keyboard->is_active; + } + + void + ply_keyboard_stop_watching_for_input (ply_keyboard_t *keyboard) + { + assert (keyboard != NULL); + ++ if (!keyboard->is_active) ++ return; ++ + switch (keyboard->provider_type) + { + case PLY_KEYBOARD_PROVIDER_TYPE_RENDERER: + ply_keyboard_stop_watching_for_renderer_input (keyboard); + break; + + case PLY_KEYBOARD_PROVIDER_TYPE_TERMINAL: + ply_keyboard_stop_watching_for_terminal_input (keyboard); + break; + } + ++ keyboard->is_active = false; + } + + void + ply_keyboard_free (ply_keyboard_t *keyboard) + { + if (keyboard == NULL) + return; + + ply_keyboard_stop_watching_for_input (keyboard); + + ply_buffer_free (keyboard->line_buffer); + + if (keyboard->provider_type == PLY_KEYBOARD_PROVIDER_TYPE_RENDERER) + { + free (keyboard->provider.if_renderer); + } + else + { + ply_buffer_free (keyboard->provider.if_terminal->key_buffer); + free (keyboard->provider.if_terminal); + } + + free (keyboard); + } + + static ply_keyboard_closure_t * + ply_keyboard_closure_new (ply_keyboard_handler_t function, + void *user_data) + { + ply_keyboard_closure_t *closure = calloc (1, sizeof (ply_keyboard_closure_t)); +diff --git a/src/libply-splash-core/ply-keyboard.h b/src/libply-splash-core/ply-keyboard.h +index 74683cf..19e3d85 100644 +--- a/src/libply-splash-core/ply-keyboard.h ++++ b/src/libply-splash-core/ply-keyboard.h +@@ -44,35 +44,36 @@ typedef void (* ply_keyboard_enter_handler_t) (void *user_data, + const char *line); + + #ifndef PLY_HIDE_FUNCTION_DECLARATIONS + ply_keyboard_t *ply_keyboard_new_for_terminal (ply_terminal_t *terminal); + ply_keyboard_t *ply_keyboard_new_for_renderer (ply_renderer_t *renderer); + void ply_keyboard_free (ply_keyboard_t *keyboard); + + void ply_keyboard_add_input_handler (ply_keyboard_t *keyboard, + ply_keyboard_input_handler_t input_handler, + void *user_data); + void ply_keyboard_remove_input_handler (ply_keyboard_t *keyboard, + ply_keyboard_input_handler_t input_handler); + void ply_keyboard_add_backspace_handler (ply_keyboard_t *keyboard, + ply_keyboard_backspace_handler_t backspace_handler, + void *user_data); + void ply_keyboard_remove_backspace_handler (ply_keyboard_t *keyboard, + ply_keyboard_backspace_handler_t backspace_handler); + void ply_keyboard_add_escape_handler (ply_keyboard_t *keyboard, + ply_keyboard_escape_handler_t escape_handler, + void *user_data); + void ply_keyboard_remove_escape_handler (ply_keyboard_t *keyboard, + ply_keyboard_escape_handler_t escape_handler); + void ply_keyboard_add_enter_handler (ply_keyboard_t *keyboard, + ply_keyboard_enter_handler_t enter_handler, + void *user_data); + void ply_keyboard_remove_enter_handler (ply_keyboard_t *keyboard, + ply_keyboard_enter_handler_t enter_handler); + + bool ply_keyboard_watch_for_input (ply_keyboard_t *keyboard); + void ply_keyboard_stop_watching_for_input (ply_keyboard_t *keyboard); ++bool ply_keyboard_is_active (ply_keyboard_t *keyboard); + + #endif + + #endif /* PLY_KEYBOARD_H */ + /* vim: set ts=4 sw=4 et ai ci cino={.5s,^-2,+.5s,t0,g0,e-2,n-2,p2s,(0,=.5s,:.5s */ +diff --git a/src/libply-splash-core/ply-seat.c b/src/libply-splash-core/ply-seat.c +index 4635889..1c885c2 100644 +--- a/src/libply-splash-core/ply-seat.c ++++ b/src/libply-splash-core/ply-seat.c +@@ -21,62 +21,60 @@ + */ + #include "config.h" + #include "ply-seat.h" + + #include + #include + #include + #include + #include + #include + + #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 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) +@@ -139,115 +137,104 @@ ply_seat_open (ply_seat_t *seat, + } + else + { + seat->renderer = renderer; + } + } + + if (seat->renderer != NULL) + { + seat->keyboard = ply_keyboard_new_for_renderer (seat->renderer); + add_pixel_displays (seat); + + } + else if (seat->terminal != NULL) + { + seat->keyboard = ply_keyboard_new_for_terminal (seat->terminal); + } + + if (seat->terminal != NULL) + { + add_text_displays (seat); + } + else + { + ply_trace ("not adding text display for seat, since seat has no associated terminal"); + } + + if (seat->keyboard != NULL) + { + ply_keyboard_watch_for_input (seat->keyboard); +- seat->keyboard_active = true; + } + else + { + ply_trace ("not watching seat for input"); + } + + 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 == 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 == NULL) + return; + + ply_trace ("activating renderer"); + ply_renderer_activate (seat->renderer); + } + + 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); + +-- +2.3.7 + + +From 2e32a42370048eda7be2ad616dbdf1bbbe785129 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 22 Jul 2015 14:45:05 -0400 +Subject: [PATCH 3/8] pixel-display: add getters for renderer data + +These functions are useful for matching a pixel display +to its renderer. +--- + src/libply-splash-core/ply-pixel-display.c | 12 ++++++++++++ + src/libply-splash-core/ply-pixel-display.h | 2 ++ + 2 files changed, 14 insertions(+) + +diff --git a/src/libply-splash-core/ply-pixel-display.c b/src/libply-splash-core/ply-pixel-display.c +index 3715120..5c5ec69 100644 +--- a/src/libply-splash-core/ply-pixel-display.c ++++ b/src/libply-splash-core/ply-pixel-display.c +@@ -55,60 +55,72 @@ struct _ply_pixel_display + ply_pixel_display_draw_handler_t draw_handler; + void *draw_handler_user_data; + + int pause_count; + + }; + + ply_pixel_display_t * + ply_pixel_display_new (ply_renderer_t *renderer, + ply_renderer_head_t *head) + { + ply_pixel_display_t *display; + ply_pixel_buffer_t *pixel_buffer; + ply_rectangle_t size; + + display = calloc (1, sizeof (ply_pixel_display_t)); + + display->loop = ply_event_loop_get_default (); + display->renderer = renderer; + display->head = head; + + pixel_buffer = ply_renderer_get_buffer_for_head (renderer, head); + ply_pixel_buffer_get_size (pixel_buffer, &size); + + display->width = size.width; + display->height = size.height; + + return display; + } + ++ply_renderer_t * ++ply_pixel_display_get_renderer (ply_pixel_display_t *display) ++{ ++ return display->renderer; ++} ++ ++ply_renderer_head_t * ++ply_pixel_display_get_renderer_head (ply_pixel_display_t *display) ++{ ++ return display->head; ++} ++ + unsigned long + ply_pixel_display_get_width (ply_pixel_display_t *display) + { + return display->width; + } + + unsigned long + ply_pixel_display_get_height (ply_pixel_display_t *display) + { + return display->height; + } + + static void + ply_pixel_display_flush (ply_pixel_display_t *display) + { + if (display->pause_count > 0) + return; + + ply_renderer_flush_head (display->renderer, display->head); + } + + void + ply_pixel_display_pause_updates (ply_pixel_display_t *display) + { + assert (display != NULL); + + display->pause_count++; + } + + void +diff --git a/src/libply-splash-core/ply-pixel-display.h b/src/libply-splash-core/ply-pixel-display.h +index 98a6b3c..92558e9 100644 +--- a/src/libply-splash-core/ply-pixel-display.h ++++ b/src/libply-splash-core/ply-pixel-display.h +@@ -16,53 +16,55 @@ + * 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 + */ + #ifndef PLY_PIXEL_DISPLAY_H + #define PLY_PIXEL_DISPLAY_H + + #include + #include + #include + + #include "ply-event-loop.h" + #include "ply-pixel-buffer.h" + #include "ply-renderer.h" + + typedef struct _ply_pixel_display ply_pixel_display_t; + + typedef void (* ply_pixel_display_draw_handler_t) (void *user_data, + ply_pixel_buffer_t *pixel_buffer, + int x, + int y, + int width, + int height, + ply_pixel_display_t *pixel_display); + + #ifndef PLY_HIDE_FUNCTION_DECLARATIONS + ply_pixel_display_t *ply_pixel_display_new (ply_renderer_t *renderer, + ply_renderer_head_t *head); ++ply_renderer_t *ply_pixel_display_get_renderer (ply_pixel_display_t *display); ++ply_renderer_head_t *ply_pixel_display_get_renderer_head (ply_pixel_display_t *display); + + void ply_pixel_display_free (ply_pixel_display_t *display); + + unsigned long ply_pixel_display_get_width (ply_pixel_display_t *display); + unsigned long ply_pixel_display_get_height (ply_pixel_display_t *display); + + void ply_pixel_display_set_draw_handler (ply_pixel_display_t *display, + ply_pixel_display_draw_handler_t draw_handler, + void *user_data); + + void ply_pixel_display_draw_area (ply_pixel_display_t *display, + int x, + int y, + int width, + int height); + + void ply_pixel_display_pause_updates (ply_pixel_display_t *display); + void ply_pixel_display_unpause_updates (ply_pixel_display_t *display); + + #endif + + #endif /* PLY_PIXEL_DISPLAY_H */ + /* vim: set ts=4 sw=4 et ai ci cino={.5s,^-2,+.5s,t0,g0,e-2,n-2,p2s,(0,=.5s,:.5s */ +-- +2.3.7 + + +From d698a677b0007caded1dfb4652d8e8b9928e068b Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 23 Jul 2015 14:16:48 -0400 +Subject: [PATCH 4/8] device-manager: drop seat abstraction + +The seat abstraction isn't really right, since it forces creating a +link between terminal and video output device, which isn't really +necessary (and other reasons). + +This commit drops the abstraction, and moves all the code that was +in ply-seat.c directly to ply-device-manager.c. +--- + src/libply-splash-core/Makefile.am | 2 - + src/libply-splash-core/ply-boot-splash.c | 258 +++++++------- + src/libply-splash-core/ply-boot-splash.h | 17 +- + src/libply-splash-core/ply-device-manager.c | 530 ++++++++++++++++------------ + src/libply-splash-core/ply-device-manager.h | 32 +- + src/libply-splash-core/ply-seat.c | 374 -------------------- + src/libply-splash-core/ply-seat.h | 66 ---- + src/main.c | 235 ++++++++---- + 8 files changed, 615 insertions(+), 899 deletions(-) + delete mode 100644 src/libply-splash-core/ply-seat.c + delete mode 100644 src/libply-splash-core/ply-seat.h + +diff --git a/src/libply-splash-core/Makefile.am b/src/libply-splash-core/Makefile.am +index d07d7f1..7036569 100644 +--- a/src/libply-splash-core/Makefile.am ++++ b/src/libply-splash-core/Makefile.am +@@ -1,53 +1,51 @@ + AM_CPPFLAGS = -I$(top_srcdir) \ + -I$(srcdir) \ + -I$(srcdir)/../libply \ + -I$(srcdir)/../plugins/controls + + if WITH_SYSTEM_ROOT_INSTALL + librarydir = $(libdir:/usr%=%) + else + librarydir = $(libdir) + endif + + library_LTLIBRARIES = libply-splash-core.la + + 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 \ + ply-text-step-bar.h + + libply_splash_core_la_CFLAGS = $(PLYMOUTH_CFLAGS) $(UDEV_CFLAGS) \ + -DPLYMOUTH_BACKGROUND_COLOR=$(background_color) \ + -DPLYMOUTH_BACKGROUND_END_COLOR=$(background_end_color) \ + -DPLYMOUTH_BACKGROUND_START_COLOR=$(background_start_color) \ + -DPLYMOUTH_PLUGIN_PATH=\"$(PLYMOUTH_PLUGIN_PATH)\" + libply_splash_core_la_LIBADD = $(PLYMOUTH_LIBS) $(UDEV_LIBS) ../libply/libply.la + libply_splash_core_la_LDFLAGS = -export-symbols-regex '^[^_].*' \ + -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \ + -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 \ + ply-text-progress-bar.c \ + ply-text-step-bar.c \ + ply-terminal.c \ + ply-pixel-buffer.c \ + ply-renderer.c \ +- ply-seat.c \ + ply-boot-splash.c + + MAINTAINERCLEANFILES = Makefile.in +diff --git a/src/libply-splash-core/ply-boot-splash.c b/src/libply-splash-core/ply-boot-splash.c +index 160ce45..f7fc70f 100644 +--- a/src/libply-splash-core/ply-boot-splash.c ++++ b/src/libply-splash-core/ply-boot-splash.c +@@ -30,259 +30,196 @@ + #include + #include + #include + #include + #include + + #include "ply-boot-splash-plugin.h" + #include "ply-terminal.h" + #include "ply-event-loop.h" + #include "ply-list.h" + #include "ply-logger.h" + #include "ply-trigger.h" + #include "ply-utils.h" + #include "ply-progress.h" + #include "ply-keyboard.h" + #include "ply-key-file.h" + + #ifndef UPDATES_PER_SECOND + #define UPDATES_PER_SECOND 30 + #endif + + 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_boot_splash_mode_t mode; + ply_buffer_t *boot_buffer; + ply_trigger_t *idle_trigger; +- ply_list_t *seats; ++ ++ ply_keyboard_t *keyboard; ++ ply_list_t *pixel_displays; ++ ply_list_t *text_displays; + + char *theme_path; + char *plugin_dir; + char *status; + + ply_progress_t *progress; + ply_boot_splash_on_idle_handler_t idle_handler; + void *idle_handler_user_data; + + uint32_t is_loaded : 1; + uint32_t should_force_text_mode : 1; + }; + + typedef const ply_boot_splash_plugin_interface_t * + (* get_plugin_interface_function_t) (void); + + static void ply_boot_splash_update_progress (ply_boot_splash_t *splash); + static void ply_boot_splash_detach_from_event_loop (ply_boot_splash_t *splash); + + ply_boot_splash_t * + ply_boot_splash_new (const char *theme_path, + const char *plugin_dir, + ply_buffer_t *boot_buffer) + { + ply_boot_splash_t *splash; + + assert (theme_path != NULL); + + splash = calloc (1, sizeof (ply_boot_splash_t)); + splash->loop = NULL; + splash->theme_path = strdup (theme_path); + splash->plugin_dir = strdup (plugin_dir); + splash->module_handle = NULL; + splash->mode = PLY_BOOT_SPLASH_MODE_INVALID; + + splash->boot_buffer = boot_buffer; +- splash->seats = ply_list_new (); ++ splash->pixel_displays = ply_list_new (); ++ splash->text_displays = ply_list_new (); + + return splash; + } + +-static void +-detach_from_seat (ply_boot_splash_t *splash, +- ply_seat_t *seat) ++void ++ply_boot_splash_set_keyboard (ply_boot_splash_t *splash, ++ ply_keyboard_t *keyboard) + { +- ply_keyboard_t *keyboard; +- ply_list_t *displays; +- ply_list_node_t *node, *next_node; +- +- 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; +- ply_list_node_t *next_node; +- unsigned long width, height; +- +- display = ply_list_node_get_data (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_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; +- } +- +- 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; +- 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 ("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); ++ if (splash->plugin_interface->set_keyboard == NULL) ++ return; + +- node = next_node; +- } ++ splash->plugin_interface->set_keyboard (splash->plugin, keyboard); ++ splash->keyboard = keyboard; + } + +-static void +-attach_to_seat (ply_boot_splash_t *splash, +- ply_seat_t *seat) ++void ++ply_boot_splash_unset_keyboard (ply_boot_splash_t *splash) + { +- ply_keyboard_t *keyboard; +- ply_list_t *displays; +- ply_list_node_t *node, *next_node; +- +- if (splash->plugin_interface->set_keyboard != NULL) +- { +- 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) +- { +- 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 (displays, node); ++ if (splash->plugin_interface->unset_keyboard == NULL) ++ return; + +- width = ply_pixel_display_get_width (display); +- height = ply_pixel_display_get_height (display); ++ splash->plugin_interface->unset_keyboard (splash->plugin, splash->keyboard); ++} + +- ply_trace ("Adding %lux%lu pixel display", width, height); ++void ++ply_boot_splash_add_pixel_display (ply_boot_splash_t *splash, ++ ply_pixel_display_t *display) ++{ ++ unsigned long width, height; + +- splash->plugin_interface->add_pixel_display (splash->plugin, display); ++ if (splash->plugin_interface->add_pixel_display == NULL) ++ return; + +- node = next_node; +- } +- } ++ width = ply_pixel_display_get_width (display); ++ height = ply_pixel_display_get_height (display); + +- if (splash->plugin_interface->add_text_display != NULL) +- { +- displays = ply_seat_get_text_displays (seat); ++ ply_trace ("Adding %lux%lu pixel display", width, height); + +- 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; ++ splash->plugin_interface->add_pixel_display (splash->plugin, display); ++ ply_list_append_data (splash->pixel_displays, display); ++} + +- display = ply_list_node_get_data (node); +- next_node = ply_list_get_next_node (displays, node); ++void ++ply_boot_splash_remove_pixel_display (ply_boot_splash_t *splash, ++ ply_pixel_display_t *display) ++{ ++ unsigned long width, height; + +- number_of_columns = ply_text_display_get_number_of_columns (display); +- number_of_rows = ply_text_display_get_number_of_rows (display); ++ if (splash->plugin_interface->remove_pixel_display == NULL) ++ return; + +- ply_trace ("Adding %dx%d text display", number_of_columns, number_of_rows); ++ width = ply_pixel_display_get_width (display); ++ height = ply_pixel_display_get_height (display); + +- splash->plugin_interface->add_text_display (splash->plugin, display); ++ ply_trace ("Removing %lux%lu pixel display", width, height); + +- node = next_node; +- } +- } ++ splash->plugin_interface->remove_pixel_display (splash->plugin, display); ++ ply_list_remove_data (splash->pixel_displays, display); + } + + void +-ply_boot_splash_attach_to_seat (ply_boot_splash_t *splash, +- ply_seat_t *seat) ++ply_boot_splash_add_text_display (ply_boot_splash_t *splash, ++ ply_text_display_t *display) + { +- ply_list_node_t *node; +- +- node = ply_list_find_node (splash->seats, seat); ++ int number_of_columns, number_of_rows; + +- if (node != NULL) ++ if (splash->plugin_interface->add_text_display == NULL) + return; + +- ply_list_append_data (splash->seats, seat); +- attach_to_seat (splash, seat); ++ 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); ++ ply_list_append_data (splash->text_displays, display); + } + + void +-ply_boot_splash_detach_from_seat (ply_boot_splash_t *splash, +- ply_seat_t *seat) ++ply_boot_splash_remove_text_display (ply_boot_splash_t *splash, ++ ply_text_display_t *display) + { +- ply_list_node_t *node; ++ int number_of_columns, number_of_rows; + +- node = ply_list_find_node (splash->seats, seat); +- +- if (node == NULL) ++ if (splash->plugin_interface->remove_text_display == NULL) + return; + +- ply_list_remove_data (splash->seats, seat); +- detach_from_seat (splash, seat); ++ 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); ++ ++ splash->plugin_interface->remove_text_display (splash->plugin, display); ++ ply_list_remove_data (splash->text_displays, display); + } + + bool + ply_boot_splash_load (ply_boot_splash_t *splash) + { + ply_key_file_t *key_file; + char *module_name; + char *module_path; + + assert (splash != NULL); + + get_plugin_interface_function_t get_boot_splash_plugin_interface; + + key_file = ply_key_file_new (splash->theme_path); + + if (!ply_key_file_load (key_file)) + return false; + + module_name = ply_key_file_get_value (key_file, "Plymouth Theme", "ModuleName"); + + asprintf (&module_path, "%s%s.so", + splash->plugin_dir, module_name); + free (module_name); + + splash->module_handle = ply_open_module (module_path); + + free (module_path); + + if (splash->module_handle == NULL) + { +@@ -364,106 +301,149 @@ ply_boot_splash_load_built_in (ply_boot_splash_t *splash) + } + + splash->plugin = splash->plugin_interface->create_plugin (NULL); + + assert (splash->plugin != NULL); + + splash->is_loaded = true; + + return true; + } + + void + ply_boot_splash_unload (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; + + splash->is_loaded = false; + } + + static void +-detach_from_seats (ply_boot_splash_t *splash) ++remove_pixel_displays (ply_boot_splash_t *splash) ++{ ++ ply_list_node_t *node; ++ ++ if (splash->plugin_interface->remove_pixel_display == NULL) ++ return; ++ ++ ply_trace ("removing pixel displays"); ++ ++ node = ply_list_get_first_node (splash->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 (splash->pixel_displays, node); ++ ++ width = ply_pixel_display_get_width (display); ++ height = ply_pixel_display_get_height (display); ++ ++ ply_trace ("Removing %lux%lu pixel display", width, height); ++ ++ splash->plugin_interface->remove_pixel_display (splash->plugin, display); ++ ++ node = next_node; ++ } ++} ++ ++static void ++remove_text_displays (ply_boot_splash_t *splash) + { + ply_list_node_t *node; + +- ply_trace ("detaching from seats"); ++ if (splash->plugin_interface->remove_text_display == NULL) ++ return; + +- node = ply_list_get_first_node (splash->seats); ++ ply_trace ("removing text displays"); ++ ++ node = ply_list_get_first_node (splash->text_displays); + while (node != NULL) + { +- ply_seat_t *seat; ++ ply_text_display_t *display; + ply_list_node_t *next_node; ++ int number_of_columns, number_of_rows; + +- seat = ply_list_node_get_data (node); +- next_node = ply_list_get_next_node (splash->seats, node); ++ display = ply_list_node_get_data (node); ++ next_node = ply_list_get_next_node (splash->text_displays, node); + +- detach_from_seat (splash, seat); ++ number_of_columns = ply_text_display_get_number_of_columns (display); ++ number_of_rows = ply_text_display_get_number_of_rows (display); + +- ply_list_remove_node (splash->seats, node); ++ ply_trace ("Removing %dx%d text display", number_of_columns, number_of_rows); ++ ++ splash->plugin_interface->remove_text_display (splash->plugin, display); + + node = next_node; + } + } + + void + ply_boot_splash_free (ply_boot_splash_t *splash) + { + ply_trace ("freeing splash"); + if (splash == NULL) + return; + + if (splash->loop != NULL) + { + if (splash->plugin_interface->on_boot_progress != NULL) + { + ply_event_loop_stop_watching_for_timeout (splash->loop, + (ply_event_loop_timeout_handler_t) + ply_boot_splash_update_progress, splash); + } + + ply_event_loop_stop_watching_for_exit (splash->loop, (ply_event_loop_exit_handler_t) + ply_boot_splash_detach_from_event_loop, + splash); + } + +- detach_from_seats (splash); +- ply_list_free (splash->seats); ++ ply_boot_splash_unset_keyboard (splash); ++ ++ remove_pixel_displays (splash); ++ ply_list_free (splash->pixel_displays); ++ ++ remove_text_displays (splash); ++ ply_list_free (splash->text_displays); + + if (splash->module_handle != NULL) + ply_boot_splash_unload (splash); + + if (splash->idle_trigger != NULL) + ply_trigger_free (splash->idle_trigger); + + free (splash->theme_path); + free (splash->plugin_dir); + free (splash); + } + + static void + ply_boot_splash_update_progress (ply_boot_splash_t *splash) + { + double percentage=0.0; + double time=0.0; + + assert (splash != NULL); + + if (splash->progress) + { + percentage = ply_progress_get_percentage(splash->progress); + time = ply_progress_get_time(splash->progress); + } + + if (splash->plugin_interface->on_boot_progress != NULL) + splash->plugin_interface->on_boot_progress (splash->plugin, + time, + percentage); +diff --git a/src/libply-splash-core/ply-boot-splash.h b/src/libply-splash-core/ply-boot-splash.h +index 335039b..8937c1f 100644 +--- a/src/libply-splash-core/ply-boot-splash.h ++++ b/src/libply-splash-core/ply-boot-splash.h +@@ -6,81 +6,86 @@ + * 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 + */ + #ifndef PLY_BOOT_SPLASH_H + #define PLY_BOOT_SPLASH_H + + #include + #include + #include + + #include "ply-event-loop.h" + #include "ply-buffer.h" + #include "ply-terminal.h" + #include "ply-keyboard.h" + #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); + + #ifndef PLY_HIDE_FUNCTION_DECLARATIONS + ply_boot_splash_t *ply_boot_splash_new (const char * theme_path, + const char * plugin_dir, + ply_buffer_t * boot_buffer); + + 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_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_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 *pixel_display); ++void ply_boot_splash_remove_pixel_display (ply_boot_splash_t *splash, ++ ply_pixel_display_t *pixel_display); ++void ply_boot_splash_add_text_display (ply_boot_splash_t *splash, ++ ply_text_display_t *text_display); ++void ply_boot_splash_remove_text_display (ply_boot_splash_t *splash, ++ ply_text_display_t *text_display); + 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); + bool ply_boot_splash_system_update (ply_boot_splash_t *splash, + int progress); + void ply_boot_splash_update_status (ply_boot_splash_t *splash, + const char *status); + void ply_boot_splash_update_output (ply_boot_splash_t *splash, + const char *output, + size_t size); + void ply_boot_splash_root_mounted (ply_boot_splash_t *splash); + void ply_boot_splash_display_message (ply_boot_splash_t *splash, + const char *message); + void ply_boot_splash_hide_message (ply_boot_splash_t *splash, + const char *message); + void ply_boot_splash_hide (ply_boot_splash_t *splash); + void ply_boot_splash_display_normal (ply_boot_splash_t *splash); + void ply_boot_splash_display_password (ply_boot_splash_t *splash, + const char *prompt, + int bullets); + void ply_boot_splash_display_question (ply_boot_splash_t *splash, + const char *prompt, + const char *entry_text); + void ply_boot_splash_attach_to_event_loop (ply_boot_splash_t *splash, + ply_event_loop_t *loop); + void ply_boot_splash_attach_progress (ply_boot_splash_t *splash, + ply_progress_t *progress); + void ply_boot_splash_become_idle (ply_boot_splash_t *splash, + ply_boot_splash_on_idle_handler_t idle_handler, + void *user_data); +diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c +index 5766bcb..c7568c1 100644 +--- a/src/libply-splash-core/ply-device-manager.c ++++ b/src/libply-splash-core/ply-device-manager.c +@@ -14,597 +14,580 @@ + * + * 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 + #include + #include + #include + #include + #include + #include + #include + #include + + #include + + #include "ply-logger.h" + #include "ply-event-loop.h" + #include "ply-hashtable.h" + #include "ply-list.h" + #include "ply-utils.h" + + #define SUBSYSTEM_DRM "drm" + #define SUBSYSTEM_FRAME_BUFFER "graphics" + +-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); ++static void create_devices_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_hashtable_t *renderers; + ply_terminal_t *local_console_terminal; +- ply_seat_t *local_console_seat; +- ply_list_t *seats; ++ ply_list_t *keyboards; ++ ply_list_t *text_displays; ++ ply_list_t *pixel_displays; + struct udev *udev_context; + struct udev_queue *udev_queue; + int udev_queue_fd; + ply_fd_watch_t *udev_queue_fd_watch; + 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; ++ ply_keyboard_added_handler_t keyboard_added_handler; ++ ply_keyboard_removed_handler_t keyboard_removed_handler; ++ ply_pixel_display_added_handler_t pixel_display_added_handler; ++ ply_pixel_display_removed_handler_t pixel_display_removed_handler; ++ ply_text_display_added_handler_t text_display_added_handler; ++ ply_text_display_removed_handler_t text_display_removed_handler; ++ void *event_handler_data; ++ ++ uint32_t local_console_managed : 1; ++ uint32_t local_console_is_text : 1; + }; + + 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 bool + drm_device_in_use (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; ++ ply_renderer_t *renderer; + +- seat = ply_list_node_get_data (node); +- next_node = ply_list_get_next_node (manager->seats, node); +- renderer = ply_seat_get_renderer (seat); ++ renderer = ply_hashtable_lookup (manager->renderers, (void *) device_path); + +- 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) +- { +- return true; +- } +- } +- } +- +- node = next_node; +- } +- +- return false; ++ return renderer != NULL; + } + + static bool + fb_device_has_drm_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; + bool has_drm_device = false; + + /* 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); + + ply_trace ("trying to find associated drm node for fb device (path: %s)", 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 && drm_device_in_use (manager, card_node)) + has_drm_device = true; + else + ply_trace ("no card node!"); + + udev_device_unref (card_device); + } + else + { + ply_trace ("no card entry!"); + } + + udev_enumerate_unref (card_matches); + return has_drm_device; + } + + static void +-create_seat_for_udev_device (ply_device_manager_t *manager, +- struct udev_device *device) ++create_devices_for_udev_device (ply_device_manager_t *manager, ++ struct udev_device *device) + { + bool for_local_console; + const char *device_path; + ply_terminal_t *terminal = NULL; + + for_local_console = device_is_for_local_console (manager, device); + + ply_trace ("device is for local console: %s", for_local_console? "yes" : "no"); + + if (for_local_console) + terminal = manager->local_console_terminal; + + device_path = udev_device_get_devnode (device); + + if (device_path != NULL) + { + const char *subsystem; + ply_renderer_type_t renderer_type = PLY_RENDERER_TYPE_NONE; + + subsystem = udev_device_get_subsystem (device); + ply_trace ("device subsystem is %s", subsystem); + + if (subsystem != NULL && strcmp (subsystem, SUBSYSTEM_DRM) == 0) + { + ply_trace ("found DRM device %s", device_path); + renderer_type = PLY_RENDERER_TYPE_DRM; + } + else if (strcmp (subsystem, SUBSYSTEM_FRAME_BUFFER) == 0) + { + ply_trace ("found frame buffer device %s", device_path); + if (!fb_device_has_drm_device (manager, device)) + { + renderer_type = PLY_RENDERER_TYPE_FRAME_BUFFER; + } + else + { + ply_trace ("ignoring, since there's a DRM device associated with it"); + } + } + + if (renderer_type != PLY_RENDERER_TYPE_NONE) +- create_seat_for_terminal_and_renderer_type (manager, +- device_path, +- terminal, +- renderer_type); ++ create_devices_for_terminal_and_renderer_type (manager, ++ device_path, ++ terminal, ++ renderer_type); + } + } + + static void +-free_seat_from_device_path (ply_device_manager_t *manager, +- const char *device_path) ++free_displays_for_renderer (ply_device_manager_t *manager, ++ ply_renderer_t *renderer) + { + ply_list_node_t *node; + +- node = ply_list_get_first_node (manager->seats); ++ node = ply_list_get_first_node (manager->pixel_displays); + while (node != NULL) + { +- ply_seat_t *seat; +- ply_renderer_t *renderer; + ply_list_node_t *next_node; +- const char *renderer_device_path; ++ ply_pixel_display_t *display; ++ ply_renderer_t *display_renderer; + +- seat = ply_list_node_get_data (node); +- next_node = ply_list_get_next_node (manager->seats, node); +- renderer = ply_seat_get_renderer (seat); ++ display = ply_list_node_get_data (node); ++ next_node = ply_list_get_next_node (manager->pixel_displays, node); ++ display_renderer = ply_pixel_display_get_renderer (display); + +- if (renderer != NULL) ++ if (display_renderer == renderer) + { +- renderer_device_path = ply_renderer_get_device_name (renderer); ++ if (manager->pixel_display_removed_handler != NULL) ++ manager->pixel_display_removed_handler (manager->event_handler_data, display); + +- 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; +- } +- } ++ ply_pixel_display_free (display); ++ ply_list_remove_node (manager->pixel_displays, node); + } + + node = next_node; + } + } + + static void +-free_seat_for_udev_device (ply_device_manager_t *manager, +- struct udev_device *device) ++free_devices_from_device_path (ply_device_manager_t *manager, ++ const char *device_path) ++{ ++ char *key = NULL; ++ ply_renderer_t *renderer = NULL; ++ ++ ply_hashtable_lookup_full (manager->renderers, ++ (void *) device_path, ++ (void **) &key, ++ (void **) &renderer); ++ ++ if (renderer == NULL) ++ return; ++ ++ free_displays_for_renderer (manager, renderer); ++ ++ ply_hashtable_remove (manager->renderers, (void *) device_path); ++ free (key); ++ ply_renderer_free (renderer); ++} ++ ++static void ++free_devices_for_udev_device (ply_device_manager_t *manager, ++ struct udev_device *device) + { + const char *device_path; + + device_path = udev_device_get_devnode (device); + + if (device_path != NULL) +- free_seat_from_device_path (manager, device_path); ++ free_devices_from_device_path (manager, device_path); + } + + static bool +-create_seats_for_subsystem (ply_device_manager_t *manager, +- const char *subsystem) ++create_devices_for_subsystem (ply_device_manager_t *manager, ++ const char *subsystem) + { + struct udev_enumerate *matches; + struct udev_list_entry *entry; + bool found_device = false; + +- ply_trace ("creating seats for %s devices", ++ ply_trace ("creating devices for %s devices", + strcmp (subsystem, SUBSYSTEM_FRAME_BUFFER) == 0? + "frame buffer": + subsystem); + + matches = udev_enumerate_new (manager->udev_context); + udev_enumerate_add_match_subsystem (matches, subsystem); + udev_enumerate_scan_devices (matches); + + udev_list_entry_foreach (entry, udev_enumerate_get_list_entry (matches)) + { + struct udev_device *device = NULL; + const char *path; + + path = udev_list_entry_get_name (entry); + + if (path == NULL) + { + ply_trace ("path was null!"); + continue; + } + + ply_trace ("found device %s", path); + + device = udev_device_new_from_syspath (manager->udev_context, path); + + /* if device isn't fully initialized, we'll get an add event later + */ + if (udev_device_get_is_initialized (device)) + { + ply_trace ("device is initialized"); + + /* We only care about devices assigned to a (any) seat. Floating + * devices should be ignored. + */ + if (udev_device_has_tag (device, "seat")) + { + const char *node; + node = udev_device_get_devnode (device); + if (node != NULL) + { + ply_trace ("found node %s", node); + found_device = true; +- create_seat_for_udev_device (manager, device); ++ create_devices_for_udev_device (manager, device); + } + } + else + { + ply_trace ("device doesn't have a seat tag"); + } + } + else + { + ply_trace ("it's not initialized"); + } + + udev_device_unref (device); + } + + udev_enumerate_unref (matches); + + return found_device; + } + + static void + on_udev_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); + + ply_trace ("got %s event for device %s", action, udev_device_get_sysname (device)); + + if (action == NULL) + return; + + if (strcmp (action, "add") == 0) + { + const char *subsystem; + bool coldplug_complete = manager->udev_queue_fd_watch == NULL; + + subsystem = udev_device_get_subsystem (device); + + if (strcmp (subsystem, SUBSYSTEM_DRM) == 0 || + coldplug_complete) + { +- ply_list_t *local_pixel_displays = NULL; +- +- if (manager->local_console_seat != NULL) +- local_pixel_displays = ply_seat_get_pixel_displays (manager->local_console_seat); +- +- if (coldplug_complete && manager->local_console_seat != NULL && local_pixel_displays == NULL) ++ if (coldplug_complete && manager->local_console_managed && manager->local_console_is_text) + ply_trace ("ignoring since we're already using text splash for local console"); + else +- create_seat_for_udev_device (manager, device); ++ create_devices_for_udev_device (manager, device); + } + else + { + ply_trace ("ignoring since we only handle subsystem %s devices after coldplug completes", subsystem); + } + } + else if (strcmp (action, "remove") == 0) + { +- free_seat_for_udev_device (manager, device); ++ free_devices_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"); + + udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, SUBSYSTEM_DRM, NULL); + udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, SUBSYSTEM_FRAME_BUFFER, 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_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_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 || + strcmp (full_name, ply_terminal_get_name (manager->local_console_terminal)) == 0) + { + terminal = manager->local_console_terminal; + + ply_hashtable_insert (manager->terminals, + (void *) ply_terminal_get_name (terminal), + 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; + } + ++static void ++free_renderer (char *device_path, ++ ply_renderer_t *renderer, ++ ply_device_manager_t *manager) ++{ ++ free_devices_from_device_path (manager, device_path); ++} ++ ++static void ++free_renderers (ply_device_manager_t *manager) ++{ ++ ply_hashtable_foreach (manager->renderers, ++ (ply_hashtable_foreach_func_t *) ++ free_renderer, ++ manager); ++} ++ + 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->renderers = ply_hashtable_new (ply_hashtable_string_hash, ply_hashtable_string_compare); + manager->local_console_terminal = ply_terminal_new (default_tty); +- manager->seats = ply_list_new (); ++ manager->keyboards = ply_list_new (); ++ manager->text_displays = ply_list_new (); ++ manager->pixel_displays = 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; + + ply_event_loop_stop_watching_for_exit (manager->loop, + (ply_event_loop_exit_handler_t) + detach_from_event_loop, + manager); +- free_seats (manager); +- ply_list_free (manager->seats); +- + free_terminals (manager); + ply_hashtable_free (manager->terminals); + ++ free_renderers (manager); ++ ply_hashtable_free (manager->renderers); ++ + if (manager->udev_monitor != NULL) + udev_monitor_unref (manager->udev_monitor); + + if (manager->udev_context != NULL) + udev_unref (manager->udev_context); + + free (manager); + } + + static bool + add_consoles_from_file (ply_device_manager_t *manager, + const char *path) + { + int fd; + char contents[512] = ""; + ssize_t contents_length; + bool has_serial_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 false; + } + + ply_trace ("reading file"); + contents_length = read (fd, contents, sizeof (contents) - 1); +@@ -638,343 +621,438 @@ add_consoles_from_file (ply_device_manager_t *manager, + + /* 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); + + if (terminal != manager->local_console_terminal) + has_serial_consoles = true; + + /* 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 has_serial_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) ++create_pixel_displays_for_renderer (ply_device_manager_t *manager, ++ ply_renderer_t *renderer) ++{ ++ ply_list_t *heads; ++ ply_list_node_t *node; ++ ++ heads = ply_renderer_get_heads (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 (renderer, head); ++ ++ ply_list_append_data (manager->pixel_displays, display); ++ ++ if (manager->pixel_display_added_handler != NULL) ++ manager->pixel_display_added_handler (manager->event_handler_data, display); ++ node = next_node; ++ } ++} ++ ++static void ++create_text_displays_for_terminal (ply_device_manager_t *manager, ++ ply_terminal_t *terminal) + { +- ply_seat_t *seat; ++ ply_text_display_t *display; ++ ++ if (!ply_terminal_is_open (terminal)) ++ { ++ if (!ply_terminal_open (terminal)) ++ { ++ ply_trace ("could not add terminal %s: %m", ++ ply_terminal_get_name (terminal)); ++ return; ++ } ++ } ++ ++ ply_trace ("adding text display for terminal %s", ++ ply_terminal_get_name (terminal)); ++ ++ display = ply_text_display_new (terminal); ++ ply_list_append_data (manager->text_displays, display); ++ ++ if (manager->text_display_added_handler != NULL) ++ manager->text_display_added_handler (manager->event_handler_data, display); ++} ++ ++static void ++create_devices_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_renderer_t *renderer = NULL; ++ ply_keyboard_t *keyboard = NULL; ++ + bool is_local_terminal = false; + + if (terminal != NULL && manager->local_console_terminal == terminal) + is_local_terminal = true; + +- if (is_local_terminal && manager->local_console_seat != NULL) ++ if (is_local_terminal && manager->local_console_managed) + { +- ply_trace ("trying to create seat for local console when one already exists"); ++ ply_trace ("trying to create devices for local console when one already exists"); + return; + } + +- ply_trace ("creating seat for %s (renderer type: %u) (terminal: %s)", ++ ply_trace ("creating devices 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)) ++ if (renderer_type != PLY_RENDERER_TYPE_NONE) + { +- ply_trace ("could not create seat"); +- ply_seat_free (seat); +- return; ++ renderer = ply_renderer_new (renderer_type, device_path, terminal); ++ ++ if (!ply_renderer_open (renderer)) ++ { ++ ply_trace ("could not open renderer for %s", device_path); ++ ply_renderer_free (renderer); ++ renderer = NULL; ++ if (renderer_type != PLY_RENDERER_TYPE_AUTO) ++ return; ++ } ++ } ++ ++ if (renderer != NULL) ++ { ++ keyboard = ply_keyboard_new_for_renderer (renderer); ++ ply_list_append_data (manager->keyboards, keyboard); ++ ++ if (manager->keyboard_added_handler != NULL) ++ manager->keyboard_added_handler (manager->event_handler_data, keyboard); ++ ++ create_pixel_displays_for_renderer (manager, renderer); ++ ply_hashtable_insert (manager->renderers, strdup (device_path), renderer); ++ } ++ else if (terminal != NULL) ++ { ++ keyboard = ply_keyboard_new_for_terminal (terminal); ++ ply_list_append_data (manager->keyboards, keyboard); ++ ++ if (manager->keyboard_added_handler != NULL) ++ manager->keyboard_added_handler (manager->event_handler_data, keyboard); ++ } ++ ++ if (terminal != NULL) ++ { ++ create_text_displays_for_terminal (manager, terminal); ++ ++ if (is_local_terminal) ++ { ++ manager->local_console_is_text = true; ++ } + } + +- ply_list_append_data (manager->seats, seat); ++ if (keyboard != NULL) ++ { ++ ply_keyboard_watch_for_input (keyboard); ++ } + + if (is_local_terminal) +- manager->local_console_seat = seat; ++ manager->local_console_managed = true; + +- 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_devices_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); ++ create_devices_for_terminal_and_renderer_type (manager, ++ device_path, ++ terminal, ++ PLY_RENDERER_TYPE_NONE); + } + static bool +-create_seats_from_terminals (ply_device_manager_t *manager) ++create_devices_from_terminals (ply_device_manager_t *manager) + { + bool has_serial_consoles; + + ply_trace ("checking for consoles"); + + if (manager->flags & PLY_DEVICE_MANAGER_FLAGS_IGNORE_SERIAL_CONSOLES) + { + has_serial_consoles = false; + ply_trace ("ignoring all consoles but default console because explicitly told to."); + } + else + { + has_serial_consoles = add_consoles_from_file (manager, "/sys/class/tty/console/active"); + } + + if (has_serial_consoles) + { + ply_trace ("serial consoles detected, managing them with details forced"); + ply_hashtable_foreach (manager->terminals, + (ply_hashtable_foreach_func_t *) +- create_seat_for_terminal, ++ create_devices_for_terminal, + manager); + return true; + } + + return false; + } + + static void +-create_seats_from_udev (ply_device_manager_t *manager) ++create_devices_from_udev (ply_device_manager_t *manager) + { + bool found_drm_device, found_fb_device; + + ply_trace ("Looking for devices from udev"); + +- found_drm_device = create_seats_for_subsystem (manager, SUBSYSTEM_DRM); +- found_fb_device = create_seats_for_subsystem (manager, SUBSYSTEM_FRAME_BUFFER); ++ found_drm_device = create_devices_for_subsystem (manager, SUBSYSTEM_DRM); ++ found_fb_device = create_devices_for_subsystem (manager, SUBSYSTEM_FRAME_BUFFER); + + if (found_drm_device || found_fb_device) + return; + +- ply_trace ("Creating non-graphical seat, since there's no suitable graphics hardware"); +- create_seat_for_terminal_and_renderer_type (manager, +- ply_terminal_get_name (manager->local_console_terminal), +- manager->local_console_terminal, +- PLY_RENDERER_TYPE_NONE); ++ ply_trace ("Creating non-graphical devices, since there's no suitable graphics hardware"); ++ create_devices_for_terminal_and_renderer_type (manager, ++ ply_terminal_get_name (manager->local_console_terminal), ++ manager->local_console_terminal, ++ PLY_RENDERER_TYPE_NONE); + } + + static void +-create_fallback_seat (ply_device_manager_t *manager) ++create_fallback_devices (ply_device_manager_t *manager) + { +- create_seat_for_terminal_and_renderer_type (manager, +- ply_terminal_get_name (manager->local_console_terminal), +- manager->local_console_terminal, +- PLY_RENDERER_TYPE_AUTO); ++ create_devices_for_terminal_and_renderer_type (manager, ++ ply_terminal_get_name (manager->local_console_terminal), ++ manager->local_console_terminal, ++ PLY_RENDERER_TYPE_AUTO); + } + + static void + on_udev_queue_changed (ply_device_manager_t *manager) + { + + if (!udev_queue_get_queue_is_empty (manager->udev_queue)) + return; + + ply_trace ("udev coldplug complete"); + ply_event_loop_stop_watching_fd (manager->loop, manager->udev_queue_fd_watch); + manager->udev_queue_fd_watch = NULL; + udev_queue_unref (manager->udev_queue); + + close (manager->udev_queue_fd); + manager->udev_queue_fd = -1; + + manager->udev_queue = NULL; + +- create_seats_from_udev (manager); ++ create_devices_from_udev (manager); + } + + static void + watch_for_coldplug_completion (ply_device_manager_t *manager) + { + int fd; + int result; + + manager->udev_queue = udev_queue_new (manager->udev_context); + + if (udev_queue_get_queue_is_empty (manager->udev_queue)) + { + ply_trace ("udev coldplug completed already "); +- create_seats_from_udev (manager); ++ create_devices_from_udev (manager); + return; + } + + fd = inotify_init1 (IN_CLOEXEC); + result = inotify_add_watch (fd, "/run/udev", IN_MOVED_TO| IN_DELETE); + + if (result < 0) + { + ply_trace ("could not watch for udev to show up: %m"); + close (fd); + +- create_fallback_seat (manager); ++ create_fallback_devices (manager); + return; + } + + manager->udev_queue_fd = fd; + + manager->udev_queue_fd_watch = ply_event_loop_watch_fd (manager->loop, + fd, + PLY_EVENT_LOOP_FD_STATUS_HAS_DATA, + (ply_event_handler_t) + on_udev_queue_changed, + NULL, + manager); + + } + + 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) ++ply_device_manager_watch_devices (ply_device_manager_t *manager, ++ ply_keyboard_added_handler_t keyboard_added_handler, ++ ply_keyboard_removed_handler_t keyboard_removed_handler, ++ ply_pixel_display_added_handler_t pixel_display_added_handler, ++ ply_pixel_display_removed_handler_t pixel_display_removed_handler, ++ ply_text_display_added_handler_t text_display_added_handler, ++ ply_text_display_removed_handler_t text_display_removed_handler, ++ void *data) + { +- bool done_with_initial_seat_setup; ++ bool done_with_initial_devices_setup; + +- manager->seat_added_handler = seat_added_handler; +- manager->seat_removed_handler = seat_removed_handler; +- manager->seat_event_handler_data = data; ++ manager->keyboard_added_handler = keyboard_added_handler; ++ manager->keyboard_removed_handler = keyboard_removed_handler; ++ manager->pixel_display_added_handler = pixel_display_added_handler; ++ manager->pixel_display_removed_handler = pixel_display_removed_handler; ++ manager->text_display_added_handler = text_display_added_handler; ++ manager->text_display_removed_handler = text_display_removed_handler; ++ manager->event_handler_data = data; + +- /* Try to create seats for each serial device right away, if possible ++ /* Try to create devices for each serial device right away, if possible + */ +- done_with_initial_seat_setup = create_seats_from_terminals (manager); ++ done_with_initial_devices_setup = create_devices_from_terminals (manager); + +- if (done_with_initial_seat_setup) ++ if (done_with_initial_devices_setup) + return; + + if ((manager->flags & PLY_DEVICE_MANAGER_FLAGS_IGNORE_UDEV)) + { +- ply_trace ("udev support disabled, creating fallback seat"); +- create_fallback_seat (manager); ++ ply_trace ("udev support disabled, creating fallback devices"); ++ create_fallback_devices (manager); + return; + } + + watch_for_udev_events (manager); + watch_for_coldplug_completion (manager); + } + + bool +-ply_device_manager_has_open_seats (ply_device_manager_t *manager) ++ply_device_manager_has_displays (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; ++ return ply_list_get_length (manager->pixel_displays) > 0 || ++ ply_list_get_length (manager->text_displays) > 0; ++} + +- node = next_node; +- } ++ply_list_t * ++ply_device_manager_get_keyboards (ply_device_manager_t *manager) ++{ ++ return manager->keyboards; ++} + +- return false; ++ply_list_t * ++ply_device_manager_get_pixel_displays (ply_device_manager_t *manager) ++{ ++ return manager->pixel_displays; + } + + ply_list_t * +-ply_device_manager_get_seats (ply_device_manager_t *manager) ++ply_device_manager_get_text_displays (ply_device_manager_t *manager) + { +- return manager->seats; ++ return manager->text_displays; + } + + ply_terminal_t * + ply_device_manager_get_default_terminal (ply_device_manager_t *manager) + { + return manager->local_console_terminal; + } + ++static void ++activate_renderer (char *device_path, ++ ply_renderer_t *renderer, ++ ply_device_manager_t *manager) ++{ ++ ply_renderer_activate (renderer); ++} ++ + 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); ++ ply_hashtable_foreach (manager->renderers, ++ (ply_hashtable_foreach_func_t *) ++ activate_renderer, ++ manager); ++} + +- node = next_node; +- } ++static void ++deactivate_renderer (char *device_path, ++ ply_renderer_t *renderer, ++ ply_device_manager_t *manager) ++{ ++ ply_renderer_deactivate (renderer); + } + + 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; +- } ++ ply_hashtable_foreach (manager->renderers, ++ (ply_hashtable_foreach_func_t *) ++ deactivate_renderer, ++ manager); + } + + 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); ++ node = ply_list_get_first_node (manager->keyboards); + while (node != NULL) + { +- ply_seat_t *seat; ++ ply_keyboard_t *keyboard; + ply_list_node_t *next_node; + +- seat = ply_list_node_get_data (node); +- next_node = ply_list_get_next_node (manager->seats, node); ++ keyboard = ply_list_node_get_data (node); ++ next_node = ply_list_get_next_node (manager->keyboards, node); + +- ply_seat_activate_keyboard (seat); ++ ply_keyboard_watch_for_input (keyboard); + + 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); ++ node = ply_list_get_first_node (manager->keyboards); + while (node != NULL) + { +- ply_seat_t *seat; ++ ply_keyboard_t *keyboard; + ply_list_node_t *next_node; + +- seat = ply_list_node_get_data (node); +- next_node = ply_list_get_next_node (manager->seats, node); ++ keyboard = ply_list_node_get_data (node); ++ next_node = ply_list_get_next_node (manager->keyboards, node); + +- ply_seat_deactivate_keyboard (seat); ++ ply_keyboard_stop_watching_for_input (keyboard); + + node = next_node; + } + } +diff --git a/src/libply-splash-core/ply-device-manager.h b/src/libply-splash-core/ply-device-manager.h +index d9c58e8..b628e41 100644 +--- a/src/libply-splash-core/ply-device-manager.h ++++ b/src/libply-splash-core/ply-device-manager.h +@@ -1,56 +1,70 @@ + /* 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 +-#include "ply-seat.h" ++ ++#include "ply-keyboard.h" ++#include "ply-pixel-display.h" ++#include "ply-renderer.h" ++#include "ply-text-display.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 *); ++typedef void (* ply_keyboard_added_handler_t) (void *, ply_keyboard_t *); ++typedef void (* ply_keyboard_removed_handler_t) (void *, ply_keyboard_t *); ++typedef void (* ply_pixel_display_added_handler_t) (void *, ply_pixel_display_t *); ++typedef void (* ply_pixel_display_removed_handler_t) (void *, ply_pixel_display_t *); ++typedef void (* ply_text_display_added_handler_t) (void *, ply_text_display_t *); ++typedef void (* ply_text_display_removed_handler_t) (void *, ply_text_display_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_watch_devices (ply_device_manager_t *manager, ++ ply_keyboard_added_handler_t keyboard_added_handler, ++ ply_keyboard_removed_handler_t keyboard_removed_handler, ++ ply_pixel_display_added_handler_t pixel_display_added_handler, ++ ply_pixel_display_removed_handler_t pixel_display_removed_handler, ++ ply_text_display_added_handler_t text_display_added_handler, ++ ply_text_display_removed_handler_t text_display_removed_handler, ++ void *data); ++bool ply_device_manager_has_displays (ply_device_manager_t *manager); ++ply_list_t *ply_device_manager_get_keyboards (ply_device_manager_t *manager); ++ply_list_t *ply_device_manager_get_pixel_displays (ply_device_manager_t *manager); ++ply_list_t *ply_device_manager_get_text_displays (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: */ +diff --git a/src/libply-splash-core/ply-seat.c b/src/libply-splash-core/ply-seat.c +deleted file mode 100644 +index 1c885c2..0000000 +--- a/src/libply-splash-core/ply-seat.c ++++ /dev/null +@@ -1,374 +0,0 @@ +-/* 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 +- */ +-#include "config.h" +-#include "ply-seat.h" +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-#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; +-}; +- +-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; +- +- if (!ply_terminal_is_open (seat->terminal)) +- { +- if (!ply_terminal_open (seat->terminal)) +- { +- ply_trace ("could not add terminal %s: %m", +- ply_terminal_get_name (seat->terminal)); +- return; +- } +- } +- +- ply_trace ("adding text display for terminal %s", +- ply_terminal_get_name (seat->terminal)); +- +- 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)) +- { +- ply_trace ("could not open renderer for %s", device); +- ply_renderer_free (renderer); +- +- if (renderer_type != PLY_RENDERER_TYPE_AUTO) +- return false; +- } +- else +- { +- seat->renderer = renderer; +- } +- } +- +- if (seat->renderer != NULL) +- { +- seat->keyboard = ply_keyboard_new_for_renderer (seat->renderer); +- add_pixel_displays (seat); +- +- } +- else if (seat->terminal != NULL) +- { +- seat->keyboard = ply_keyboard_new_for_terminal (seat->terminal); +- } +- +- if (seat->terminal != NULL) +- { +- add_text_displays (seat); +- } +- else +- { +- ply_trace ("not adding text display for seat, since seat has no associated terminal"); +- } +- +- if (seat->keyboard != NULL) +- { +- ply_keyboard_watch_for_input (seat->keyboard); +- } +- else +- { +- ply_trace ("not watching seat for input"); +- } +- +- 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 == 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 == NULL) +- return; +- +- ply_trace ("deactivating renderer"); +- ply_renderer_deactivate (seat->renderer); +-} +- +-void +-ply_seat_activate_keyboard (ply_seat_t *seat) +-{ +- if (seat->keyboard == NULL) +- return; +- +- ply_trace ("activating keyboard"); +- ply_keyboard_watch_for_input (seat->keyboard); +-} +- +-void +-ply_seat_activate_renderer (ply_seat_t *seat) +-{ +- if (seat->renderer == NULL) +- return; +- +- ply_trace ("activating renderer"); +- ply_renderer_activate (seat->renderer); +-} +- +-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 */ +diff --git a/src/libply-splash-core/ply-seat.h b/src/libply-splash-core/ply-seat.h +deleted file mode 100644 +index d5d3397..0000000 +--- a/src/libply-splash-core/ply-seat.h ++++ /dev/null +@@ -1,66 +0,0 @@ +-/* 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 +- */ +-#ifndef PLY_SEAT_H +-#define PLY_SEAT_H +- +-#include +-#include +-#include +-#include +- +-#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 */ +diff --git a/src/main.c b/src/main.c +index db5c281..ec46199 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -108,62 +108,62 @@ typedef struct + double splash_delay; + + char kernel_command_line[PLY_MAX_COMMAND_LINE_SIZE]; + uint32_t kernel_command_line_is_set : 1; + uint32_t no_boot_log : 1; + uint32_t showing_details : 1; + uint32_t system_initialized : 1; + uint32_t is_redirected : 1; + uint32_t is_attached : 1; + uint32_t should_be_attached : 1; + uint32_t should_retain_splash : 1; + uint32_t is_inactive : 1; + uint32_t is_shown : 1; + uint32_t should_force_details : 1; + + char *override_splash_path; + char *system_default_splash_path; + char *distribution_default_splash_path; + const char *default_tty; + + int number_of_errors; + } state_t; + + static void show_splash (state_t *state); + static ply_boot_splash_t *load_built_in_theme (state_t *state); + static ply_boot_splash_t *load_theme (state_t *state, + const char *theme_path); + static ply_boot_splash_t *show_theme (state_t *state, + const char *theme_path); + +-static void attach_splash_to_seats (state_t *state, +- ply_boot_splash_t *splash); ++static void attach_splash_to_devices (state_t *state, ++ ply_boot_splash_t *splash); + static bool attach_to_running_session (state_t *state); + static void detach_from_running_session (state_t *state); + static void on_escape_pressed (state_t *state); + static void dump_details_and_quit_splash (state_t *state); + static void update_display (state_t *state); + + static void on_error_message (ply_buffer_t *debug_buffer, + const void *bytes, + size_t number_of_bytes); + static ply_buffer_t *debug_buffer; + static char *debug_buffer_path = NULL; + static char *pid_file = NULL; + static void toggle_between_splash_and_details (state_t *state); + #ifdef PLY_ENABLE_SYSTEMD_INTEGRATION + static void tell_systemd_to_print_details (state_t *state); + static void tell_systemd_to_stop_printing_details (state_t *state); + #endif + static const char * get_cache_file_for_mode (ply_mode_t mode); + static void on_escape_pressed (state_t *state); + static void on_enter (state_t *state, + const char *line); + static void on_keyboard_input (state_t *state, + const char *keyboard_input, + size_t character_size); + static void on_backspace (state_t *state); + static void on_quit (state_t *state, + bool retain_splash, + ply_trigger_t *quit_trigger); + static bool sh_is_init (state_t *state); + +@@ -486,69 +486,69 @@ show_default_splash (state_t *state) + update_display (state); + } + + static void + cancel_pending_delayed_show (state_t *state) + { + if (isnan (state->splash_delay)) + return; + + ply_event_loop_stop_watching_for_timeout (state->loop, + (ply_event_loop_timeout_handler_t) + show_splash, + state); + state->splash_delay = NAN; + } + + static void + on_ask_for_password (state_t *state, + const char *prompt, + ply_trigger_t *answer) + { + ply_entry_trigger_t *entry_trigger; + + if (state->boot_splash == NULL) + { + /* Waiting to be shown, boot splash will + * arrive shortly so just sit tight + */ + if (state->is_shown) + { +- bool has_open_seats; ++ bool has_displays; + + cancel_pending_delayed_show (state); + +- has_open_seats = ply_device_manager_has_open_seats (state->device_manager); ++ has_displays = ply_device_manager_has_displays (state->device_manager); + +- if (has_open_seats) ++ if (has_displays) + { +- ply_trace ("seats open now, showing splash immediately"); ++ ply_trace ("displays available now, showing splash immediately"); + show_splash (state); + } + else + { + ply_trace ("splash still coming up, waiting a bit"); + } + } + else + { + /* No splash, client will have to get password */ + ply_trace ("no splash loaded, replying immediately with no password"); + ply_trigger_pull (answer, NULL); + return; + } + } + + entry_trigger = calloc (1, sizeof (ply_entry_trigger_t)); + entry_trigger->type = PLY_ENTRY_TRIGGER_TYPE_PASSWORD; + entry_trigger->prompt = prompt; + entry_trigger->trigger = answer; + ply_trace ("queuing password request with boot splash"); + ply_list_append_data (state->entry_triggers, entry_trigger); + update_display (state); + } + + static void + on_ask_question (state_t *state, + const char *prompt, + ply_trigger_t *answer) + { +@@ -873,224 +873,273 @@ plymouth_should_show_default_splash (state_t *state) + { + ply_trace ("no default splash because kernel command line has option \"splash=verbose\""); + return false; + } + + if (command_line_has_argument (state->kernel_command_line, "rhgb")) + { + ply_trace ("using default splash because kernel command line has option \"rhgb\""); + return true; + } + + if (command_line_has_argument (state->kernel_command_line, "splash")) + { + ply_trace ("using default splash because kernel command line has option \"splash\""); + return true; + } + + if (command_line_has_argument (state->kernel_command_line, "splash=silent")) + { + ply_trace ("using default splash because kernel command line has option \"splash=slient\""); + return true; + } + + ply_trace ("no default splash because kernel command line lacks \"splash\" or \"rhgb\""); + return false; + } + + static void + on_show_splash (state_t *state) + { +- bool has_open_seats; ++ bool has_displays; + + if (state->is_shown) + { + ply_trace ("show splash called while already shown"); + return; + } + + if (state->is_inactive) + { + ply_trace ("show splash called while inactive"); + return; + } + + if (plymouth_should_ignore_show_splash_calls (state)) + { + ply_trace ("show splash called while ignoring show splash calls"); + dump_details_and_quit_splash (state); + return; + } + + state->is_shown = true; +- has_open_seats = ply_device_manager_has_open_seats (state->device_manager); ++ has_displays = ply_device_manager_has_displays (state->device_manager); + +- if (!state->is_attached && state->should_be_attached && has_open_seats) ++ if (!state->is_attached && state->should_be_attached && has_displays) + attach_to_running_session (state); + +- if (has_open_seats) ++ if (has_displays) + { +- ply_trace ("at least one seat already open, so loading splash"); ++ ply_trace ("at least one display already available, so loading splash"); + show_splash (state); + } + else + { +- ply_trace ("no seats available to show splash on, waiting..."); ++ ply_trace ("no displays available to show splash on, waiting..."); + } + } + + static void +-on_seat_removed (state_t *state, +- ply_seat_t *seat) +-{ +- ply_keyboard_t *keyboard; +- +- keyboard = ply_seat_get_keyboard (seat); +- +- ply_trace ("no longer listening for keystrokes"); +- ply_keyboard_remove_input_handler (keyboard, +- (ply_keyboard_input_handler_t) +- on_keyboard_input); +- ply_trace ("no longer listening for escape"); +- ply_keyboard_remove_escape_handler (keyboard, +- (ply_keyboard_escape_handler_t) +- on_escape_pressed); +- ply_trace ("no longer listening for backspace"); +- ply_keyboard_remove_backspace_handler (keyboard, +- (ply_keyboard_backspace_handler_t) +- on_backspace); +- ply_trace ("no longer listening for enter"); +- ply_keyboard_remove_enter_handler (keyboard, +- (ply_keyboard_enter_handler_t) +- on_enter); +- +- if (state->boot_splash != NULL) +- ply_boot_splash_detach_from_seat (state->boot_splash, seat); +-} +- +-static void + show_splash (state_t *state) + { + if (state->boot_splash != NULL) + return; + + if (!isnan (state->splash_delay)) + { + double now, running_time; + + now = ply_get_timestamp (); + running_time = now - state->start_time; + if (state->splash_delay > running_time) + { + double time_left = state->splash_delay - running_time; + + ply_trace ("delaying show splash for %lf seconds", + time_left); + ply_event_loop_stop_watching_for_timeout (state->loop, + (ply_event_loop_timeout_handler_t) + show_splash, + state); + ply_event_loop_watch_for_timeout (state->loop, + time_left, + (ply_event_loop_timeout_handler_t) + show_splash, + state); + return; + } + } + + if (plymouth_should_show_default_splash (state)) + { + show_default_splash (state); + state->showing_details = false; + } + else + { + show_detailed_splash (state); + state->showing_details = true; + } + } + + static void +-on_seat_added (state_t *state, +- ply_seat_t *seat) ++on_keyboard_added (state_t *state, ++ ply_keyboard_t *keyboard) + { +- ply_keyboard_t *keyboard; +- +- if (state->is_shown) +- { +- if (state->boot_splash == NULL) +- { +- ply_trace ("seat added before splash loaded, so loading splash now"); +- show_splash (state); +- } +- else +- { +- ply_trace ("seat added after splash loaded, so attaching to splash"); +- ply_boot_splash_attach_to_seat (state->boot_splash, seat); +- } +- } +- +- keyboard = ply_seat_get_keyboard (seat); +- + ply_trace ("listening for keystrokes"); + ply_keyboard_add_input_handler (keyboard, + (ply_keyboard_input_handler_t) + on_keyboard_input, state); + ply_trace ("listening for escape"); + ply_keyboard_add_escape_handler (keyboard, + (ply_keyboard_escape_handler_t) + on_escape_pressed, state); + ply_trace ("listening for backspace"); + ply_keyboard_add_backspace_handler (keyboard, + (ply_keyboard_backspace_handler_t) + on_backspace, state); + ply_trace ("listening for enter"); + ply_keyboard_add_enter_handler (keyboard, + (ply_keyboard_enter_handler_t) + on_enter, state); + ++ if (state->boot_splash != NULL) ++ { ++ ply_trace ("keyboard set after splash loaded, so attaching to splash"); ++ ply_boot_splash_set_keyboard (state->boot_splash, keyboard); ++ } ++} ++ ++static void ++on_keyboard_removed (state_t *state, ++ ply_keyboard_t *keyboard) ++{ ++ ply_trace ("no longer listening for keystrokes"); ++ ply_keyboard_remove_input_handler (keyboard, ++ (ply_keyboard_input_handler_t) ++ on_keyboard_input); ++ ply_trace ("no longer listening for escape"); ++ ply_keyboard_remove_escape_handler (keyboard, ++ (ply_keyboard_escape_handler_t) ++ on_escape_pressed); ++ ply_trace ("no longer listening for backspace"); ++ ply_keyboard_remove_backspace_handler (keyboard, ++ (ply_keyboard_backspace_handler_t) ++ on_backspace); ++ ply_trace ("no longer listening for enter"); ++ ply_keyboard_remove_enter_handler (keyboard, ++ (ply_keyboard_enter_handler_t) ++ on_enter); ++ ++ if (state->boot_splash != NULL) ++ ply_boot_splash_unset_keyboard (state->boot_splash); ++} ++ ++static void ++on_pixel_display_added (state_t *state, ++ ply_pixel_display_t *display) ++{ ++ if (state->is_shown) ++ { ++ if (state->boot_splash == NULL) ++ { ++ ply_trace ("pixel display added before splash loaded, so loading splash now"); ++ show_splash (state); ++ } ++ else ++ { ++ ply_trace ("pixel display added after splash loaded, so attaching to splash"); ++ ply_boot_splash_add_pixel_display (state->boot_splash, display); ++ } ++ } ++} ++ ++static void ++on_pixel_display_removed (state_t *state, ++ ply_pixel_display_t *display) ++{ ++ if (state->boot_splash == NULL) ++ return; ++ ++ ply_boot_splash_remove_pixel_display (state->boot_splash, display); ++} ++ ++static void ++on_text_display_added (state_t *state, ++ ply_text_display_t *display) ++{ ++ if (state->is_shown) ++ { ++ if (state->boot_splash == NULL) ++ { ++ ply_trace ("text display added before splash loaded, so loading splash now"); ++ show_splash (state); ++ } ++ else ++ { ++ ply_trace ("text display added after splash loaded, so attaching to splash"); ++ ply_boot_splash_add_text_display (state->boot_splash, display); ++ } ++ } ++} ++ ++static void ++on_text_display_removed (state_t *state, ++ ply_text_display_t *display) ++{ ++ if (state->boot_splash == NULL) ++ return; ++ ++ ply_boot_splash_remove_text_display (state->boot_splash, display); + } + + static void + load_devices (state_t *state, + ply_device_manager_flags_t flags) + { + state->device_manager = ply_device_manager_new (state->default_tty, flags); + state->local_console_terminal = ply_device_manager_get_default_terminal (state->device_manager); + +- ply_device_manager_watch_seats (state->device_manager, +- (ply_seat_added_handler_t) +- on_seat_added, +- (ply_seat_removed_handler_t) +- on_seat_removed, +- state); ++ ply_device_manager_watch_devices (state->device_manager, ++ (ply_keyboard_added_handler_t) ++ on_keyboard_added, ++ (ply_keyboard_removed_handler_t) ++ on_keyboard_removed, ++ (ply_pixel_display_added_handler_t) ++ on_pixel_display_added, ++ (ply_pixel_display_removed_handler_t) ++ on_pixel_display_removed, ++ (ply_text_display_added_handler_t) ++ on_text_display_added, ++ (ply_text_display_removed_handler_t) ++ on_text_display_removed, ++ state); + } + + static void + quit_splash (state_t *state) + { + ply_trace ("quiting splash"); + if (state->boot_splash != NULL) + { + ply_trace ("freeing splash"); + ply_boot_splash_free (state->boot_splash); + state->boot_splash = NULL; + } + + ply_device_manager_deactivate_keyboards (state->device_manager); + + if (state->local_console_terminal != NULL) + { + if (!state->should_retain_splash) + { + ply_trace ("Not retaining splash, so deallocating VT"); + ply_terminal_deactivate_vt (state->local_console_terminal); + ply_terminal_close (state->local_console_terminal); + } + } + + detach_from_running_session (state); + } + + static void + hide_splash (state_t *state) +@@ -1548,78 +1597,110 @@ on_enter (state_t *state, + node = ply_list_get_first_node (state->entry_triggers); + if (node) + { + ply_entry_trigger_t* entry_trigger = ply_list_node_get_data (node); + const char* reply_text = ply_buffer_get_bytes (state->entry_buffer); + ply_trigger_pull (entry_trigger->trigger, reply_text); + ply_buffer_clear (state->entry_buffer); + ply_list_remove_node (state->entry_triggers, node); + free (entry_trigger); + update_display (state); + } + else + { + for (node = ply_list_get_first_node (state->keystroke_triggers); node; + node = ply_list_get_next_node (state->keystroke_triggers, node)) + { + ply_keystroke_watch_t* keystroke_trigger = ply_list_node_get_data (node); + if (!keystroke_trigger->keys || strstr(keystroke_trigger->keys, "\n")) /* assume strstr works on utf8 arrays */ + { + ply_trigger_pull (keystroke_trigger->trigger, line); + ply_list_remove_node (state->keystroke_triggers, node); + free(keystroke_trigger); + return; + } + } + return; + } + } + + static void +-attach_splash_to_seats (state_t *state, +- ply_boot_splash_t *splash) ++attach_splash_to_devices (state_t *state, ++ ply_boot_splash_t *splash) + { + +- ply_list_t *seats; ++ ply_list_t *keyboards; ++ ply_list_t *pixel_displays; ++ ply_list_t *text_displays; + ply_list_node_t *node; + +- seats = ply_device_manager_get_seats (state->device_manager); +- node = ply_list_get_first_node (seats); ++ keyboards = ply_device_manager_get_keyboards (state->device_manager); ++ node = ply_list_get_first_node (keyboards); ++ while (node != NULL) ++ { ++ ply_keyboard_t *keyboard; ++ ply_list_node_t *next_node; ++ ++ keyboard = ply_list_node_get_data (node); ++ next_node = ply_list_get_next_node (keyboards, node); ++ ++ ply_boot_splash_set_keyboard (splash, keyboard); ++ ++ node = next_node; ++ } ++ ++ pixel_displays = ply_device_manager_get_pixel_displays (state->device_manager); ++ node = ply_list_get_first_node (pixel_displays); ++ while (node != NULL) ++ { ++ ply_pixel_display_t *pixel_display; ++ ply_list_node_t *next_node; ++ ++ pixel_display = ply_list_node_get_data (node); ++ next_node = ply_list_get_next_node (pixel_displays, node); ++ ++ ply_boot_splash_add_pixel_display (splash, pixel_display); ++ ++ node = next_node; ++ } ++ ++ text_displays = ply_device_manager_get_text_displays (state->device_manager); ++ node = ply_list_get_first_node (text_displays); + while (node != NULL) + { +- ply_seat_t *seat; ++ ply_text_display_t *text_display; + ply_list_node_t *next_node; + +- seat = ply_list_node_get_data (node); +- next_node = ply_list_get_next_node (seats, node); ++ text_display = ply_list_node_get_data (node); ++ next_node = ply_list_get_next_node (text_displays, node); + +- ply_boot_splash_attach_to_seat (splash, seat); ++ ply_boot_splash_add_text_display (splash, text_display); + + node = next_node; + } + } + + #ifdef PLY_ENABLE_SYSTEMD_INTEGRATION + static void + tell_systemd_to_print_details (state_t *state) + { + ply_trace ("telling systemd to start printing details"); + if (kill (1, SIGRTMIN + 20) < 0) + ply_trace ("could not tell systemd to print details: %m"); + } + + static void + tell_systemd_to_stop_printing_details (state_t *state) + { + ply_trace ("telling systemd to stop printing details"); + if (kill (1, SIGRTMIN + 21) < 0) + ply_trace ("could not tell systemd to stop printing details: %m"); + } + #endif + + static ply_boot_splash_t * + load_built_in_theme (state_t *state) + { + ply_boot_splash_t *splash; + bool is_loaded; + + ply_trace ("Loading built-in theme"); +@@ -1668,61 +1749,61 @@ load_theme (state_t *state, + ply_save_errno (); + ply_boot_splash_free (splash); + ply_restore_errno (); + return NULL; + } + + ply_trace ("attaching plugin to event loop"); + ply_boot_splash_attach_to_event_loop (splash, state->loop); + + ply_trace ("attaching progress to plugin"); + ply_boot_splash_attach_progress (splash, state->progress); + + return splash; + } + + static ply_boot_splash_t * + show_theme (state_t *state, + const char *theme_path) + { + ply_boot_splash_mode_t splash_mode; + ply_boot_splash_t *splash; + + if (theme_path != NULL) + splash = load_theme (state, theme_path); + else + splash = load_built_in_theme (state); + + if (splash == NULL) + return NULL; + +- attach_splash_to_seats (state, splash); ++ attach_splash_to_devices (state, splash); + ply_device_manager_activate_renderers (state->device_manager); + + if (state->mode == PLY_MODE_SHUTDOWN) + splash_mode = PLY_BOOT_SPLASH_MODE_SHUTDOWN; + else + splash_mode = PLY_BOOT_SPLASH_MODE_BOOT_UP; + + if (!ply_boot_splash_show (splash, splash_mode)) + { + ply_save_errno (); + ply_boot_splash_free (splash); + ply_restore_errno (); + return NULL; + } + + #ifdef PLY_ENABLE_SYSTEMD_INTEGRATION + if (state->is_attached) + tell_systemd_to_print_details (state); + #endif + + ply_device_manager_activate_keyboards (state->device_manager); + show_messages (state); + + return splash; + } + + static bool + attach_to_running_session (state_t *state) + { + ply_terminal_session_t *session; +-- +2.3.7 + + +From 8ae7a1af26bfdd367c2a926a0050e03db5dfb87e Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 24 Jul 2015 14:12:40 -0400 +Subject: [PATCH 5/8] device-manager: decouple local console from output device + +The code currently does a faulty heuristic to figure out which +drm device is associated with the tty. We shouldn't actually +even need an accurate association, so this commit just makes +sure the terminal gets used for the first device. +--- + src/libply-splash-core/ply-device-manager.c | 73 +++++++++-------------------- + 1 file changed, 21 insertions(+), 52 deletions(-) + +diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c +index c7568c1..b90a0f6 100644 +--- a/src/libply-splash-core/ply-device-manager.c ++++ b/src/libply-splash-core/ply-device-manager.c +@@ -70,87 +70,60 @@ struct _ply_device_manager + void *event_handler_data; + + uint32_t local_console_managed : 1; + uint32_t local_console_is_text : 1; + }; + + 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 bool + drm_device_in_use (ply_device_manager_t *manager, + const char *device_path) + { + ply_renderer_t *renderer; + + renderer = ply_hashtable_lookup (manager->renderers, (void *) device_path); + + return renderer != NULL; + } + + static bool + fb_device_has_drm_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; + bool has_drm_device = false; + + /* 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); + + ply_trace ("trying to find associated drm node for fb device (path: %s)", id_path); + +@@ -162,104 +135,105 @@ fb_device_has_drm_device (ply_device_manager_t *manager, + + 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 && drm_device_in_use (manager, card_node)) + has_drm_device = true; + else + ply_trace ("no card node!"); + + udev_device_unref (card_device); + } + else + { + ply_trace ("no card entry!"); + } + + udev_enumerate_unref (card_matches); + return has_drm_device; + } + + static void + create_devices_for_udev_device (ply_device_manager_t *manager, + struct udev_device *device) + { +- bool for_local_console; + const char *device_path; +- ply_terminal_t *terminal = NULL; +- +- for_local_console = device_is_for_local_console (manager, device); +- +- ply_trace ("device is for local console: %s", for_local_console? "yes" : "no"); +- +- if (for_local_console) +- terminal = manager->local_console_terminal; + + device_path = udev_device_get_devnode (device); + + if (device_path != NULL) + { + const char *subsystem; ++ + ply_renderer_type_t renderer_type = PLY_RENDERER_TYPE_NONE; + + subsystem = udev_device_get_subsystem (device); + ply_trace ("device subsystem is %s", subsystem); + + if (subsystem != NULL && strcmp (subsystem, SUBSYSTEM_DRM) == 0) + { + ply_trace ("found DRM device %s", device_path); + renderer_type = PLY_RENDERER_TYPE_DRM; + } + else if (strcmp (subsystem, SUBSYSTEM_FRAME_BUFFER) == 0) + { + ply_trace ("found frame buffer device %s", device_path); + if (!fb_device_has_drm_device (manager, device)) + { + renderer_type = PLY_RENDERER_TYPE_FRAME_BUFFER; + } + else + { + ply_trace ("ignoring, since there's a DRM device associated with it"); + } + } + + if (renderer_type != PLY_RENDERER_TYPE_NONE) +- create_devices_for_terminal_and_renderer_type (manager, +- device_path, +- terminal, +- renderer_type); ++ { ++ ply_terminal_t *terminal = NULL; ++ ++ if (!manager->local_console_managed) ++ { ++ terminal = manager->local_console_terminal; ++ } ++ ++ create_devices_for_terminal_and_renderer_type (manager, ++ device_path, ++ terminal, ++ renderer_type); ++ } + } + } + + static void + free_displays_for_renderer (ply_device_manager_t *manager, + ply_renderer_t *renderer) + { + ply_list_node_t *node; + + node = ply_list_get_first_node (manager->pixel_displays); + while (node != NULL) + { + ply_list_node_t *next_node; + ply_pixel_display_t *display; + ply_renderer_t *display_renderer; + + display = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (manager->pixel_displays, node); + display_renderer = ply_pixel_display_get_renderer (display); + + if (display_renderer == renderer) + { + if (manager->pixel_display_removed_handler != NULL) + manager->pixel_display_removed_handler (manager->event_handler_data, display); + + ply_pixel_display_free (display); + ply_list_remove_node (manager->pixel_displays, node); + } + + node = next_node; +@@ -687,126 +661,121 @@ create_text_displays_for_terminal (ply_device_manager_t *manager, + + if (!ply_terminal_is_open (terminal)) + { + if (!ply_terminal_open (terminal)) + { + ply_trace ("could not add terminal %s: %m", + ply_terminal_get_name (terminal)); + return; + } + } + + ply_trace ("adding text display for terminal %s", + ply_terminal_get_name (terminal)); + + display = ply_text_display_new (terminal); + ply_list_append_data (manager->text_displays, display); + + if (manager->text_display_added_handler != NULL) + manager->text_display_added_handler (manager->event_handler_data, display); + } + + static void + create_devices_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_renderer_t *renderer = NULL; + ply_keyboard_t *keyboard = NULL; + +- bool is_local_terminal = false; +- +- if (terminal != NULL && manager->local_console_terminal == terminal) +- is_local_terminal = true; ++ renderer = ply_hashtable_lookup (manager->renderers, (void *) device_path); + +- if (is_local_terminal && manager->local_console_managed) ++ if (renderer != NULL) + { +- ply_trace ("trying to create devices for local console when one already exists"); ++ ply_trace ("ignoring device %s since it's already managed", ++ device_path); + return; + } + + ply_trace ("creating devices for %s (renderer type: %u) (terminal: %s)", + device_path? : "", renderer_type, terminal? ply_terminal_get_name (terminal): "none"); + + if (renderer_type != PLY_RENDERER_TYPE_NONE) + { + renderer = ply_renderer_new (renderer_type, device_path, terminal); + + if (!ply_renderer_open (renderer)) + { + ply_trace ("could not open renderer for %s", device_path); + ply_renderer_free (renderer); + renderer = NULL; + if (renderer_type != PLY_RENDERER_TYPE_AUTO) + return; + } + } + + if (renderer != NULL) + { + keyboard = ply_keyboard_new_for_renderer (renderer); + ply_list_append_data (manager->keyboards, keyboard); + + if (manager->keyboard_added_handler != NULL) + manager->keyboard_added_handler (manager->event_handler_data, keyboard); + + create_pixel_displays_for_renderer (manager, renderer); + ply_hashtable_insert (manager->renderers, strdup (device_path), renderer); + } + else if (terminal != NULL) + { + keyboard = ply_keyboard_new_for_terminal (terminal); + ply_list_append_data (manager->keyboards, keyboard); + + if (manager->keyboard_added_handler != NULL) + manager->keyboard_added_handler (manager->event_handler_data, keyboard); + } + + if (terminal != NULL) + { + create_text_displays_for_terminal (manager, terminal); + +- if (is_local_terminal) ++ if (terminal == manager->local_console_terminal) + { +- manager->local_console_is_text = true; ++ manager->local_console_is_text = renderer == NULL; ++ manager->local_console_managed = true; + } + } + + if (keyboard != NULL) + { + ply_keyboard_watch_for_input (keyboard); + } +- +- if (is_local_terminal) +- manager->local_console_managed = true; +- + } + + static void + create_devices_for_terminal (const char *device_path, + ply_terminal_t *terminal, + ply_device_manager_t *manager) + { + create_devices_for_terminal_and_renderer_type (manager, + device_path, + terminal, + PLY_RENDERER_TYPE_NONE); + } + static bool + create_devices_from_terminals (ply_device_manager_t *manager) + { + bool has_serial_consoles; + + ply_trace ("checking for consoles"); + + if (manager->flags & PLY_DEVICE_MANAGER_FLAGS_IGNORE_SERIAL_CONSOLES) + { + has_serial_consoles = false; + ply_trace ("ignoring all consoles but default console because explicitly told to."); + } + else + { + has_serial_consoles = add_consoles_from_file (manager, "/sys/class/tty/console/active"); + } + + if (has_serial_consoles) +-- +2.3.7 + + +From 595557cfde30b99fc9d1789b305c2f80a576c502 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 24 Jul 2015 16:23:00 -0400 +Subject: [PATCH 6/8] device-manager: force details if serial consoles are used + +it's better to skip trying to load the default splash rather than +relying on it failing and falling back. +--- + src/libply-splash-core/ply-device-manager.c | 9 +++++++++ + src/libply-splash-core/ply-device-manager.h | 1 + + src/main.c | 3 +++ + 3 files changed, 13 insertions(+) + +diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c +index b90a0f6..787e67c 100644 +--- a/src/libply-splash-core/ply-device-manager.c ++++ b/src/libply-splash-core/ply-device-manager.c +@@ -44,60 +44,61 @@ + static void create_devices_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_hashtable_t *renderers; + ply_terminal_t *local_console_terminal; + ply_list_t *keyboards; + ply_list_t *text_displays; + ply_list_t *pixel_displays; + struct udev *udev_context; + struct udev_queue *udev_queue; + int udev_queue_fd; + ply_fd_watch_t *udev_queue_fd_watch; + struct udev_monitor *udev_monitor; + + ply_keyboard_added_handler_t keyboard_added_handler; + ply_keyboard_removed_handler_t keyboard_removed_handler; + ply_pixel_display_added_handler_t pixel_display_added_handler; + ply_pixel_display_removed_handler_t pixel_display_removed_handler; + ply_text_display_added_handler_t text_display_added_handler; + ply_text_display_removed_handler_t text_display_removed_handler; + void *event_handler_data; + + uint32_t local_console_managed : 1; + uint32_t local_console_is_text : 1; ++ uint32_t serial_consoles_detected : 1; + }; + + 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 + drm_device_in_use (ply_device_manager_t *manager, + const char *device_path) + { + ply_renderer_t *renderer; +@@ -754,60 +755,62 @@ create_devices_for_terminal_and_renderer_type (ply_device_manager_t *manager, + static void + create_devices_for_terminal (const char *device_path, + ply_terminal_t *terminal, + ply_device_manager_t *manager) + { + create_devices_for_terminal_and_renderer_type (manager, + device_path, + terminal, + PLY_RENDERER_TYPE_NONE); + } + static bool + create_devices_from_terminals (ply_device_manager_t *manager) + { + bool has_serial_consoles; + + ply_trace ("checking for consoles"); + + if (manager->flags & PLY_DEVICE_MANAGER_FLAGS_IGNORE_SERIAL_CONSOLES) + { + has_serial_consoles = false; + ply_trace ("ignoring all consoles but default console because explicitly told to."); + } + else + { + has_serial_consoles = add_consoles_from_file (manager, "/sys/class/tty/console/active"); + } + + if (has_serial_consoles) + { + ply_trace ("serial consoles detected, managing them with details forced"); ++ manager->serial_consoles_detected = true; ++ + ply_hashtable_foreach (manager->terminals, + (ply_hashtable_foreach_func_t *) + create_devices_for_terminal, + manager); + return true; + } + + return false; + } + + static void + create_devices_from_udev (ply_device_manager_t *manager) + { + bool found_drm_device, found_fb_device; + + ply_trace ("Looking for devices from udev"); + + found_drm_device = create_devices_for_subsystem (manager, SUBSYSTEM_DRM); + found_fb_device = create_devices_for_subsystem (manager, SUBSYSTEM_FRAME_BUFFER); + + if (found_drm_device || found_fb_device) + return; + + ply_trace ("Creating non-graphical devices, since there's no suitable graphics hardware"); + create_devices_for_terminal_and_renderer_type (manager, + ply_terminal_get_name (manager->local_console_terminal), + manager->local_console_terminal, + PLY_RENDERER_TYPE_NONE); + } + +@@ -921,60 +924,66 @@ bool + ply_device_manager_has_displays (ply_device_manager_t *manager) + { + return ply_list_get_length (manager->pixel_displays) > 0 || + ply_list_get_length (manager->text_displays) > 0; + } + + ply_list_t * + ply_device_manager_get_keyboards (ply_device_manager_t *manager) + { + return manager->keyboards; + } + + ply_list_t * + ply_device_manager_get_pixel_displays (ply_device_manager_t *manager) + { + return manager->pixel_displays; + } + + ply_list_t * + ply_device_manager_get_text_displays (ply_device_manager_t *manager) + { + return manager->text_displays; + } + + ply_terminal_t * + ply_device_manager_get_default_terminal (ply_device_manager_t *manager) + { + return manager->local_console_terminal; + } + ++bool ++ply_device_manager_has_serial_consoles (ply_device_manager_t *manager) ++{ ++ return manager->serial_consoles_detected; ++} ++ + static void + activate_renderer (char *device_path, + ply_renderer_t *renderer, + ply_device_manager_t *manager) + { + ply_renderer_activate (renderer); + } + + void + ply_device_manager_activate_renderers (ply_device_manager_t *manager) + { + ply_trace ("activating renderers"); + ply_hashtable_foreach (manager->renderers, + (ply_hashtable_foreach_func_t *) + activate_renderer, + manager); + } + + static void + deactivate_renderer (char *device_path, + ply_renderer_t *renderer, + ply_device_manager_t *manager) + { + ply_renderer_deactivate (renderer); + } + + void + ply_device_manager_deactivate_renderers (ply_device_manager_t *manager) + { + ply_trace ("deactivating renderers"); +diff --git a/src/libply-splash-core/ply-device-manager.h b/src/libply-splash-core/ply-device-manager.h +index b628e41..558aabe 100644 +--- a/src/libply-splash-core/ply-device-manager.h ++++ b/src/libply-splash-core/ply-device-manager.h +@@ -26,45 +26,46 @@ + #include "ply-pixel-display.h" + #include "ply-renderer.h" + #include "ply-text-display.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_keyboard_added_handler_t) (void *, ply_keyboard_t *); + typedef void (* ply_keyboard_removed_handler_t) (void *, ply_keyboard_t *); + typedef void (* ply_pixel_display_added_handler_t) (void *, ply_pixel_display_t *); + typedef void (* ply_pixel_display_removed_handler_t) (void *, ply_pixel_display_t *); + typedef void (* ply_text_display_added_handler_t) (void *, ply_text_display_t *); + typedef void (* ply_text_display_removed_handler_t) (void *, ply_text_display_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_devices (ply_device_manager_t *manager, + ply_keyboard_added_handler_t keyboard_added_handler, + ply_keyboard_removed_handler_t keyboard_removed_handler, + ply_pixel_display_added_handler_t pixel_display_added_handler, + ply_pixel_display_removed_handler_t pixel_display_removed_handler, + ply_text_display_added_handler_t text_display_added_handler, + ply_text_display_removed_handler_t text_display_removed_handler, + void *data); ++bool ply_device_manager_has_serial_consoles (ply_device_manager_t *manager); + bool ply_device_manager_has_displays (ply_device_manager_t *manager); + ply_list_t *ply_device_manager_get_keyboards (ply_device_manager_t *manager); + ply_list_t *ply_device_manager_get_pixel_displays (ply_device_manager_t *manager); + ply_list_t *ply_device_manager_get_text_displays (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: */ +diff --git a/src/main.c b/src/main.c +index ec46199..875dd1a 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -1086,60 +1086,63 @@ static void + on_text_display_removed (state_t *state, + ply_text_display_t *display) + { + if (state->boot_splash == NULL) + return; + + ply_boot_splash_remove_text_display (state->boot_splash, display); + } + + static void + load_devices (state_t *state, + ply_device_manager_flags_t flags) + { + state->device_manager = ply_device_manager_new (state->default_tty, flags); + state->local_console_terminal = ply_device_manager_get_default_terminal (state->device_manager); + + ply_device_manager_watch_devices (state->device_manager, + (ply_keyboard_added_handler_t) + on_keyboard_added, + (ply_keyboard_removed_handler_t) + on_keyboard_removed, + (ply_pixel_display_added_handler_t) + on_pixel_display_added, + (ply_pixel_display_removed_handler_t) + on_pixel_display_removed, + (ply_text_display_added_handler_t) + on_text_display_added, + (ply_text_display_removed_handler_t) + on_text_display_removed, + state); ++ ++ if (ply_device_manager_has_serial_consoles (state->device_manager)) ++ state->should_force_details = true; + } + + static void + quit_splash (state_t *state) + { + ply_trace ("quiting splash"); + if (state->boot_splash != NULL) + { + ply_trace ("freeing splash"); + ply_boot_splash_free (state->boot_splash); + state->boot_splash = NULL; + } + + ply_device_manager_deactivate_keyboards (state->device_manager); + + if (state->local_console_terminal != NULL) + { + if (!state->should_retain_splash) + { + ply_trace ("Not retaining splash, so deallocating VT"); + ply_terminal_deactivate_vt (state->local_console_terminal); + ply_terminal_close (state->local_console_terminal); + } + } + + detach_from_running_session (state); + } + + static void + hide_splash (state_t *state) +-- +2.3.7 + + +From 6c06eb9a42df75b637b7390ef60e06a3f6c7965c Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Tue, 28 Jul 2015 10:00:25 -0400 +Subject: [PATCH 7/8] animation,throbber: allow calling stop after animation is + stopped + +Right now if a user calls ply_throbber_stop or ply_animation_stop +after the animation is stopped things malfunction. In the case +of the throbber we end up never calling the stop completion handler +passed in, and in the case of the animation, we end up setting +some state that shouldn't be set. + +This commit checks if the animation and throbber objects are stopped, +and if so does the necessary steps to process the late stop request. +--- + src/libply-splash-graphics/ply-animation.c | 6 ++++++ + src/libply-splash-graphics/ply-throbber.c | 10 ++++++++++ + 2 files changed, 16 insertions(+) + +diff --git a/src/libply-splash-graphics/ply-animation.c b/src/libply-splash-graphics/ply-animation.c +index bba8490..2f24812 100644 +--- a/src/libply-splash-graphics/ply-animation.c ++++ b/src/libply-splash-graphics/ply-animation.c +@@ -348,60 +348,66 @@ ply_animation_start (ply_animation_t *animation, + + ply_event_loop_watch_for_timeout (animation->loop, + 1.0 / FRAMES_PER_SECOND, + (ply_event_loop_timeout_handler_t) + on_timeout, animation); + + return true; + } + + static void + ply_animation_stop_now (ply_animation_t *animation) + { + animation->is_stopped = true; + + ply_trace ("stopping animation now"); + + if (animation->loop != NULL) + { + ply_event_loop_stop_watching_for_timeout (animation->loop, + (ply_event_loop_timeout_handler_t) + on_timeout, animation); + animation->loop = NULL; + } + + animation->display = NULL; + } + + void + ply_animation_stop (ply_animation_t *animation) + { ++ if (animation->is_stopped) ++ { ++ ply_trace ("animation already stopped, ignoring stop request"); ++ return; ++ } ++ + if (animation->stop_trigger == NULL) + { + ply_animation_stop_now (animation); + return; + } + + ply_trace ("stopping animation next time through the loop"); + animation->stop_requested = true; + } + + bool + ply_animation_is_stopped (ply_animation_t *animation) + { + return animation->is_stopped; + } + + void + ply_animation_draw_area (ply_animation_t *animation, + ply_pixel_buffer_t *buffer, + long x, + long y, + unsigned long width, + unsigned long height) + { + ply_pixel_buffer_t * const * frames; + int number_of_frames; + int frame_index; + + if (animation->is_stopped) + return; +diff --git a/src/libply-splash-graphics/ply-throbber.c b/src/libply-splash-graphics/ply-throbber.c +index 42044ba..d4594b8 100644 +--- a/src/libply-splash-graphics/ply-throbber.c ++++ b/src/libply-splash-graphics/ply-throbber.c +@@ -320,60 +320,70 @@ ply_throbber_start (ply_throbber_t *throbber, + (ply_event_loop_timeout_handler_t) + on_timeout, throbber); + + return true; + } + + static void + ply_throbber_stop_now (ply_throbber_t *throbber) + { + throbber->is_stopped = true; + + ply_pixel_display_draw_area (throbber->display, + throbber->x, + throbber->y, + throbber->frame_area.width, + throbber->frame_area.height); + if (throbber->loop != NULL) + { + ply_event_loop_stop_watching_for_timeout (throbber->loop, + (ply_event_loop_timeout_handler_t) + on_timeout, throbber); + throbber->loop = NULL; + } + throbber->display = NULL; + } + + void + ply_throbber_stop (ply_throbber_t *throbber, + ply_trigger_t *stop_trigger) + { ++ if (throbber->is_stopped) ++ { ++ ply_trace ("throbber already stopped"); ++ if (stop_trigger != NULL) ++ { ++ ply_trace ("pulling stop trigger right away"); ++ ply_trigger_pull (stop_trigger, NULL); ++ } ++ return; ++ } + + if (stop_trigger == NULL) + { + ply_throbber_stop_now (throbber); + return; + } + + throbber->stop_trigger = stop_trigger; + } + + bool + ply_throbber_is_stopped (ply_throbber_t *throbber) + { + return throbber->is_stopped; + } + + void + ply_throbber_draw_area (ply_throbber_t *throbber, + ply_pixel_buffer_t *buffer, + long x, + long y, + unsigned long width, + unsigned long height) + { + ply_pixel_buffer_t * const * frames; + + if (throbber->is_stopped) + return; + + frames = (ply_pixel_buffer_t * const *) ply_array_get_pointer_elements (throbber->frames); +-- +2.3.7 + +From 80e71304093c163e338168d27bfdb3552c9aa242 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 10 Aug 2015 10:11:32 -0400 +Subject: [PATCH 8/8] boot-splash: don't crash in free if module not loaded + +ply_boot_splash_free currently calls some code that depends +on a module being loaded. We call ply_boot_splash_free to +clean up the boot splash object if a module can't be loaded, +leading to crash. + +This commit addresses that issue by only calling the module +specific destruction code in ply_boot_splash_free in the case +where a module is loaded. + +https://bugs.freedesktop.org/show_bug.cgi?id=91590 +--- + src/libply-splash-core/ply-boot-splash.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/src/libply-splash-core/ply-boot-splash.c b/src/libply-splash-core/ply-boot-splash.c +index f7fc70f..664acc3 100644 +--- a/src/libply-splash-core/ply-boot-splash.c ++++ b/src/libply-splash-core/ply-boot-splash.c +@@ -383,70 +383,72 @@ remove_text_displays (ply_boot_splash_t *splash) + + ply_trace ("Removing %dx%d text display", number_of_columns, number_of_rows); + + splash->plugin_interface->remove_text_display (splash->plugin, display); + + node = next_node; + } + } + + void + ply_boot_splash_free (ply_boot_splash_t *splash) + { + ply_trace ("freeing splash"); + if (splash == NULL) + return; + + if (splash->loop != NULL) + { + if (splash->plugin_interface->on_boot_progress != NULL) + { + ply_event_loop_stop_watching_for_timeout (splash->loop, + (ply_event_loop_timeout_handler_t) + ply_boot_splash_update_progress, splash); + } + + ply_event_loop_stop_watching_for_exit (splash->loop, (ply_event_loop_exit_handler_t) + ply_boot_splash_detach_from_event_loop, + splash); + } + +- ply_boot_splash_unset_keyboard (splash); ++ if (splash->module_handle != NULL) ++ { ++ ply_boot_splash_unset_keyboard (splash); + +- remove_pixel_displays (splash); +- ply_list_free (splash->pixel_displays); ++ remove_pixel_displays (splash); ++ ply_list_free (splash->pixel_displays); + +- remove_text_displays (splash); +- ply_list_free (splash->text_displays); ++ remove_text_displays (splash); ++ ply_list_free (splash->text_displays); + +- if (splash->module_handle != NULL) +- ply_boot_splash_unload (splash); ++ ply_boot_splash_unload (splash); ++ } + + if (splash->idle_trigger != NULL) + ply_trigger_free (splash->idle_trigger); + + free (splash->theme_path); + free (splash->plugin_dir); + free (splash); + } + + static void + ply_boot_splash_update_progress (ply_boot_splash_t *splash) + { + double percentage=0.0; + double time=0.0; + + assert (splash != NULL); + + if (splash->progress) + { + percentage = ply_progress_get_percentage(splash->progress); + time = ply_progress_get_time(splash->progress); + } + + if (splash->plugin_interface->on_boot_progress != NULL) + splash->plugin_interface->on_boot_progress (splash->plugin, + time, + percentage); + + ply_event_loop_watch_for_timeout (splash->loop, + 1.0 / UPDATES_PER_SECOND, +-- +2.5.0 + diff --git a/SOURCES/fix-ask-password-race.patch b/SOURCES/fix-ask-password-race.patch new file mode 100644 index 0000000..0bc8658 --- /dev/null +++ b/SOURCES/fix-ask-password-race.patch @@ -0,0 +1,211 @@ +From e0e098f6b1240979f7da473f8966cd8043bce576 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 6 Mar 2014 10:02:21 -0500 +Subject: [PATCH] main: call update_display when splash is shown + +we need to call update display any time a splash is shown, +because there may be a pending password request. + +The code attempted to do this in show_splash, but did it before +the splash was assigned to running state, so function was a noop. + +This commit moves it a little later in code after the splash is +properly assigned. +--- + src/main.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/main.c b/src/main.c +index ccb8b63..fb91bf2 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -294,60 +294,61 @@ load_settings (state_t *state, + ply_trace ("Splash delay is set to %lf", state->splash_delay); + state->splash_delay = atof (delay_string); + } + } + + settings_loaded = true; + out: + ply_key_file_free (key_file); + + return settings_loaded; + } + + static void + show_detailed_splash (state_t *state) + { + ply_boot_splash_t *splash; + + if (state->boot_splash != NULL) + return; + + ply_trace ("Showing detailed splash screen"); + splash = show_theme (state, NULL); + + if (splash == NULL) + { + ply_trace ("Could not start detailed splash screen, this could be a problem."); + return; + } + + state->boot_splash = splash; ++ update_display (state); + } + + static const char * + command_line_get_string_after_prefix (const char *command_line, + const char *prefix) + { + char *argument; + + argument = strstr (command_line, prefix); + + if (argument == NULL) + return NULL; + + if (argument == command_line || + argument[-1] == ' ') + return argument + strlen (prefix); + + return NULL; + } + + static bool + command_line_has_argument (const char *command_line, + const char *argument) + { + const char *string; + + string = command_line_get_string_after_prefix (command_line, argument); + + if (string == NULL) + return false; +@@ -450,60 +451,62 @@ show_default_splash (state_t *state) + { + ply_trace ("Trying distribution default splash"); + state->boot_splash = show_theme (state, state->distribution_default_splash_path); + } + + if (state->boot_splash == NULL) + { + ply_trace ("Trying old scheme for default splash"); + state->boot_splash = show_theme (state, PLYMOUTH_THEME_PATH "default.plymouth"); + } + + if (state->boot_splash == NULL) + { + ply_trace ("Could not start default splash screen," + "showing text splash screen"); + state->boot_splash = show_theme (state, PLYMOUTH_THEME_PATH "text/text.plymouth"); + } + + if (state->boot_splash == NULL) + { + ply_trace ("Could not start text splash screen," + "showing built-in splash screen"); + state->boot_splash = show_theme (state, NULL); + } + + if (state->boot_splash == NULL) + { + ply_error ("plymouthd: could not start boot splash: %m"); + return; + } ++ ++ update_display (state); + } + + static void + cancel_pending_delayed_show (state_t *state) + { + if (isnan (state->splash_delay)) + return; + + ply_event_loop_stop_watching_for_timeout (state->loop, + (ply_event_loop_timeout_handler_t) + show_splash, + state); + state->splash_delay = NAN; + } + + static void + on_ask_for_password (state_t *state, + const char *prompt, + ply_trigger_t *answer) + { + ply_entry_trigger_t *entry_trigger; + + if (state->boot_splash == NULL) + { + /* Waiting to be shown, boot splash will + * arrive shortly so just sit tight + */ + if (state->is_shown) + { + bool has_open_seats; +@@ -1671,61 +1674,60 @@ show_theme (state_t *state, + splash = load_theme (state, theme_path); + else + splash = load_built_in_theme (state); + + if (splash == NULL) + return NULL; + + attach_splash_to_seats (state, splash); + ply_device_manager_activate_renderers (state->device_manager); + + if (state->mode == PLY_MODE_SHUTDOWN) + splash_mode = PLY_BOOT_SPLASH_MODE_SHUTDOWN; + else + splash_mode = PLY_BOOT_SPLASH_MODE_BOOT_UP; + + if (!ply_boot_splash_show (splash, splash_mode)) + { + ply_save_errno (); + ply_boot_splash_free (splash); + ply_restore_errno (); + return NULL; + } + + #ifdef PLY_ENABLE_SYSTEMD_INTEGRATION + if (state->is_attached) + tell_systemd_to_print_details (state); + #endif + + ply_device_manager_activate_keyboards (state->device_manager); + show_messages (state); +- update_display (state); + + return splash; + } + + static bool + attach_to_running_session (state_t *state) + { + ply_terminal_session_t *session; + ply_terminal_session_flags_t flags; + bool should_be_redirected; + + flags = 0; + + should_be_redirected = !state->no_boot_log; + + if (should_be_redirected) + flags |= PLY_TERMINAL_SESSION_FLAGS_REDIRECT_CONSOLE; + + if (state->session == NULL) + { + ply_trace ("creating new terminal session"); + session = ply_terminal_session_new (NULL); + + ply_terminal_session_attach_to_event_loop (session, state->loop); + } + else + { + session = state->session; + ply_trace ("session already created"); + } +-- +1.8.3.1 + diff --git a/SOURCES/fix-coldplug-detection.patch b/SOURCES/fix-coldplug-detection.patch new file mode 100644 index 0000000..162c816 --- /dev/null +++ b/SOURCES/fix-coldplug-detection.patch @@ -0,0 +1,81 @@ +From 3d38bbb09383a634c78722c7bf18a3e1a3f36647 Mon Sep 17 00:00:00 2001 +From: Frederic Crozat +Date: Thu, 19 Jun 2014 17:58:50 +0200 +Subject: [PATCH] libply-splash-core: also monitor for file removal in udev + directory + +Ensure plymouth detects coldplug completion with recent udev (>= 213). +--- + src/libply-splash-core/ply-device-manager.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c +index a7890d0..5766bcb 100644 +--- a/src/libply-splash-core/ply-device-manager.c ++++ b/src/libply-splash-core/ply-device-manager.c +@@ -780,61 +780,61 @@ on_udev_queue_changed (ply_device_manager_t *manager) + + ply_trace ("udev coldplug complete"); + ply_event_loop_stop_watching_fd (manager->loop, manager->udev_queue_fd_watch); + manager->udev_queue_fd_watch = NULL; + udev_queue_unref (manager->udev_queue); + + close (manager->udev_queue_fd); + manager->udev_queue_fd = -1; + + manager->udev_queue = NULL; + + create_seats_from_udev (manager); + } + + static void + watch_for_coldplug_completion (ply_device_manager_t *manager) + { + int fd; + int result; + + manager->udev_queue = udev_queue_new (manager->udev_context); + + if (udev_queue_get_queue_is_empty (manager->udev_queue)) + { + ply_trace ("udev coldplug completed already "); + create_seats_from_udev (manager); + return; + } + + fd = inotify_init1 (IN_CLOEXEC); +- result = inotify_add_watch (fd, "/run/udev", IN_MOVED_TO); ++ result = inotify_add_watch (fd, "/run/udev", IN_MOVED_TO| IN_DELETE); + + if (result < 0) + { + ply_trace ("could not watch for udev to show up: %m"); + close (fd); + + create_fallback_seat (manager); + return; + } + + manager->udev_queue_fd = fd; + + manager->udev_queue_fd_watch = ply_event_loop_watch_fd (manager->loop, + fd, + PLY_EVENT_LOOP_FD_STATUS_HAS_DATA, + (ply_event_handler_t) + on_udev_queue_changed, + NULL, + manager); + + } + + 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 done_with_initial_seat_setup; + +-- +2.3.7 + diff --git a/SOURCES/fix-details.patch b/SOURCES/fix-details.patch new file mode 100644 index 0000000..ef501c7 --- /dev/null +++ b/SOURCES/fix-details.patch @@ -0,0 +1,271 @@ +From 785a0050c01567e3e9eaaf0534e7e52045fc4a9d Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 24 Jan 2014 14:08:16 -0500 +Subject: [PATCH 1/3] plymouthd: build with -rdynamic so built-in module works + +The details plugin is "built in" to the plymouthd binary, so +it's always available even if the details module isn't installed +(say /usr isn't mounted yet or something) + +Unfortunately, this feature isn't working because plymouthd isn't +built with -rdynamic (except for in my local CFLAGS). + +This commit fixes the makefile goo accordingly. +--- + src/Makefile.am | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/Makefile.am b/src/Makefile.am +index 152cd43..fc2f5da 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -1,47 +1,48 @@ + SUBDIRS = libply libply-splash-core libply-splash-graphics . plugins client viewer + if ENABLE_UPSTART_MONITORING + SUBDIRS += upstart-bridge + endif + AM_CPPFLAGS = -I$(top_srcdir) \ + -I$(srcdir)/libply \ + -I$(srcdir)/libply-splash-core \ + -I$(srcdir) \ + -DPLYMOUTH_LOG_DIRECTORY=\"$(localstatedir)/log\" \ + -DPLYMOUTH_SPOOL_DIRECTORY=\"$(localstatedir)/spool/plymouth\" \ + -DPLYMOUTH_TIME_DIRECTORY=\"$(localstatedir)/lib/plymouth/\" \ + -DPLYMOUTH_LOGO_FILE=\"$(logofile)\" + + plymouthdbindir = $(plymouthdaemondir) + plymouthdbin_PROGRAMS = plymouthd + + plymouthd_CFLAGS = $(PLYMOUTH_CFLAGS) \ ++ -rdynamic \ + -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_SOURCES = \ + ply-boot-protocol.h \ + ply-boot-server.h \ + ply-boot-server.c \ + plugins/splash/details/plugin.c \ + main.c + + plymouthdrundir = $(localstatedir)/run/plymouth + plymouthdspooldir = $(localstatedir)/spool/plymouth + plymouthdtimedir = $(localstatedir)/lib/plymouth + + pkgconfigdir = $(libdir)/pkgconfig + pkgconfig_DATA = ply-splash-core.pc ply-splash-graphics.pc + + plymouthd_defaultsdir = $(PLYMOUTH_POLICY_DIR) + dist_plymouthd_defaults_DATA = plymouthd.defaults + + plymouthd_confdir = $(PLYMOUTH_CONF_DIR) + dist_plymouthd_conf_DATA = plymouthd.conf + + install-data-hook: + -mkdir -p $(DESTDIR)$(plymouthdrundir) + -mkdir -p $(DESTDIR)$(plymouthdspooldir) + -mkdir -p $(DESTDIR)$(plymouthdtimedir) +-- +1.8.3.1 + + +From 382305e4a9f7b4c221968fcba7394b1cc03b454e Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 24 Jan 2014 14:29:31 -0500 +Subject: [PATCH 2/3] main: disable hotplug events and splash delay if details + forced + +There's no point in waiting for a graphics device if details are +forced, and we shouldn't ever delay showing details. If details +are requested, we shouldn't be hiding them. +--- + src/main.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/src/main.c b/src/main.c +index 2ccb8ec..43e3a0a 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -2279,60 +2279,69 @@ main (int argc, + } + } + + state.progress = ply_progress_new (); + state.splash_delay = NAN; + + ply_progress_load_cache (state.progress, + get_cache_file_for_mode (state.mode)); + + if (pid_file != NULL) + write_pid_file (pid_file); + + if (daemon_handle != NULL + && !ply_detach_daemon (daemon_handle, 0)) + { + ply_error ("plymouthd: could not tell parent to exit: %m"); + return EX_UNAVAILABLE; + } + + find_override_splash (&state); + find_system_default_splash (&state); + find_distribution_default_splash (&state); + + if (command_line_has_argument (state.kernel_command_line, "plymouth.ignore-serial-consoles")) + device_manager_flags |= PLY_DEVICE_MANAGER_FLAGS_IGNORE_SERIAL_CONSOLES; + + if (command_line_has_argument (state.kernel_command_line, "plymouth.ignore-udev") || + (getenv ("DISPLAY") != NULL)) + device_manager_flags |= PLY_DEVICE_MANAGER_FLAGS_IGNORE_UDEV; + ++ if (!plymouth_should_show_default_splash (&state)) ++ { ++ /* don't bother listening for udev events if we're forcing details */ ++ device_manager_flags |= PLY_DEVICE_MANAGER_FLAGS_IGNORE_UDEV; ++ ++ /* don't ever delay showing the detailed splash */ ++ state.splash_delay = NAN; ++ } ++ + load_devices (&state, device_manager_flags); + + ply_trace ("entering event loop"); + exit_code = ply_event_loop_run (state.loop); + ply_trace ("exited event loop"); + + ply_boot_splash_free (state.boot_splash); + state.boot_splash = NULL; + + ply_command_parser_free (state.command_parser); + + ply_boot_server_free (state.boot_server); + state.boot_server = NULL; + + ply_trace ("freeing terminal session"); + ply_terminal_session_free (state.session); + + ply_buffer_free (state.boot_buffer); + ply_progress_free (state.progress); + + ply_trace ("exiting with code %d", exit_code); + + if (debug_buffer != NULL) + { + dump_debug_buffer_to_file (); + ply_buffer_free (debug_buffer); + } + + ply_free_error_log(); + +-- +1.8.3.1 + + +From 9255a442e93a4fce835ca6e7e9dc9023be6eaf30 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 24 Jan 2014 15:08:10 -0500 +Subject: [PATCH 3/3] seat: proceed without renderer if type is AUTO and + renderer fails + +If a seat gets opened with a renderer type of AUTO, and the renderer +fails to open, then it's okay and expected to proceed without a +renderer (and just use the terminal). The code attempted to do this +but failed to nullify the seat->renderer object, so it ended up +going down the renderer-active code path. + +This commit fixes that. +--- + src/libply-splash-core/ply-seat.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +diff --git a/src/libply-splash-core/ply-seat.c b/src/libply-splash-core/ply-seat.c +index d9c7a2b..541b29e 100644 +--- a/src/libply-splash-core/ply-seat.c ++++ b/src/libply-splash-core/ply-seat.c +@@ -90,69 +90,76 @@ add_pixel_displays (ply_seat_t *seat) + 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) ++ if (!ply_renderer_open (renderer)) + { + ply_trace ("could not open renderer for %s", device); + ply_renderer_free (renderer); +- return false; +- } + +- seat->renderer = renderer; +- seat->renderer_active = true; ++ seat->renderer = NULL; ++ seat->renderer_active = false; ++ ++ if (renderer_type != PLY_RENDERER_TYPE_AUTO) ++ return false; ++ } ++ else ++ { ++ 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); + + ply_keyboard_watch_for_input (seat->keyboard); + 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) + { +-- +1.8.3.1 + diff --git a/SOURCES/fix-escape-key-for-media-check.patch b/SOURCES/fix-escape-key-for-media-check.patch new file mode 100644 index 0000000..19e1841 --- /dev/null +++ b/SOURCES/fix-escape-key-for-media-check.patch @@ -0,0 +1,96 @@ +From 014f62a8701e7c69436bfbf37a0f1b73968a23e8 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 1 Jul 2016 16:39:59 -0400 +Subject: [PATCH] main: fix escape key for media check + +Right now, if a show-splash request comes in, then +we don't actually operate on it until splash delay +seconds later (~5 by default). + +The problem is, if a hide-splash request comes in, in the mean +while, we don't cancel the queued show-splash request. + +This commit fixes that. +--- + src/main.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/src/main.c b/src/main.c +index 7c4ea3c..8a201f8 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -1153,62 +1153,70 @@ hide_splash (state_t *state) + state->is_shown = false; + + cancel_pending_delayed_show (state); + + if (state->boot_splash == NULL) + return; + + ply_boot_splash_hide (state->boot_splash); + + if (state->local_console_terminal != NULL) + ply_terminal_set_mode (state->local_console_terminal, PLY_TERMINAL_MODE_TEXT); + } + + static void + dump_details_and_quit_splash (state_t *state) + { + state->showing_details = false; + toggle_between_splash_and_details (state); + + ply_device_manager_deactivate_renderers (state->device_manager); + hide_splash (state); + quit_splash (state); + } + + static void + on_hide_splash (state_t *state) + { + if (state->is_inactive) + return; + ++ /* If the splash is NULL then we haven't shown it yet, ++ * but we still need to call hide splash so it won't show ++ * spontaneously after the splash delay later. ++ */ + if (state->boot_splash == NULL) +- return; ++ { ++ ply_trace ("cancelling pending show splash operation (if any)"); ++ hide_splash (state); ++ return; ++ } + + ply_trace ("hiding boot splash"); + dump_details_and_quit_splash (state); + } + + #ifdef PLY_ENABLE_DEPRECATED_GDM_TRANSITION + static void + tell_gdm_to_transition (void) + { + int fd; + + fd = creat ("/var/spool/gdm/force-display-on-active-vt", 0644); + close (fd); + } + #endif + + static void + quit_program (state_t *state) + { + ply_trace ("cleaning up devices"); + ply_device_manager_free (state->device_manager); + + ply_trace ("exiting event loop"); + ply_event_loop_exit (state->loop, 0); + + if (pid_file != NULL) + { + unlink (pid_file); + free (pid_file); + pid_file = NULL; +-- +2.7.4 + diff --git a/SOURCES/fix-hide-splash.patch b/SOURCES/fix-hide-splash.patch new file mode 100644 index 0000000..729bcb4 --- /dev/null +++ b/SOURCES/fix-hide-splash.patch @@ -0,0 +1,174 @@ +From 1628320b093e3605e91f0aa7183b6859920a0a85 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 6 Feb 2014 14:42:40 -0500 +Subject: [PATCH 1/2] main: don't nullify local_console_terminal in quit_splash + +quit_splash gets called on hide-splash so nullify the terminal +will make it unavailable on later show-splash calls. +--- + src/main.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/main.c b/src/main.c +index 91e0649..1f9f6dd 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -1042,61 +1042,60 @@ load_devices (state_t *state, + { + state->device_manager = ply_device_manager_new (state->default_tty, flags); + state->local_console_terminal = ply_device_manager_get_default_terminal (state->device_manager); + + ply_device_manager_watch_seats (state->device_manager, + (ply_seat_added_handler_t) + on_seat_added, + (ply_seat_removed_handler_t) + on_seat_removed, + state); + } + + static void + quit_splash (state_t *state) + { + ply_trace ("quiting splash"); + if (state->boot_splash != NULL) + { + ply_trace ("freeing splash"); + ply_boot_splash_free (state->boot_splash); + state->boot_splash = NULL; + } + + if (state->local_console_terminal != NULL) + { + if (!state->should_retain_splash) + { + ply_trace ("Not retaining splash, so deallocating VT"); + ply_terminal_deactivate_vt (state->local_console_terminal); + } +- state->local_console_terminal = NULL; + } + + detach_from_running_session (state); + } + + static void + hide_splash (state_t *state) + { + state->is_shown = false; + + cancel_pending_delayed_show (state); + + if (state->boot_splash == NULL) + return; + + ply_boot_splash_hide (state->boot_splash); + + if (state->local_console_terminal != NULL) + ply_terminal_set_mode (state->local_console_terminal, PLY_TERMINAL_MODE_TEXT); + } + + static void + dump_details_and_quit_splash (state_t *state) + { + state->showing_details = false; + toggle_between_splash_and_details (state); + + ply_device_manager_deactivate_renderers (state->device_manager); + hide_splash (state); + quit_splash (state); +-- +1.8.3.1 + + +From fea0252399bf9d13e88b27b7296f263732f180fc Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 6 Feb 2014 15:22:54 -0500 +Subject: [PATCH 2/2] main: detach from keyboard on hide-splash + +Currently plymouth stays in control of the terminal +after hide-splash. This is wrong. Once plymouth is +hidden, the terminal should be free to use for other +programs. + +This commit makes sure we free up the terminal on +hide splash. +--- + src/main.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/main.c b/src/main.c +index 1f9f6dd..92a1cfd 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -1035,66 +1035,69 @@ on_seat_added (state_t *state, + on_enter, state); + + } + + static void + load_devices (state_t *state, + ply_device_manager_flags_t flags) + { + state->device_manager = ply_device_manager_new (state->default_tty, flags); + state->local_console_terminal = ply_device_manager_get_default_terminal (state->device_manager); + + ply_device_manager_watch_seats (state->device_manager, + (ply_seat_added_handler_t) + on_seat_added, + (ply_seat_removed_handler_t) + on_seat_removed, + state); + } + + static void + quit_splash (state_t *state) + { + ply_trace ("quiting splash"); + if (state->boot_splash != NULL) + { + ply_trace ("freeing splash"); + ply_boot_splash_free (state->boot_splash); + state->boot_splash = NULL; + } + ++ ply_device_manager_deactivate_keyboards (state->device_manager); ++ + if (state->local_console_terminal != NULL) + { + if (!state->should_retain_splash) + { + ply_trace ("Not retaining splash, so deallocating VT"); + ply_terminal_deactivate_vt (state->local_console_terminal); ++ ply_terminal_close (state->local_console_terminal); + } + } + + detach_from_running_session (state); + } + + static void + hide_splash (state_t *state) + { + state->is_shown = false; + + cancel_pending_delayed_show (state); + + if (state->boot_splash == NULL) + return; + + ply_boot_splash_hide (state->boot_splash); + + if (state->local_console_terminal != NULL) + ply_terminal_set_mode (state->local_console_terminal, PLY_TERMINAL_MODE_TEXT); + } + + static void + dump_details_and_quit_splash (state_t *state) + { + state->showing_details = false; + toggle_between_splash_and_details (state); + + ply_device_manager_deactivate_renderers (state->device_manager); + hide_splash (state); +-- +1.8.3.1 + diff --git a/SOURCES/fix-init-bin-sh.patch b/SOURCES/fix-init-bin-sh.patch new file mode 100644 index 0000000..0b31cab --- /dev/null +++ b/SOURCES/fix-init-bin-sh.patch @@ -0,0 +1,231 @@ +From be52bd06949cb2a386fda147d24155581708ef1a Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 10 Oct 2014 13:30:56 -0400 +Subject: [PATCH] main: show splash when init=/bin/sh + +but quit after switch root. The keeps luks +working. +--- + src/main.c | 23 ++++++++++++++++++++--- + 1 file changed, 20 insertions(+), 3 deletions(-) + +diff --git a/src/main.c b/src/main.c +index fb91bf2..4101550 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -135,60 +135,64 @@ static ply_boot_splash_t *load_theme (state_t *state, + static ply_boot_splash_t *show_theme (state_t *state, + const char *theme_path); + + static void attach_splash_to_seats (state_t *state, + ply_boot_splash_t *splash); + static bool attach_to_running_session (state_t *state); + static void detach_from_running_session (state_t *state); + static void on_escape_pressed (state_t *state); + static void dump_details_and_quit_splash (state_t *state); + static void update_display (state_t *state); + + static void on_error_message (ply_buffer_t *debug_buffer, + const void *bytes, + size_t number_of_bytes); + static ply_buffer_t *debug_buffer; + static char *debug_buffer_path = NULL; + static char *pid_file = NULL; + static void toggle_between_splash_and_details (state_t *state); + #ifdef PLY_ENABLE_SYSTEMD_INTEGRATION + static void tell_systemd_to_print_details (state_t *state); + static void tell_systemd_to_stop_printing_details (state_t *state); + #endif + static const char * get_cache_file_for_mode (ply_mode_t mode); + static void on_escape_pressed (state_t *state); + static void on_enter (state_t *state, + const char *line); + static void on_keyboard_input (state_t *state, + const char *keyboard_input, + size_t character_size); + static void on_backspace (state_t *state); ++static void on_quit (state_t *state, ++ bool retain_splash, ++ ply_trigger_t *quit_trigger); ++static bool sh_is_init (state_t *state); + + static void + on_session_output (state_t *state, + const char *output, + size_t size) + { + ply_buffer_append_bytes (state->boot_buffer, output, size); + if (state->boot_splash != NULL) + ply_boot_splash_update_output (state->boot_splash, + output, size); + } + + static void + on_session_hangup (state_t *state) + { + ply_trace ("got hang up on terminal session fd"); + } + + static void + on_update (state_t *state, + const char *status) + { + ply_trace ("updating status to '%s'", status); + ply_progress_status_update (state->progress, + status); + if (state->boot_splash != NULL) + ply_boot_splash_update_status (state->boot_splash, + status); + } + +@@ -626,60 +630,67 @@ on_ignore_keystroke (state_t *state, + { + ply_keystroke_watch_t* keystroke_trigger = ply_list_node_get_data (node); + if ((!keystroke_trigger->keys && !keys) || + (keystroke_trigger->keys && keys && strcmp(keystroke_trigger->keys, keys)==0)) + { + ply_trigger_pull (keystroke_trigger->trigger, NULL); + ply_list_remove_node (state->keystroke_triggers, node); + return; + } + } + } + + static void + on_progress_pause (state_t *state) + { + ply_trace ("pausing progress"); + ply_progress_pause (state->progress); + } + + static void + on_progress_unpause (state_t *state) + { + ply_trace ("unpausing progress"); + ply_progress_unpause (state->progress); + } + + static void + on_newroot (state_t *state, + const char *root_dir) + { ++ if (sh_is_init (state)) ++ { ++ ply_trace ("new root mounted at \"%s\", exiting since init= a shell", root_dir); ++ on_quit (state, false, ply_trigger_new (NULL)); ++ return; ++ } ++ + ply_trace ("new root mounted at \"%s\", switching to it", root_dir); + chdir(root_dir); + chroot("."); + chdir("/"); + ply_progress_load_cache (state->progress, get_cache_file_for_mode (state->mode)); + if (state->boot_splash != NULL) + ply_boot_splash_root_mounted (state->boot_splash); + } + + static const char * + get_cache_file_for_mode (ply_mode_t mode) + { + const char *filename; + + switch ((int)mode) + { + case PLY_MODE_BOOT: + filename = BOOT_DURATION_FILE; + break; + case PLY_MODE_SHUTDOWN: + filename = SHUTDOWN_DURATION_FILE; + break; + case PLY_MODE_UPDATES: + filename = NULL; + break; + default: + ply_error ("Unhandled case in %s line %d\n", __FILE__, __LINE__); + abort (); + break; + } +@@ -781,70 +792,76 @@ prepare_logging (state_t *state) + if (state->number_of_errors > 0) + spool_error (state); + } + } + + static void + on_system_initialized (state_t *state) + { + ply_trace ("system now initialized, opening log"); + state->system_initialized = true; + + prepare_logging (state); + } + + static void + on_error (state_t *state) + { + ply_trace ("encountered error during boot up"); + + if (state->system_initialized && state->number_of_errors == 0) + spool_error (state); + else + ply_trace ("not spooling because number of errors %d", state->number_of_errors); + + state->number_of_errors++; + } + + static bool + plymouth_should_ignore_show_splash_calls (state_t *state) + { +- const char *init_string; +- size_t length; +- + ply_trace ("checking if plymouth should be running"); + if (state->mode != PLY_MODE_BOOT || command_line_has_argument (state->kernel_command_line, "plymouth.force-splash")) + return false; + + if (command_line_has_argument (state->kernel_command_line, "plymouth.ignore-show-splash")) + return true; + ++ return false; ++} ++ ++static bool ++sh_is_init (state_t *state) ++{ ++ const char *init_string; ++ size_t length; ++ + init_string = command_line_get_string_after_prefix (state->kernel_command_line, "init="); + + if (init_string) + { + length = strcspn (init_string, " \n"); + if (length > 2 && ply_string_has_prefix (init_string + length - 2, "sh")) + return true; + } + + return false; + } + + static bool + plymouth_should_show_default_splash (state_t *state) + { + ply_trace ("checking if plymouth should show default splash"); + + const char const *strings[] = { + "single", "1", "s", "S", "-S", NULL + }; + int i; + + if (state->should_force_details) + return false; + + for (i = 0; strings[i] != NULL; i++) + { + if (command_line_has_argument (state->kernel_command_line, strings[i])) + { + ply_trace ("no default splash because kernel command line has option \"%s\"", strings[i]); +-- +1.8.3.1 + diff --git a/SOURCES/fix-progress-bar-colors.patch b/SOURCES/fix-progress-bar-colors.patch new file mode 100644 index 0000000..7bd89d0 --- /dev/null +++ b/SOURCES/fix-progress-bar-colors.patch @@ -0,0 +1,88 @@ +From 167e74e56df055f419c960657eb66d73802a54f1 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 20 Jun 2016 11:06:49 -0400 +Subject: [PATCH] drm: don't pick up drm master implicitly + +If a client opens the drm device, they're given drm master +implicitly. We already explicitly take DRM master when we need it, +so that featuer is unneeded. + +Furthermore, it's actively harmful, since fbdev won't let you change +the color palette of the terminal if drm master is held. + +This commit makes sure to drop master as soon as we get it from +open(). +--- + src/plugins/renderers/drm/plugin.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/plugins/renderers/drm/plugin.c b/src/plugins/renderers/drm/plugin.c +index 6677279..ebfe864 100644 +--- a/src/plugins/renderers/drm/plugin.c ++++ b/src/plugins/renderers/drm/plugin.c +@@ -462,60 +462,62 @@ load_driver (ply_renderer_backend_t *backend) + int device_fd; + + ply_trace ("Opening '%s'", backend->device_name); + device_fd = open (backend->device_name, O_RDWR); + + if (device_fd < 0) + { + ply_trace ("open failed: %m"); + return false; + } + + backend->driver_interface = ply_renderer_generic_driver_get_interface (device_fd); + backend->driver_supports_mapping_console = false; + + if (backend->driver_interface == NULL) + { + close (device_fd); + return false; + } + + backend->driver = backend->driver_interface->create_driver (device_fd); + + if (backend->driver == NULL) + { + close (device_fd); + return false; + } + + backend->device_fd = device_fd; + ++ drmDropMaster (device_fd); ++ + return true; + } + + static void + unload_driver (ply_renderer_backend_t *backend) + { + if (backend->driver == NULL) + return; + + ply_trace ("unloading driver"); + assert (backend->driver_interface != NULL); + + backend->driver_interface->destroy_driver (backend->driver); + backend->driver = NULL; + + backend->driver_interface = NULL; + + if (backend->device_fd >= 0) + { + drmClose (backend->device_fd); + backend->device_fd = -1; + } + } + + static bool + open_device (ply_renderer_backend_t *backend) + { + assert (backend != NULL); + assert (backend->device_name != NULL); + +-- +2.7.4 + diff --git a/SOURCES/fix-startup-race.patch b/SOURCES/fix-startup-race.patch new file mode 100644 index 0000000..c449b77 --- /dev/null +++ b/SOURCES/fix-startup-race.patch @@ -0,0 +1,213 @@ +From 530db7a38000c0ee82ef833eec27ca05539da59e Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 5 Feb 2014 15:09:13 -0500 +Subject: [PATCH 1/2] main: don't show splash from cancel_pending_delayed_show + +It was a weird to show something in a function called "cancel..show" + +Instead move the logic to the one caller that actually needed that +functionality (on_ask_for_password) +--- + src/main.c | 24 ++++++++++++++---------- + 1 file changed, 14 insertions(+), 10 deletions(-) + +diff --git a/src/main.c b/src/main.c +index e1cbcd9..64552b4 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -455,95 +455,99 @@ show_default_splash (state_t *state) + if (state->boot_splash == NULL) + { + ply_trace ("Trying old scheme for default splash"); + state->boot_splash = show_theme (state, PLYMOUTH_THEME_PATH "default.plymouth"); + } + + if (state->boot_splash == NULL) + { + ply_trace ("Could not start default splash screen," + "showing text splash screen"); + state->boot_splash = show_theme (state, PLYMOUTH_THEME_PATH "text/text.plymouth"); + } + + if (state->boot_splash == NULL) + { + ply_trace ("Could not start text splash screen," + "showing built-in splash screen"); + state->boot_splash = show_theme (state, NULL); + } + + if (state->boot_splash == NULL) + { + ply_error ("plymouthd: could not start boot splash: %m"); + return; + } + } + + static void + cancel_pending_delayed_show (state_t *state) + { +- bool has_open_seats; +- + if (isnan (state->splash_delay)) + return; + + ply_event_loop_stop_watching_for_timeout (state->loop, + (ply_event_loop_timeout_handler_t) + show_splash, + state); + state->splash_delay = NAN; +- has_open_seats = ply_device_manager_has_open_seats (state->device_manager); +- +- if (state->is_shown && has_open_seats) +- { +- ply_trace ("splash delay cancelled, showing splash immediately"); +- show_splash (state); +- } + } + + static void + on_ask_for_password (state_t *state, + const char *prompt, + ply_trigger_t *answer) + { + ply_entry_trigger_t *entry_trigger; + + if (state->boot_splash == NULL) + { + /* Waiting to be shown, boot splash will + * arrive shortly so just sit tight + */ + if (state->is_shown) + { +- ply_trace ("splash still coming up, waiting a bit"); ++ bool has_open_seats; ++ + cancel_pending_delayed_show (state); ++ ++ has_open_seats = ply_device_manager_has_open_seats (state->device_manager); ++ ++ if (has_open_seats) ++ { ++ ply_trace ("seats open now, showing splash immediately"); ++ show_splash (state); ++ } ++ else ++ { ++ ply_trace ("splash still coming up, waiting a bit"); ++ } + } + else + { + /* No splash, client will have to get password */ + ply_trace ("no splash loaded, replying immediately with no password"); + ply_trigger_pull (answer, NULL); + return; + } + } + + entry_trigger = calloc (1, sizeof (ply_entry_trigger_t)); + entry_trigger->type = PLY_ENTRY_TRIGGER_TYPE_PASSWORD; + entry_trigger->prompt = prompt; + entry_trigger->trigger = answer; + ply_trace ("queuing password request with boot splash"); + ply_list_append_data (state->entry_triggers, entry_trigger); + update_display (state); + } + + static void + on_ask_question (state_t *state, + const char *prompt, + ply_trigger_t *answer) + { + ply_entry_trigger_t *entry_trigger; + + entry_trigger = calloc (1, sizeof (ply_entry_trigger_t)); + entry_trigger->type = PLY_ENTRY_TRIGGER_TYPE_QUESTION; + entry_trigger->prompt = prompt; + entry_trigger->trigger = answer; +-- +1.8.3.1 + + +From 09bbba9201456305ac609d5f6a4be96463adcfd2 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 5 Feb 2014 15:12:17 -0500 +Subject: [PATCH 2/2] main: cancel show_splash timeout on deactivate + +This fixes a race/crash where plymouthd get deactivated +right before the show timer fires and it tries to +show itself after things have been torn down. +--- + src/main.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/main.c b/src/main.c +index 64552b4..4a9d91f 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -1211,60 +1211,62 @@ on_boot_splash_idle (state_t *state) + } + else if (state->deactivate_trigger != NULL) + { + ply_trace ("deactivating splash"); + deactivate_splash (state); + } + } + + static void + on_deactivate (state_t *state, + ply_trigger_t *deactivate_trigger) + { + if (state->is_inactive) + { + ply_trigger_pull (deactivate_trigger, NULL); + return; + } + + if (state->deactivate_trigger != NULL) + { + ply_trigger_add_handler (state->deactivate_trigger, + (ply_trigger_handler_t) + ply_trigger_pull, + deactivate_trigger); + return; + } + + state->deactivate_trigger = deactivate_trigger; + + ply_trace ("deactivating"); ++ cancel_pending_delayed_show (state); ++ + ply_device_manager_deactivate_keyboards (state->device_manager); + + if (state->boot_splash != NULL) + { + ply_boot_splash_become_idle (state->boot_splash, + (ply_boot_splash_on_idle_handler_t) + on_boot_splash_idle, + state); + } + else + { + ply_trace ("deactivating splash"); + deactivate_splash (state); + } + } + + static void + on_reactivate (state_t *state) + { + if (!state->is_inactive) + return; + + if (state->local_console_terminal != NULL) + { + ply_terminal_open (state->local_console_terminal); + ply_terminal_watch_for_vt_changes (state->local_console_terminal); + ply_terminal_set_unbuffered_input (state->local_console_terminal); + ply_terminal_ignore_mode_changes (state->local_console_terminal, false); + } + +-- +1.8.3.1 + diff --git a/SOURCES/fix-text-splash-os-string.patch b/SOURCES/fix-text-splash-os-string.patch new file mode 100644 index 0000000..a096d6d --- /dev/null +++ b/SOURCES/fix-text-splash-os-string.patch @@ -0,0 +1,107 @@ +From ae62b6013c3fd562659e59b517237d64bb0a12c6 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 25 May 2016 14:57:43 -0400 +Subject: [PATCH] text-progress-bar: munge os-release output + +RHEL uses the same /etc/os-release file in the installer for all +variants. This means we need to trim the variant out from the +string, since it's not accurate. + +dracut adds its own mark to the os-release file in the initramfs, +we need to trim that out, too. +--- + src/libply-splash-core/ply-text-progress-bar.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/src/libply-splash-core/ply-text-progress-bar.c b/src/libply-splash-core/ply-text-progress-bar.c +index 8c4e759..a5a6aff 100644 +--- a/src/libply-splash-core/ply-text-progress-bar.c ++++ b/src/libply-splash-core/ply-text-progress-bar.c +@@ -121,60 +121,84 @@ get_os_string (void) + { + char key[] = "PRETTY_NAME="; + + for (pos = strstr (buf, key); + pos != NULL; + pos = strstr (pos, key)) + { + if (pos == buf || pos[-1] == '\n') + break; + } + + if (pos != NULL) + { + pos += strlen (key); + pos2 = strstr (pos, "\n"); + + if (pos2 != NULL) + *pos2 = '\0'; + else + pos2 = pos + strlen(pos) - 1; + + if ((*pos == '\"' && pos2[-1] == '\"') || + (*pos == '\'' && pos2[-1] == '\'')) + { + pos++; + pos2--; + + *pos2 = '\0'; + } + asprintf (&os_string, " %s", pos); ++ ++ /* For RHEL, overwrite variant because it's not reliable, see ++ * bug 911553 ++ */ ++ pos = strstr (os_string, "Red Hat Enterprise Linux "); ++ ++ if (pos != NULL) ++ { ++ pos += strlen ("Red Hat Enterprise Linux "); ++ ++ pos2 = strstr (pos, " "); ++ ++ if (pos2 != NULL) ++ { ++ pos2++; ++ memmove (pos, pos2, strlen (pos2)); ++ } ++ } ++ ++ /* Trim out code names and dracut gook ++ */ ++ pos = strstr (os_string, " ("); ++ if (pos != NULL) ++ *pos = '\0'; + } + goto out; + } + + pos = strstr (buf, " release "); + + if (pos == NULL) + goto out; + + pos2 = strstr (pos, " ("); + + if (pos2 == NULL) + goto out; + + *pos = '\0'; + pos += strlen (" release "); + + *pos2 = '\0'; + asprintf (&os_string, " %s %s", buf, pos); + + out: + free (buf); + + if (os_string == NULL) + os_string = strdup (""); + } + + void + ply_text_progress_bar_draw (ply_text_progress_bar_t *progress_bar) + { +-- +2.8.1 + diff --git a/SOURCES/ignore-early-fb-devices.patch b/SOURCES/ignore-early-fb-devices.patch new file mode 100644 index 0000000..05cb562 --- /dev/null +++ b/SOURCES/ignore-early-fb-devices.patch @@ -0,0 +1,768 @@ +From 10e686c2128bde0e70e7c137191dbe004d2f46fd Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 3 Mar 2014 13:27:30 -0500 +Subject: [PATCH 1/2] device-manager: handle drm hotplug separately from + /dev/fb + +Right now, we piggyback off fb subsystem events to know whether or +not a drm device is hotplugged (since all drm devices have fb devices +for backward compat). + +This commit makes drm and fb processing more independent, so we don't +rely on the compat device being available for drm hotplug to work.. +--- + src/libply-splash-core/ply-device-manager.c | 182 ++++++++++++++-------------- + 1 file changed, 89 insertions(+), 93 deletions(-) + +diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c +index 36e814d..25f7d54 100644 +--- a/src/libply-splash-core/ply-device-manager.c ++++ b/src/libply-splash-core/ply-device-manager.c +@@ -11,60 +11,63 @@ + * 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 + #include + #include + #include + #include + #include + #include + #include + #include + + #include + + #include "ply-logger.h" + #include "ply-event-loop.h" + #include "ply-hashtable.h" + #include "ply-list.h" + #include "ply-utils.h" + ++#define SUBSYSTEM_DRM "drm" ++#define SUBSYSTEM_FRAME_BUFFER "graphics" ++ + 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_seat_t *local_console_seat; + ply_list_t *seats; + struct udev *udev_context; + struct udev_queue *udev_queue; + int udev_queue_fd; + ply_fd_watch_t *udev_queue_fd_watch; + 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; + } +@@ -84,342 +87,334 @@ attach_to_event_loop (ply_device_manager_t *manager, + 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) ++static bool ++fb_device_has_drm_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; ++ bool has_drm_device = false; + + /* 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); + + ply_trace ("trying to find associated drm node for fb device (path: %s)", 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); ++ has_drm_device = true; + else + ply_trace ("no card node!"); + + udev_device_unref (card_device); + } + else + { + ply_trace ("no card entry!"); + } + + udev_enumerate_unref (card_matches); +- return device_node_path; ++ return has_drm_device; + } + + static void + create_seat_for_udev_device (ply_device_manager_t *manager, + struct udev_device *device) + { + bool for_local_console; +- char *card_path; ++ const char *device_path; + ply_terminal_t *terminal = NULL; + + for_local_console = device_is_for_local_console (manager, device); + + ply_trace ("device is for local console: %s", for_local_console? "yes" : "no"); + + if (for_local_console) + terminal = manager->local_console_terminal; + +- card_path = get_drm_device_node_path_from_fb_device (manager, device); ++ device_path = udev_device_get_devnode (device); + +- if (card_path != NULL) +- { +- create_seat_for_terminal_and_renderer_type (manager, +- card_path, +- terminal, +- PLY_RENDERER_TYPE_DRM); +- free (card_path); +- } +- else ++ if (device_path != NULL) + { +- const char *fb_device_node_path; ++ const char *subsystem; ++ ply_renderer_type_t renderer_type = PLY_RENDERER_TYPE_NONE; ++ ++ subsystem = udev_device_get_subsystem (device); ++ ++ if (strcmp (subsystem, SUBSYSTEM_DRM) == 0) ++ { ++ ply_trace ("found DRM device %s", device_path); ++ renderer_type = PLY_RENDERER_TYPE_DRM; ++ } ++ else if (strcmp (subsystem, SUBSYSTEM_FRAME_BUFFER) == 0) ++ { ++ ply_trace ("found frame buffer device %s", device_path); ++ if (!fb_device_has_drm_device (manager, device)) ++ { ++ renderer_type = PLY_RENDERER_TYPE_FRAME_BUFFER; ++ } ++ else ++ { ++ ply_trace ("ignoring, since there's a DRM device associated with it"); ++ } ++ } + +- fb_device_node_path = udev_device_get_devnode (device); +- if (fb_device_node_path != NULL) ++ if (renderer_type != PLY_RENDERER_TYPE_NONE) + create_seat_for_terminal_and_renderer_type (manager, +- fb_device_node_path, ++ device_path, + terminal, +- PLY_RENDERER_TYPE_FRAME_BUFFER); ++ renderer_type); + } + } + + 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; ++ const char *device_path; + +- fb_device_node_path = udev_device_get_devnode (device); ++ device_path = udev_device_get_devnode (device); + +- if (fb_device_node_path != NULL) +- free_seat_from_device_path (manager, fb_device_node_path); +- } ++ if (device_path != NULL) ++ free_seat_from_device_path (manager, device_path); + } + + static bool +-scan_graphics_devices (ply_device_manager_t *manager) ++create_seats_for_subsystem (ply_device_manager_t *manager, ++ const char *subsystem) + { +- struct udev_enumerate *fb_matches; +- struct udev_list_entry *fb_entry; ++ struct udev_enumerate *matches; ++ struct udev_list_entry *entry; + bool found_device = false; + +- 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_subsystem (fb_matches, "graphics"); +- udev_enumerate_scan_devices (fb_matches); ++ ply_trace ("creating seats for %s devices", ++ strcmp (subsystem, SUBSYSTEM_FRAME_BUFFER) == 0? ++ "frame buffer": ++ subsystem); + +- udev_list_entry_foreach (fb_entry, udev_enumerate_get_list_entry (fb_matches)) ++ matches = udev_enumerate_new (manager->udev_context); ++ udev_enumerate_add_match_subsystem (matches, subsystem); ++ udev_enumerate_scan_devices (matches); ++ ++ udev_list_entry_foreach (entry, udev_enumerate_get_list_entry (matches)) + { +- struct udev_device *fb_device = NULL; +- const char *fb_path; ++ struct udev_device *device = NULL; ++ const char *path; + +- fb_path = udev_list_entry_get_name (fb_entry); ++ path = udev_list_entry_get_name (entry); + +- if (fb_path == NULL) ++ if (path == NULL) + { +- ply_trace ("fb path was null!"); ++ ply_trace ("path was null!"); + continue; + } + +- ply_trace ("found device %s", fb_path); ++ ply_trace ("found device %s", path); + +- /* skip virtual fbcon device +- */ +- if (strcmp (fb_path, "/sys/devices/virtual/graphics/fbcon") == 0) +- { +- ply_trace ("ignoring since it's fbcon"); +- continue; +- } +- +- fb_device = udev_device_new_from_syspath (manager->udev_context, fb_path); ++ device = udev_device_new_from_syspath (manager->udev_context, path); + + /* if device isn't fully initialized, we'll get an add event later + */ +- if (udev_device_get_is_initialized (fb_device)) ++ if (udev_device_get_is_initialized (device)) + { + ply_trace ("device is initialized"); ++ + /* 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. ++ * devices should be ignored. + */ +- if (udev_device_has_tag (fb_device, "seat")) ++ if (udev_device_has_tag (device, "seat")) + { +- const char *fb_node; +- fb_node = udev_device_get_devnode (fb_device); +- if (fb_node != NULL) ++ const char *node; ++ node = udev_device_get_devnode (device); ++ if (node != NULL) + { +- ply_trace ("found node %s", fb_node); ++ ply_trace ("found node %s", node); + found_device = true; +- create_seat_for_udev_device (manager, fb_device); ++ create_seat_for_udev_device (manager, device); + } + } + else + { + ply_trace ("device doesn't have a seat tag"); + } + } + else + { + ply_trace ("it's not initialized"); + } + +- udev_device_unref (fb_device); ++ udev_device_unref (device); + } + +- udev_enumerate_unref (fb_matches); ++ udev_enumerate_unref (matches); + + return found_device; + } + + static void +-on_udev_graphics_event (ply_device_manager_t *manager) ++on_udev_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); + + ply_trace ("got %s event for device %s", action, udev_device_get_sysname (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_subsystem_devtype (manager->udev_monitor, SUBSYSTEM_DRM, NULL); ++ udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, SUBSYSTEM_FRAME_BUFFER, 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, ++ on_udev_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 +@@ -657,77 +652,78 @@ create_seats_from_terminals (ply_device_manager_t *manager) + int num_consoles; + + 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); + return true; + } + + return false; + } + +-static bool ++static void + create_seats_from_udev (ply_device_manager_t *manager) + { +- bool found_device; ++ bool found_drm_device, found_fb_device; + + ply_trace ("Looking for devices from udev"); +- found_device = scan_graphics_devices (manager); +- if (!found_device) +- { +- ply_trace ("Creating non-graphical seat, since there's no suitable graphics hardware"); +- create_seat_for_terminal_and_renderer_type (manager, +- ply_terminal_get_name (manager->local_console_terminal), +- manager->local_console_terminal, +- PLY_RENDERER_TYPE_NONE); +- } + +- return true; ++ found_drm_device = create_seats_for_subsystem (manager, SUBSYSTEM_DRM); ++ found_fb_device = create_seats_for_subsystem (manager, SUBSYSTEM_FRAME_BUFFER); ++ ++ if (found_drm_device || found_fb_device) ++ return; ++ ++ ply_trace ("Creating non-graphical seat, since there's no suitable graphics hardware"); ++ create_seat_for_terminal_and_renderer_type (manager, ++ ply_terminal_get_name (manager->local_console_terminal), ++ manager->local_console_terminal, ++ PLY_RENDERER_TYPE_NONE); + } + + static void + create_fallback_seat (ply_device_manager_t *manager) + { + create_seat_for_terminal_and_renderer_type (manager, + ply_terminal_get_name (manager->local_console_terminal), + manager->local_console_terminal, + PLY_RENDERER_TYPE_AUTO); + } + + static void + on_udev_queue_changed (ply_device_manager_t *manager) + { + + if (!udev_queue_get_queue_is_empty (manager->udev_queue)) + return; + + ply_trace ("udev coldplug complete"); + ply_event_loop_stop_watching_fd (manager->loop, manager->udev_queue_fd_watch); + manager->udev_queue_fd_watch = NULL; + udev_queue_unref (manager->udev_queue); + + close (manager->udev_queue_fd); + manager->udev_queue_fd = -1; + + manager->udev_queue = NULL; + + create_seats_from_udev (manager); + } +-- +1.8.3.1 + + +From 20603c552e7e31f65f6265ed7230ba4bcaf12bf5 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 3 Mar 2014 17:25:44 -0500 +Subject: [PATCH 2/2] device-manager: defer /dev/fb compat processing until + after coldplug + +We never want to use a /dev/fb device if a DRM device will work instead +(since it supports multi-monitor, isn't a legacy interface, etc) + +Unfortunately, right now plymouthd notices efifb at early start up, +see's there is no DRM device associated with it and chooses it for +the main display, which causes all sort of problems. + +This commit defers using /dev/fb devices until after udev settles. +--- + src/libply-splash-core/ply-device-manager.c | 24 +++++++++++++++++++++--- + 1 file changed, 21 insertions(+), 3 deletions(-) + +diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c +index 25f7d54..d06e1b5 100644 +--- a/src/libply-splash-core/ply-device-manager.c ++++ b/src/libply-splash-core/ply-device-manager.c +@@ -161,62 +161,63 @@ fb_device_has_drm_device (ply_device_manager_t *manager, + ply_trace ("no card entry!"); + } + + udev_enumerate_unref (card_matches); + return has_drm_device; + } + + static void + create_seat_for_udev_device (ply_device_manager_t *manager, + struct udev_device *device) + { + bool for_local_console; + const char *device_path; + ply_terminal_t *terminal = NULL; + + for_local_console = device_is_for_local_console (manager, device); + + ply_trace ("device is for local console: %s", for_local_console? "yes" : "no"); + + if (for_local_console) + terminal = manager->local_console_terminal; + + device_path = udev_device_get_devnode (device); + + if (device_path != NULL) + { + const char *subsystem; + ply_renderer_type_t renderer_type = PLY_RENDERER_TYPE_NONE; + + subsystem = udev_device_get_subsystem (device); ++ ply_trace ("device subsystem is %s", subsystem); + +- if (strcmp (subsystem, SUBSYSTEM_DRM) == 0) ++ if (subsystem != NULL && strcmp (subsystem, SUBSYSTEM_DRM) == 0) + { + ply_trace ("found DRM device %s", device_path); + renderer_type = PLY_RENDERER_TYPE_DRM; + } + else if (strcmp (subsystem, SUBSYSTEM_FRAME_BUFFER) == 0) + { + ply_trace ("found frame buffer device %s", device_path); + if (!fb_device_has_drm_device (manager, device)) + { + renderer_type = PLY_RENDERER_TYPE_FRAME_BUFFER; + } + else + { + ply_trace ("ignoring, since there's a DRM device associated with it"); + } + } + + if (renderer_type != PLY_RENDERER_TYPE_NONE) + create_seat_for_terminal_and_renderer_type (manager, + device_path, + terminal, + renderer_type); + } + } + + static void + free_seat_from_device_path (ply_device_manager_t *manager, + const char *device_path) + { + ply_list_node_t *node; +@@ -332,63 +333,80 @@ create_seats_for_subsystem (ply_device_manager_t *manager, + { + ply_trace ("it's not initialized"); + } + + udev_device_unref (device); + } + + udev_enumerate_unref (matches); + + return found_device; + } + + static void + on_udev_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); + + ply_trace ("got %s event for device %s", action, udev_device_get_sysname (device)); + + if (action == NULL) + return; + + if (strcmp (action, "add") == 0) +- create_seat_for_udev_device (manager, device); ++ { ++ const char *subsystem; ++ bool coldplug_complete = manager->udev_queue_fd_watch == NULL; ++ ++ subsystem = udev_device_get_subsystem (device); ++ ++ if (strcmp (subsystem, SUBSYSTEM_DRM) == 0 || ++ coldplug_complete) ++ { ++ create_seat_for_udev_device (manager, device); ++ } ++ else ++ { ++ ply_trace ("ignoring since we only handle subsystem %s devices after coldplug completes", subsystem); ++ } ++ } + else if (strcmp (action, "remove") == 0) +- free_seat_for_udev_device (manager, device); ++ { ++ 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"); + + udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, SUBSYSTEM_DRM, NULL); + udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, SUBSYSTEM_FRAME_BUFFER, 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_event, + NULL, + manager); + } + +-- +1.8.3.1 + diff --git a/SOURCES/plymouth-update-initrd b/SOURCES/plymouth-update-initrd new file mode 100755 index 0000000..4ed5709 --- /dev/null +++ b/SOURCES/plymouth-update-initrd @@ -0,0 +1,2 @@ +#!/bin/bash +dracut -f diff --git a/SOURCES/resize-proc-cmdline-buffer.patch b/SOURCES/resize-proc-cmdline-buffer.patch new file mode 100644 index 0000000..2301b2d --- /dev/null +++ b/SOURCES/resize-proc-cmdline-buffer.patch @@ -0,0 +1,153 @@ +From 6e15c8b20b2ff852fcc638948eb88ea5dfa4a916 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 10 Oct 2014 16:11:01 -0400 +Subject: [PATCH] main: fix incorrectly sized buffer for /proc/cmdline + +We assume /proc/cmdline will be no more than 512 bytes (including NUL). +It can actually be 4096 bytes (excluding NUL). + +This commit makes sure we allocate enough space for it and its NUL. +--- + src/main.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/src/main.c b/src/main.c +index 4101550..d5f4f4d 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -30,61 +30,61 @@ + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include + #include + + #include "ply-buffer.h" + #include "ply-command-parser.h" + #include "ply-boot-server.h" + #include "ply-boot-splash.h" + #include "ply-device-manager.h" + #include "ply-event-loop.h" + #include "ply-hashtable.h" + #include "ply-list.h" + #include "ply-logger.h" + #include "ply-renderer.h" + #include "ply-terminal-session.h" + #include "ply-trigger.h" + #include "ply-utils.h" + #include "ply-progress.h" + + #ifndef PLY_MAX_COMMAND_LINE_SIZE +-#define PLY_MAX_COMMAND_LINE_SIZE 512 ++#define PLY_MAX_COMMAND_LINE_SIZE 4097 + #endif + + #define BOOT_DURATION_FILE PLYMOUTH_TIME_DIRECTORY "/boot-duration" + #define SHUTDOWN_DURATION_FILE PLYMOUTH_TIME_DIRECTORY "/shutdown-duration" + + typedef enum { + PLY_MODE_BOOT, + PLY_MODE_SHUTDOWN, + PLY_MODE_UPDATES + } ply_mode_t; + + typedef struct + { + const char *keys; + ply_trigger_t *trigger; + } ply_keystroke_watch_t; + + typedef struct + { + enum {PLY_ENTRY_TRIGGER_TYPE_PASSWORD, + PLY_ENTRY_TRIGGER_TYPE_QUESTION} + type; + const char *prompt; + ply_trigger_t *trigger; + } ply_entry_trigger_t; + + typedef struct + { + ply_event_loop_t *loop; + ply_boot_server_t *boot_server; +@@ -1782,68 +1782,67 @@ detach_from_running_session (state_t *state) + + if (!state->is_attached) + return; + + ply_trace ("detaching from terminal session"); + ply_terminal_session_detach (state->session); + state->is_redirected = false; + state->is_attached = false; + } + + static bool + get_kernel_command_line (state_t *state) + { + int fd; + const char *remaining_command_line; + char *key; + + if (state->kernel_command_line_is_set) + return true; + + ply_trace ("opening /proc/cmdline"); + fd = open ("/proc/cmdline", O_RDONLY); + + if (fd < 0) + { + ply_trace ("couldn't open it: %m"); + return false; + } + + ply_trace ("reading kernel command line"); +- if (read (fd, state->kernel_command_line, sizeof (state->kernel_command_line)) < 0) ++ if (read (fd, state->kernel_command_line, sizeof (state->kernel_command_line) - 1) < 0) + { + ply_trace ("couldn't read it: %m"); + close (fd); + return false; + } + +- + /* we now use plymouth.argument for kernel commandline arguments. + * It used to be plymouth:argument. This bit just rewrites all : to be . + */ + remaining_command_line = state->kernel_command_line; + while ((key = strstr (remaining_command_line, "plymouth:")) != NULL) + { + char *colon; + + colon = key + strlen ("plymouth"); + *colon = '.'; + + remaining_command_line = colon + 1; + } + ply_trace ("Kernel command line is: '%s'", state->kernel_command_line); + + close (fd); + + state->kernel_command_line_is_set = true; + return true; + } + + static void + check_verbosity (state_t *state) + { + const char *stream; + const char *path; + + ply_trace ("checking if tracing should be enabled"); + + stream = command_line_get_string_after_prefix (state->kernel_command_line, +-- +1.8.3.1 + diff --git a/SOURCES/serial-console-fixes.patch b/SOURCES/serial-console-fixes.patch new file mode 100644 index 0000000..6c93491 --- /dev/null +++ b/SOURCES/serial-console-fixes.patch @@ -0,0 +1,541 @@ +From 8a1dfbe91c1b309d361b4053e05bd5e01056fd41 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 3 Mar 2014 17:55:59 -0500 +Subject: [PATCH 1/4] device-manager: ignore udev if only console is serial + console + +Right now we use the heuristic, "more than one entry in +/sys/class/tty/console/active" to mean "has serial consoles". + +We used to use the heuristic "file has more than tty0 in it". +The older heuristic is more accurate because a user may have +console=ttyS0 without console=tty0 on the kernel command line. +--- + src/libply-splash-core/ply-device-manager.c | 27 +++++++++++++-------------- + 1 file changed, 13 insertions(+), 14 deletions(-) + +diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c +index d06e1b5..098fd85 100644 +--- a/src/libply-splash-core/ply-device-manager.c ++++ b/src/libply-splash-core/ply-device-manager.c +@@ -514,204 +514,203 @@ ply_device_manager_new (const char *default_tty, + return manager; + } + + void + ply_device_manager_free (ply_device_manager_t *manager) + { + ply_trace ("freeing device manager"); + + if (manager == NULL) + return; + + ply_event_loop_stop_watching_for_exit (manager->loop, + (ply_event_loop_exit_handler_t) + detach_from_event_loop, + manager); + 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 ++static bool + add_consoles_from_file (ply_device_manager_t *manager, + const char *path) + { + int fd; + char contents[512] = ""; + ssize_t contents_length; +- int num_consoles; ++ bool has_serial_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; ++ return false; + } + + 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; ++ return false; + } + close (fd); + + remaining_file_contents = contents; +- num_consoles = 0; ++ has_serial_consoles = false; + + 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++; ++ ++ if (terminal != manager->local_console_terminal) ++ has_serial_consoles = true; + + /* 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; ++ return has_serial_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; + bool is_local_terminal = false; + + if (terminal != NULL && manager->local_console_terminal == terminal) + is_local_terminal = true; + + if (is_local_terminal && manager->local_console_seat != NULL) + { + ply_trace ("trying to create seat for local console when one already exists"); + return; + } + + 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 (is_local_terminal) + manager->local_console_seat = 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 has_serial_consoles; + + ply_trace ("checking for consoles"); + + if (manager->flags & PLY_DEVICE_MANAGER_FLAGS_IGNORE_SERIAL_CONSOLES) + { +- num_consoles = 0; ++ has_serial_consoles = false; + 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"); ++ has_serial_consoles = add_consoles_from_file (manager, "/sys/class/tty/console/active"); + } + +- if (num_consoles > 1) ++ if (has_serial_consoles) + { + 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); + return true; + } + + return false; + } + + static void + create_seats_from_udev (ply_device_manager_t *manager) + { + bool found_drm_device, found_fb_device; + + ply_trace ("Looking for devices from udev"); + + found_drm_device = create_seats_for_subsystem (manager, SUBSYSTEM_DRM); + found_fb_device = create_seats_for_subsystem (manager, SUBSYSTEM_FRAME_BUFFER); + + if (found_drm_device || found_fb_device) + return; + + ply_trace ("Creating non-graphical seat, since there's no suitable graphics hardware"); + create_seat_for_terminal_and_renderer_type (manager, + ply_terminal_get_name (manager->local_console_terminal), + manager->local_console_terminal, + PLY_RENDERER_TYPE_NONE); +-- +1.8.3.1 + + +From 5fbfc8d1ec9da9060ebeaf0938afe8e2e0102b3d Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 3 Mar 2014 18:00:19 -0500 +Subject: [PATCH 2/4] device-manager: be more tolerant of tty active console + value + +Some kernels mistakenly put tty1 instead of tty0 in the file, +so try to cope with them for maximium compatibility. +--- + src/libply-splash-core/ply-device-manager.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c +index 098fd85..dbc203d 100644 +--- a/src/libply-splash-core/ply-device-manager.c ++++ b/src/libply-splash-core/ply-device-manager.c +@@ -441,61 +441,62 @@ free_terminal (char *device, + 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) ++ strcmp (full_name, "/dev/tty") == 0 || ++ strcmp (full_name, ply_terminal_get_name (manager->local_console_terminal)) == 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); +-- +1.8.3.1 + + +From 0d5fae7feb3c2fb462f124940e91fea16298eb1f Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 6 Mar 2014 14:42:16 -0500 +Subject: [PATCH 3/4] seat: make sure to open terminal when adding text + displays + +If we have a pixel display, the renderer will handle opening the +associated terminal. but if we don't have a pixel display, something +needs to open the terminal. + +This commit adds code to do that. +--- + src/libply-splash-core/ply-seat.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/src/libply-splash-core/ply-seat.c b/src/libply-splash-core/ply-seat.c +index 541b29e..2ac8bf7 100644 +--- a/src/libply-splash-core/ply-seat.c ++++ b/src/libply-splash-core/ply-seat.c +@@ -75,60 +75,73 @@ add_pixel_displays (ply_seat_t *seat) + 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; + ++ if (!ply_terminal_is_open (seat->terminal)) ++ { ++ if (!ply_terminal_open (seat->terminal)) ++ { ++ ply_trace ("could not add terminal %s: %m", ++ ply_terminal_get_name (seat->terminal)); ++ return; ++ } ++ } ++ ++ ply_trace ("adding text display for terminal %s", ++ ply_terminal_get_name (seat->terminal)); ++ + 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)) + { + ply_trace ("could not open renderer for %s", device); + ply_renderer_free (renderer); + + seat->renderer = NULL; + seat->renderer_active = false; + + if (renderer_type != PLY_RENDERER_TYPE_AUTO) + return false; + } + else + { + seat->renderer = renderer; + seat->renderer_active = true; +-- +1.8.3.1 + + +From aa2f5ac95c7cc0f4eb5f61465ecaf22247c7047c Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 6 Mar 2014 15:31:20 -0500 +Subject: [PATCH 4/4] device-manager: Don't add local console to terminals hash + table unless passed on cmdline + +it's unexpected for plymouth to show boot messages on the local console +if there is not console=tty0 on the kernel command line. + +This commit fixes that. +--- + src/libply-splash-core/ply-device-manager.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c +index dbc203d..8f5360c 100644 +--- a/src/libply-splash-core/ply-device-manager.c ++++ b/src/libply-splash-core/ply-device-manager.c +@@ -445,92 +445,93 @@ free_terminal (char *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 || + strcmp (full_name, ply_terminal_get_name (manager->local_console_terminal)) == 0) + { + terminal = manager->local_console_terminal; ++ ++ ply_hashtable_insert (manager->terminals, ++ (void *) ply_terminal_get_name (terminal), ++ 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; + + ply_event_loop_stop_watching_for_exit (manager->loop, + (ply_event_loop_exit_handler_t) + detach_from_event_loop, + manager); + free_seats (manager); + ply_list_free (manager->seats); + + free_terminals (manager); + ply_hashtable_free (manager->terminals); + + if (manager->udev_monitor != NULL) +-- +1.8.3.1 + diff --git a/SOURCES/ship-label-plugin-in-initrd.patch b/SOURCES/ship-label-plugin-in-initrd.patch new file mode 100644 index 0000000..f2284d6 --- /dev/null +++ b/SOURCES/ship-label-plugin-in-initrd.patch @@ -0,0 +1,146 @@ +From 68f14b8a0163d688ca36541bc1e28173b0b62317 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 20 Jul 2015 09:24:27 -0400 +Subject: [PATCH] populate-initrd: ship label plugin / font in initrd + +Some customers require showing text in the initrd, so +this commit goes ahead and ships label.so (and all its +dependencies) and one font in the initrd. +--- + scripts/plymouth-populate-initrd.in | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/scripts/plymouth-populate-initrd.in b/scripts/plymouth-populate-initrd.in +index d25ab07..da55318 100755 +--- a/scripts/plymouth-populate-initrd.in ++++ b/scripts/plymouth-populate-initrd.in +@@ -1,47 +1,48 @@ + #!/bin/bash + # + # inst bits ruthlessly and viciously stolen from dracut + + [ -z "$DESTDIR" ] || exit 0 + + [ -z "$PLYMOUTH_LIBEXECDIR" ] && PLYMOUTH_LIBEXECDIR="@PLYMOUTH_LIBEXECDIR@" + [ -z "$PLYMOUTH_DATADIR" ] && PLYMOUTH_DATADIR="@PLYMOUTH_DATADIR@" + [ -z "$PLYMOUTH_PLUGIN_PATH" ] && PLYMOUTH_PLUGIN_PATH="$(plymouth --get-splash-plugin-path)" + [ -z "$PLYMOUTH_LOGO_FILE" ] && PLYMOUTH_LOGO_FILE="@PLYMOUTH_LOGO_FILE@" + [ -n "$PLYMOUTH_THEME_NAME" ] && THEME_OVERRIDE=1 + [ -z "$PLYMOUTH_THEME_NAME" ] && PLYMOUTH_THEME_NAME=$(plymouth-set-default-theme) + [ -z "$PLYMOUTH_CONFDIR" ] && PLYMOUTH_CONFDIR="@PLYMOUTH_CONF_DIR@" + [ -z "$PLYMOUTH_POLICYDIR" ] && PLYMOUTH_POLICYDIR="@PLYMOUTH_POLICY_DIR@" + [ -z "$PLYMOUTH_DAEMON_PATH" ] && PLYMOUTH_DAEMON_PATH="@PLYMOUTH_DAEMON_DIR@/plymouthd" + [ -z "$PLYMOUTH_CLIENT_PATH" ] && PLYMOUTH_CLIENT_PATH="@PLYMOUTH_CLIENT_DIR@/plymouth" + [ -z "$SYSTEMD_UNIT_DIR" ] && SYSTEMD_UNIT_DIR="@SYSTEMD_UNIT_DIR@" ++[ -z "$SUPPORTED_LANGUAGES" ] && SUPPORTED_LANGUAGES="pt fr de it ru es en zh ja ko zh as bn gu hi kn ml mr or pa ta te" + + # Generic substring function. If $2 is in $1, return 0. + strstr() { [ "${1#*$2*}" != "$1" ]; } + + ddebug() { + [ "$verbose" = "true" ] && echo "$@" + } + + # normalize_path + # Prints the normalized path, where it removes any duplicated + # and trailing slashes. + # Example: + # $ normalize_path ///test/test// + # /test/test + normalize_path() { + shopt -q -s extglob + set -- "${1//+(\/)//}" + shopt -q -u extglob + echo "${1%/}" + } + + # convert_abs_rel + # Prints the relative path, when creating a symlink to from . + # Example: + # $ convert_abs_rel /usr/bin/test /bin/test-2 + # ../../bin/test-2 + # $ ln -s $(convert_abs_rel /usr/bin/test /bin/test-2) /usr/bin/test + convert_abs_rel() { + local __current __absolute __abssize __cursize __newpath + local -i __i __level +@@ -387,59 +388,77 @@ inst ${PLYMOUTH_CONFDIR}/plymouthd.conf $INITRDDIR + if [ -z "$PLYMOUTH_THEME_NAME" ]; then + echo "No default plymouth plugin is set" > /dev/stderr + exit 1 + fi + + if [ $THEME_OVERRIDE ]; then + conf=$INITRDDIR/${PLYMOUTH_CONFDIR}/plymouthd.conf + echo "modifying plymouthd.conf: Theme=$PLYMOUTH_THEME_NAME" > /dev/stderr + sed -i "s/^ *Theme *=.*/# theme modified by plymouth-populate-initrd\nTheme=$PLYMOUTH_THEME_NAME/" $conf + fi + + PLYMOUTH_MODULE_NAME=$(grep "ModuleName *= *" ${PLYMOUTH_DATADIR}/plymouth/themes/${PLYMOUTH_THEME_NAME}/${PLYMOUTH_THEME_NAME}.plymouth | sed 's/ModuleName *= *//') + + if [ ! -f ${PLYMOUTH_PLUGIN_PATH}/${PLYMOUTH_MODULE_NAME}.so ]; then + echo "The default plymouth plugin (${PLYMOUTH_MODULE_NAME}) doesn't exist" > /dev/stderr + exit 1 + fi + + inst ${PLYMOUTH_PLUGIN_PATH}/${PLYMOUTH_MODULE_NAME}.so $INITRDDIR + + [ -f "${PLYMOUTH_PLUGIN_PATH}/renderers/drm.so" ] && inst ${PLYMOUTH_PLUGIN_PATH}/renderers/drm.so $INITRDDIR + inst ${PLYMOUTH_PLUGIN_PATH}/renderers/frame-buffer.so $INITRDDIR + + if [ -d ${PLYMOUTH_DATADIR}/plymouth/themes/${PLYMOUTH_THEME_NAME} ]; then + for x in ${PLYMOUTH_DATADIR}/plymouth/themes/${PLYMOUTH_THEME_NAME}/* ; do + [ ! -f "$x" ] && continue + inst $x $INITRDDIR + done + fi + ++fonts="" ++needs_graphics="$(find ${INITRDDIR} -name 'libply-splash-graphics.so*' -print -quit | grep -q libply-splash-graphics.so && echo -n 1)" ++ ++if [ -n "$needs_graphics" ]; then ++ for lang in $SUPPORTED_LANGUAGES; do ++ font=$(fc-match "":lang="$lang" file | awk -F= '{ print $2}') ++ echo $fonts | grep -q "$font" && continue ++ fonts="$fonts $font" ++ done ++ ++ if [ -n "$fonts" ]; then ++ inst ${PLYMOUTH_PLUGIN_PATH}/label.so $INITRDDIR ++ for font in $fonts; do ++ inst $font $INITRDDIR ++ done ++ fi ++fi ++ + if [ -L ${PLYMOUTH_DATADIR}/plymouth/themes/default.plymouth ]; then + cp -a ${PLYMOUTH_DATADIR}/plymouth/themes/default.plymouth $INITRDDIR${PLYMOUTH_DATADIR}/plymouth/themes + fi + + if [ -n "$SYSTEMD_UNIT_DIR" -a -d "$SYSTEMD_UNIT_DIR" ]; then + inst $SYSTEMD_UNIT_DIR/systemd-ask-password-plymouth.path $INITRDDIR + inst $SYSTEMD_UNIT_DIR/systemd-ask-password-plymouth.service $INITRDDIR + + inst $SYSTEMD_UNIT_DIR/plymouth-switch-root.service $INITRDDIR + inst $SYSTEMD_UNIT_DIR/plymouth-start.service $INITRDDIR + inst $SYSTEMD_UNIT_DIR/plymouth-quit.service $INITRDDIR + inst $SYSTEMD_UNIT_DIR/plymouth-quit-wait.service $INITRDDIR + inst $SYSTEMD_UNIT_DIR/plymouth-reboot.service $INITRDDIR + inst $SYSTEMD_UNIT_DIR/plymouth-kexec.service $INITRDDIR + inst $SYSTEMD_UNIT_DIR/plymouth-poweroff.service $INITRDDIR + inst $SYSTEMD_UNIT_DIR/plymouth-halt.service $INITRDDIR + + inst $SYSTEMD_UNIT_DIR/initrd-switch-root.target.wants/plymouth-switch-root.service $INITRDDIR + inst $SYSTEMD_UNIT_DIR/initrd-switch-root.target.wants/plymouth-start.service $INITRDDIR + inst $SYSTEMD_UNIT_DIR/sysinit.target.wants/plymouth-start.service $INITRDDIR + inst $SYSTEMD_UNIT_DIR/multi-user.target.wants/plymouth-quit.service $INITRDDIR + inst $SYSTEMD_UNIT_DIR/multi-user.target.wants/plymouth-quit-wait.service $INITRDDIR + inst $SYSTEMD_UNIT_DIR/reboot.target.wants/plymouth-reboot.service $INITRDDIR + inst $SYSTEMD_UNIT_DIR/kexec.target.wants/plymouth-kexec.service $INITRDDIR + inst $SYSTEMD_UNIT_DIR/poweroff.target.wants/plymouth-poweroff.service $INITRDDIR + inst $SYSTEMD_UNIT_DIR/halt.target.wants/plymouth-halt.service $INITRDDIR + fi + + # vim:ts=8:sw=4:sts=4:et +-- +2.3.7 + diff --git a/SPECS/plymouth.spec b/SPECS/plymouth.spec new file mode 100644 index 0000000..ecfb673 --- /dev/null +++ b/SPECS/plymouth.spec @@ -0,0 +1,1368 @@ +%define plymouthdaemon_execdir %{_sbindir} +%define plymouthclient_execdir %{_bindir} +%define plymouth_libdir %{_libdir} +%define plymouth_initrd_file /boot/initrd-plymouth.img +%global _hardened_build 1 + +Summary: Graphical Boot Animation and Logger +Name: plymouth +Version: 0.8.9 +Release: 0.33.20140113%{?dist} +License: GPLv2+ +Group: System Environment/Base +Source0: http://freedesktop.org/software/plymouth/releases/%{name}-%{version}.tar.bz2 +Source1: boot-duration +Source2: charge.plymouth +Source3: plymouth-update-initrd +Source4: bootlog + +URL: http://www.freedesktop.org/wiki/Software/Plymouth +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) + +Requires: plymouth-core-libs = %{version}-%{release} +Requires: system-logos +Requires(post): plymouth-scripts +Requires: initscripts >= 8.83-1 +Conflicts: filesystem < 3 +Conflicts: systemd < 185-3 + +BuildRequires: git +BuildRequires: pkgconfig(libdrm) +BuildRequires: kernel-headers +BuildRequires: pkgconfig(libudev) +BuildRequires: automake, autoconf, libtool +BuildRequires: libxslt, docbook-style-xsl + +Obsoletes: plymouth-text-and-details-only < %{version}-%{release} +Obsoletes: plymouth-plugin-pulser < 0.7.0-0.2009.05.08.2 +Obsoletes: plymouth-theme-pulser < 0.7.0-0.2009.05.08.2 +Obsoletes: plymouth-gdm-hooks < 0.8.4-0.20101119.4 +Obsoletes: plymouth-utils < 0.8.4-0.20101119.4 + +Patch0: dont-block-show-splash.patch +Patch1: always-add-text-splash.patch +Patch2: fix-text-splash-os-string.patch +Patch3: fix-details.patch +Patch4: fix-startup-race.patch +Patch5: fix-hide-splash.patch +Patch6: ignore-early-fb-devices.patch +Patch7: fix-ask-password-race.patch +Patch8: serial-console-fixes.patch +Patch9: fix-init-bin-sh.patch +Patch10: resize-proc-cmdline-buffer.patch +Patch11: cursor-fix.patch +Patch12: ship-label-plugin-in-initrd.patch +Patch13: fix-coldplug-detection.patch +Patch14: ensure-output-gets-terminal.patch +Patch15: activate-new-renderers.patch +Patch16: fix-progress-bar-colors.patch +Patch17: fix-escape-key-for-media-check.patch +Patch18: 0001-Revert-Recreate-boot-log-at-each-boot-instead-of-app.patch +Patch19: 0001-Revert-Make-boot.log-world-readable-by-default.patch +Patch20: 0001-device-manager-fall-back-to-text-mode-if-graphical-d.patch +Patch21: 0001-ply-device-manager-Fix-race-causing-undesired-creati.patch +Patch22: 0001-boot-splash-handle-update-coming-in-after-splash-is-.patch + +Patch99: colors.patch + +%description +Plymouth provides an attractive graphical boot animation in +place of the text messages that normally get shown. Text +messages are instead redirected to a log file for viewing +after boot. + +%package system-theme +Summary: Plymouth default theme +Group: System Environment/Base +Obsoletes: rhgb < 1:10.0.0 +Provides: rhgb = 1:10.0.0 +Obsoletes: %{name}-system-plugin < %{version}-%{release} +Provides: %{name}-system-plugin = %{version}-%{release} +Provides: rhgb = 1:10.0.0 +Requires: plymouth(system-theme) = %{version}-%{release} + +%description system-theme +This metapackage tracks the current distribution default theme. + +%package core-libs +Summary: Plymouth core libraries +Group: Development/Libraries + +%description core-libs +This package contains the libply and libply-splash-core libraries +used by Plymouth. + +%package graphics-libs +Summary: Plymouth graphics libraries +Group: Development/Libraries +Requires: %{name}-core-libs = %{version}-%{release} +Obsoletes: %{name}-libs < %{version}-%{release} +Provides: %{name}-libs = %{version}-%{release} +BuildRequires: libpng-devel + +%description graphics-libs +This package contains the libply-splash-graphics library +used by graphical Plymouth splashes. + +%package devel +Summary: Libraries and headers for writing Plymouth splash plugins +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} +Requires: %{name}-core-libs = %{version}-%{release} +Requires: %{name}-graphics-libs = %{version}-%{release} +Requires: pkgconfig +BuildRequires: pkgconfig(gtk+-2.0) + +%description devel +This package contains the libply and libplybootsplash libraries +and headers needed to develop 3rd party splash plugins for Plymouth. + +%package scripts +Summary: Plymouth related scripts +Group: Applications/System +Requires: findutils, coreutils, gzip, cpio, dracut, plymouth + +%description scripts +This package contains scripts that help integrate Plymouth with +the system. + +%package plugin-label +Summary: Plymouth label plugin +Group: System Environment/Base +Requires: %{name} = %{version}-%{release} +Requires: %{name}-core-libs = %{version}-%{release} +Requires: %{name}-graphics-libs = %{version}-%{release} +BuildRequires: pango-devel >= 1.21.0 +BuildRequires: cairo-devel + +%description plugin-label +This package contains the label control plugin for +Plymouth. It provides the ability to render text on +graphical boot splashes using pango and cairo. + +%package plugin-fade-throbber +Summary: Plymouth "Fade-Throbber" plugin +Group: System Environment/Base +Requires: %{name} = %{version}-%{release} +Requires: %{name}-core-libs = %{version}-%{release} +Requires: %{name}-graphics-libs = %{version}-%{release} + +%description plugin-fade-throbber +This package contains the "Fade-In" boot splash plugin for +Plymouth. It features a centered image that fades in and out +while other images pulsate around during system boot up. + +%package theme-fade-in +Summary: Plymouth "Fade-In" theme +Group: System Environment/Base +Requires: %{name}-plugin-fade-throbber = %{version}-%{release} +Requires(post): plymouth-scripts +Obsoletes: plymouth-plugin-fade-in <= 0.7.0-0.2009.05.08.2 +Provides: plymouth-plugin-fade-in = 0.7.0-0.2009.05.08.2 + +%description theme-fade-in +This package contains the "Fade-In" boot splash theme for +Plymouth. It features a centered logo that fades in and out +while stars twinkle around the logo during system boot up. + +%package plugin-throbgress +Summary: Plymouth "Throbgress" plugin +Group: System Environment/Base +Requires: %{name} = %{version}-%{release} +Requires: %{name}-core-libs = %{version}-%{release} +Requires: %{name}-graphics-libs = %{version}-%{release} +Requires: plymouth-plugin-label + +%description plugin-throbgress +This package contains the "throbgress" boot splash plugin for +Plymouth. It features a centered logo and animated spinner that +spins repeatedly while a progress bar advances at the bottom of +the screen. + +%package theme-spinfinity +Summary: Plymouth "Spinfinity" theme +Group: System Environment/Base +Requires: %{name}-plugin-throbgress = %{version}-%{release} +Requires(post): plymouth-scripts +Obsoletes: plymouth-plugin-spinfinity <= 0.7.0-0.2009.05.08.2 +Provides: plymouth-plugin-spinfinity = 0.7.0-0.2009.05.08.2 + +%description theme-spinfinity +This package contains the "Spinfinity" boot splash theme for +Plymouth. It features a centered logo and animated spinner that +spins in the shape of an infinity sign. + +%package plugin-space-flares +Summary: Plymouth "space-flares" plugin +Group: System Environment/Base +Requires: %{name} = %{version}-%{release} +Requires: %{name}-core-libs = %{version}-%{release} +Requires: %{name}-graphics-libs = %{version}-%{release} +Requires: plymouth-plugin-label + +%description plugin-space-flares +This package contains the "space-flares" boot splash plugin for +Plymouth. It features a corner image with animated flares. + +%package theme-solar +Summary: Plymouth "Solar" theme +Group: System Environment/Base +Requires: %{name}-plugin-space-flares = %{version}-%{release} +Requires(post): plymouth-scripts +Obsoletes: plymouth-plugin-solar <= 0.7.0-0.2009.05.08.2 +Provides: plymouth-plugin-solar = 0.7.0-0.2009.05.08.2 +# We require this to fix upgrades (see bug 499940). +Requires: plymouth-system-theme + +%description theme-solar +This package contains the "Solar" boot splash theme for +Plymouth. It features a blue flamed sun with animated solar flares. + +%package plugin-two-step +Summary: Plymouth "two-step" plugin +Group: System Environment/Base +Requires: %{name} = %{version}-%{release} +Requires: %{name}-core-libs = %{version}-%{release} +Requires: %{name}-graphics-libs = %{version}-%{release} +Requires: plymouth-plugin-label + +%description plugin-two-step +This package contains the "two-step" boot splash plugin for +Plymouth. It features a two phased boot process that starts with +a progressing animation synced to boot time and finishes with a +short, fast one-shot animation. + +%package theme-charge +Summary: Plymouth "Charge" plugin +Group: System Environment/Base +Requires: %{name}-plugin-two-step = %{version}-%{release} +Requires(post): plymouth-scripts +Provides: plymouth(system-theme) = %{version}-%{release} + +%description theme-charge +This package contains the "charge" boot splash theme for +Plymouth. It is the default theme for Red Hat Enterprise Linux. + +%package plugin-script +Summary: Plymouth "script" plugin +Group: System Environment/Base +Requires: %{name} = %{version}-%{release} +Requires: %{name}-core-libs = %{version}-%{release} +Requires: %{name}-graphics-libs = %{version}-%{release} + +%description plugin-script +This package contains the "script" boot splash plugin for +Plymouth. It features an extensible, scriptable boot splash +language that simplifies the process of designing custom +boot splash themes. + +%package theme-script +Summary: Plymouth "Script" plugin +Group: System Environment/Base +Requires: %{name}-plugin-script = %{version}-%{release} +Requires(post): %{_sbindir}/plymouth-set-default-theme + +%description theme-script +This package contains the "script" boot splash theme for +Plymouth. It it is a simple example theme the uses the "script" +plugin. + +%package theme-spinner +Summary: Plymouth "Spinner" theme +Group: System Environment/Base +Requires: %{name}-plugin-two-step = %{version}-%{release} +Requires(post): plymouth-scripts + +%description theme-spinner +This package contains the "spinner" boot splash theme for +Plymouth. It features a small spinner on a dark background. + +%prep +%autosetup -S git + +# Change the default theme +sed -i -e 's/fade-in/charge/g' src/plymouthd.defaults + +%build +autoreconf -f -i +%configure --enable-tracing --disable-tests \ + --with-release-file=/etc/os-release \ + --with-logo=%{_datadir}/pixmaps/system-logo-white.png \ + --with-background-start-color-stop=0xc6bdd2 \ + --with-background-end-color-stop=0x4e376b \ + --with-background-color=0x8d59d2 \ + --disable-gdm-transition \ + --enable-systemd-integration \ + --without-system-root-install \ + --without-rhgb-compat-link \ + --without-log-viewer \ + --enable-documentation \ + --disable-libkms + +make + +%install +rm -rf $RPM_BUILD_ROOT + +make install DESTDIR=$RPM_BUILD_ROOT + +# Glow isn't quite ready for primetime +rm -rf $RPM_BUILD_ROOT%{_datadir}/plymouth/glow/ +rm -f $RPM_BUILD_ROOT%{_libdir}/plymouth/glow.so + +find $RPM_BUILD_ROOT -name '*.a' -exec rm -f {} \; +find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} \; + +mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/lib/plymouth +cp $RPM_SOURCE_DIR/boot-duration $RPM_BUILD_ROOT%{_datadir}/plymouth/default-boot-duration +cp $RPM_SOURCE_DIR/boot-duration $RPM_BUILD_ROOT%{_localstatedir}/lib/plymouth + +# Add charge, our new default +mkdir -p $RPM_BUILD_ROOT%{_datadir}/plymouth/themes/charge +cp %{SOURCE2} $RPM_BUILD_ROOT%{_datadir}/plymouth/themes/charge +cp $RPM_BUILD_ROOT%{_datadir}/plymouth/themes/glow/{box,bullet,entry,lock}.png $RPM_BUILD_ROOT%{_datadir}/plymouth/themes/charge + +# Drop glow, it's not very Fedora-y +rm -rf $RPM_BUILD_ROOT%{_datadir}/plymouth/themes/glow + +# Revert text theme back to the tribar one +rm -rf $RPM_BUILD_ROOT%{_datadir}/plymouth/themes/text +mv $RPM_BUILD_ROOT%{_libdir}/plymouth/tribar.so $RPM_BUILD_ROOT%{_libdir}/plymouth/text.so +mv $RPM_BUILD_ROOT%{_datadir}/plymouth/themes/tribar $RPM_BUILD_ROOT%{_datadir}/plymouth/themes/text +mv $RPM_BUILD_ROOT%{_datadir}/plymouth/themes/text/tribar.plymouth $RPM_BUILD_ROOT%{_datadir}/plymouth/themes/text/text.plymouth +sed -i -e 's/tribar/text/' $RPM_BUILD_ROOT%{_datadir}/plymouth/themes/text/text.plymouth + +cp $RPM_SOURCE_DIR/plymouth-update-initrd $RPM_BUILD_ROOT%{_libexecdir}/plymouth/plymouth-update-initrd + +install -d -m 755 $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d +install -p -m 644 $RPM_SOURCE_DIR/bootlog $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/bootlog + +%clean +rm -rf $RPM_BUILD_ROOT + +%post +[ -f %{_localstatedir}/lib/plymouth/boot-duration ] || cp -f %{_datadir}/plymouth/default-boot-duration %{_localstatedir}/lib/plymouth/boot-duration + +%postun +if [ $1 -eq 0 ]; then + rm -f %{_libdir}/plymouth/default.so + rm -f /boot/initrd-plymouth.img +fi + +%post core-libs -p /sbin/ldconfig +%postun core-libs -p /sbin/ldconfig + +%post graphics-libs -p /sbin/ldconfig +%postun graphics-libs -p /sbin/ldconfig + +%post theme-charge +export LIB=%{_lib} +if [ $1 -eq 1 ]; then + %{_sbindir}/plymouth-set-default-theme charge +fi + +%postun theme-charge +export LIB=%{_lib} +if [ $1 -eq 0 ]; then + if [ "$(%{_sbindir}/plymouth-set-default-theme)" == "charge" ]; then + %{_sbindir}/plymouth-set-default-theme --reset + fi +fi + +%files +%defattr(-, root, root) +%doc AUTHORS NEWS README +%dir %{_datadir}/plymouth +%dir %{_datadir}/plymouth/themes +%dir %{_datadir}/plymouth/themes/details +%dir %{_datadir}/plymouth/themes/text +%dir %{_libexecdir}/plymouth +%dir %{_localstatedir}/lib/plymouth +%dir %{_libdir}/plymouth/renderers +%dir %{_sysconfdir}/plymouth +%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/plymouth/plymouthd.conf +%config(noreplace) %{_sysconfdir}/logrotate.d/bootlog +%{plymouthdaemon_execdir}/plymouthd +%{plymouthclient_execdir}/plymouth +%{_bindir}/plymouth +%{_libdir}/plymouth/details.so +%{_libdir}/plymouth/text.so +%{_libdir}/plymouth/renderers/drm* +%{_libdir}/plymouth/renderers/frame-buffer* +%{_datadir}/plymouth/default-boot-duration +%{_datadir}/plymouth/themes/details/details.plymouth +%{_datadir}/plymouth/themes/text/text.plymouth +%{_datadir}/plymouth/plymouthd.defaults +%{_localstatedir}/run/plymouth +%{_localstatedir}/spool/plymouth +%{_mandir}/man?/* +%ghost %{_localstatedir}/lib/plymouth/boot-duration +%{_prefix}/lib/systemd/system/* + +%files devel +%defattr(-, root, root) +%{plymouth_libdir}/libply.so +%{plymouth_libdir}/libply-splash-core.so +%{_libdir}/libply-boot-client.so +%{_libdir}/libply-splash-graphics.so +%{_libdir}/pkgconfig/ply-splash-core.pc +%{_libdir}/pkgconfig/ply-splash-graphics.pc +%{_libdir}/pkgconfig/ply-boot-client.pc +%{_libdir}/plymouth/renderers/x11* +%{_includedir}/plymouth-1 + +%files core-libs +%defattr(-, root, root) +%{plymouth_libdir}/libply.so.* +%{plymouth_libdir}/libply-splash-core.so.* +%{_libdir}/libply-boot-client.so.* +%dir %{_libdir}/plymouth + +%files graphics-libs +%defattr(-, root, root) +%{_libdir}/libply-splash-graphics.so.* + +%files scripts +%defattr(-, root, root) +%{_sbindir}/plymouth-set-default-theme +%{_libexecdir}/plymouth/plymouth-update-initrd +%{_libexecdir}/plymouth/plymouth-generate-initrd +%{_libexecdir}/plymouth/plymouth-populate-initrd + +%files plugin-label +%defattr(-, root, root) +%{_libdir}/plymouth/label.so + +%files plugin-fade-throbber +%defattr(-, root, root) +%{_libdir}/plymouth/fade-throbber.so + +%files theme-fade-in +%defattr(-, root, root) +%dir %{_datadir}/plymouth/themes/fade-in +%{_datadir}/plymouth/themes/fade-in/bullet.png +%{_datadir}/plymouth/themes/fade-in/entry.png +%{_datadir}/plymouth/themes/fade-in/lock.png +%{_datadir}/plymouth/themes/fade-in/star.png +%{_datadir}/plymouth/themes/fade-in/fade-in.plymouth + +%files theme-spinner +%defattr(-, root, root) +%dir %{_datadir}/plymouth/themes/spinner +%{_datadir}/plymouth/themes/spinner/*.png +%{_datadir}/plymouth/themes/spinner/spinner.plymouth + +%files plugin-throbgress +%defattr(-, root, root) +%{_libdir}/plymouth/throbgress.so + +%files theme-spinfinity +%defattr(-, root, root) +%dir %{_datadir}/plymouth/themes/spinfinity +%{_datadir}/plymouth/themes/spinfinity/box.png +%{_datadir}/plymouth/themes/spinfinity/bullet.png +%{_datadir}/plymouth/themes/spinfinity/entry.png +%{_datadir}/plymouth/themes/spinfinity/lock.png +%{_datadir}/plymouth/themes/spinfinity/throbber-[0-3][0-9].png +%{_datadir}/plymouth/themes/spinfinity/spinfinity.plymouth + +%files plugin-space-flares +%defattr(-, root, root) +%{_libdir}/plymouth/space-flares.so + +%files theme-solar +%defattr(-, root, root) +%dir %{_datadir}/plymouth/themes/solar +%{_datadir}/plymouth/themes/solar/*.png +%{_datadir}/plymouth/themes/solar/solar.plymouth + +%files plugin-two-step +%defattr(-, root, root) +%{_libdir}/plymouth/two-step.so + +%files theme-charge +%defattr(-, root, root) +%dir %{_datadir}/plymouth/themes/charge +%{_datadir}/plymouth/themes/charge/*.png +%{_datadir}/plymouth/themes/charge/charge.plymouth + +%files plugin-script +%defattr(-, root, root) +%{_libdir}/plymouth/script.so + +%files theme-script +%defattr(-, root, root) +%dir %{_datadir}/plymouth/themes/script +%{_datadir}/plymouth/themes/script/*.png +%{_datadir}/plymouth/themes/script/script.script +%{_datadir}/plymouth/themes/script/script.plymouth + +%files system-theme +%defattr(-, root, root) + +%changelog +* Thu Aug 29 2019 Ray Strode - 0.8.9-0.33.20140113 +- Address crash during upgrade + Resolves: #1581197 + +* Tue Mar 26 2019 Ray Strode - 0.8.9-0.32.20140113 +- Fix race leading to duplicate output on some systems + Resolves: #1690023 + +* Mon Jan 08 2018 Ray Strode - 0.8.9-0.31.20140113 +- Change how we do scripts one more time + Resolves: #1530727 + Related: #1266085 + +* Tue Nov 07 2017 Ray Strode - 0.8.9-0.30.20140113 +- Update logrotate script to not rotate if empty + Resolves: #1507197 + +* Tue Nov 07 2017 Ray Strode - 0.8.9-0.29.20140113 +- Fall back to text mode if /dev/dri/card0 can't modeset + Resolves: #1431141 +- Remove unnecessary post scripts that rpm -V output + Resolves: #1266085 + +* Thu May 11 2017 Ray Strode - 0.8.9-0.28.20140113 +- Don't change file mode of boot.log. Instead, remember what mode + the admin set it to. + Related: #916704 +- Don't unlink boot.log before opening it. + Related: #916704 + +* Fri Mar 24 2017 Ray Strode - 0.8.3-27.20140113 +- Don't truncate boot.log. Rely on logrotate.d to carve it up. + Resolves: #916704 + +* Fri Jul 01 2016 Ray Strode - 0.8.9-0.26.20140113 +- Fix color of text progress bar + Related: #1167735 +- Fix escape key during media check of live image + Resolves: #1167735 + +* Wed May 25 2016 Ray Strode - 0.8.9-0.25.20140113 +- Read OS string from PRETTY_NAME instead of REDHAT_BUGZILLA_PRODUCT + again, this time munging it to get rid of parts we want to hide. + Related: #911553 + Resolves: #1306543 + +* Fri Oct 23 2015 Ray Strode 0.8.9-0.24.20140113 +- Fix text plugins in the same way we fixed pixel plugins + Related: #1260705 + Resolves: #1265646 + +* Fri Oct 09 2015 Ray Strode 0.8.9-0.23.20140113 +- Fix details plugin race + Related: #1260705 + Resolves: 1265646 + +* Thu Sep 24 2015 Ray Strode 0.8.9-0.22.20140113 +- Fix password prompt on some machines + Resolves: #1260705 + +* Tue Aug 11 2015 Ray Strode 0.8.9-0.21.20140113 +- Fix crash on minimal install + Related: #1159160 + +* Tue Aug 04 2015 Ray Strode 0.8.9-0.20.20140113 +- Fix crash on s390 + Resolves: 1250171 + Related: #1244858 + +* Tue Jul 28 2015 Ray Strode 0.8.9-0.19.20140113 +- Fix infinite loop at shutdown + Related: #1244858 + Resolves: 1243793 + +* Fri Jul 24 2015 Ray Strode 0.8.9-0.18.20140113 +- Don't instantiate drm renderer twice on some boots + Related: #1097174 1244858 + +* Fri Jul 24 2015 Ray Strode 0.8.9-0.17.20140113 +- Fix up last commit to ensure serial consoles force details mode + Related: #1097174 1244858 + +* Fri Jul 24 2015 Ray Strode 0.8.9-0.16.20140113 +- Ensure graphical special gets terminal even if drm driver isn't + boot_vga (more fixes for hyper-v) + Related: #1097174 1244858 + +* Mon Jul 20 2015 Ray Strode 0.8.9-0.15.20140113 +- Ship label plugin in initrd + Resolves: #801932 +- Backport udev queue detection fix which may help missing password + prompt on hyper-v + Related: #1097174 1244858 + +* Fri Jul 03 2015 Ray Strode 0.8.9-0.14.20140113 +- Fix hidden cursor after boot up on hyper-v + Resolves: #1097174 + +* Fri Oct 10 2014 Ray Strode 0.8.9-0.13.20140113 +- Resize /proc/cmdline buffer to quash coverity message + Related: #1085094 + +* Fri Oct 10 2014 Ray Strode 0.8.9-0.12.20140113 +- Fix init=/bin/sh with encrypted root fs + Resolves: #1098332 + +* Wed Oct 08 2014 Ray Strode 0.8.9-0.11.20140113 +- Add requires to appease rpmdiff + Resolves: #1085094 + +* Thu Mar 06 2014 Ray Strode 0.8.9-0.10.20140113 +- more serial console fixes + Resolves: #1058049 + +* Mon Mar 03 2014 Ray Strode 0.8.9-0.9.20140113 +- Ignore early fb devices + Resolves: #1063758 + Resolves: #1064235 + Resolves: #1066641 +- Ignore udev if using lone serial console + Resolves: #1058049 +- Fix password at start up race + Resolves: #1070707 + Resolves: #1073145 + +* Tue Feb 11 2014 Ray Strode 0.8.9-0.8.20140113 +- Enable position-independent code + Resolves: #1063953 + +* Thu Feb 06 2014 Ray Strode 0.8.9-0.7.20140113 +- Release terminal on hide-splash + Resolves: #1062334 + +* Wed Feb 05 2014 Ray Strode 0.8.9-0.6.20140113 +- Fix race causing assertion failure at startup + Resolves: #1061186 + +* Tue Jan 28 2014 Daniel Mach - 0.8.9-0.5.20140113 +- Mass rebuild 2014-01-24 + +* Fri Jan 24 2014 Ray Strode 0.8.9-0.4.20140113 +- Make booting without "rhgb" work + Resolves: #1050876 + +* Fri Jan 17 2014 Ray Strode 0.8.9-0.3.20140113 +- Read OS string from REDHAT_BUGZILLA_PRODUCT instead of PRETTY_NAME + in /etc/os-release to work around a lorax bug. + Resolves: #911553 +- Fix text splash when explicitly configured by user + Related: #911553 + Related: #1026571 + +* Thu Jan 16 2014 Ray Strode 0.8.9-0.2.20140113 +- Remove artificial 5 second delay for asking for password + Related: #1043689 + +* Wed Jan 15 2014 Ray Strode 0.8.9-0.1.20140113 +- Update to more compliant versioning scheme + Resolves: #1053769 + +* Mon Jan 13 2014 Ray Strode 0.8.9-0.2014.01.13.1 +- more udev fixes + Related: #1026571 + Related: #1043689 + +* Fri Jan 10 2014 Ray Strode 0.8.9-0.2014.01.10.2 +- Fix plymouth-set-default-theme -R + Resolves: #1045514 + +* Fri Jan 10 2014 Ray Strode 0.8.9-0.2014.01.10.1 +- Update to latest snapshot +- Fixes ask-for-password feature + Resolves: #1043689 +- Drops bogus delay when hitting escape + Resolves: #1049379 + +* Fri Dec 27 2013 Daniel Mach - 0.8.9-0.2014 +- Mass rebuild 2013-12-27 + +* Tue Dec 10 2013 Ray Strode 0.8.9-0.2013.12.10.1 +- Update to latest snapshot, but revert text splash back to tribar +- Fixes systemd unit files and lets us drop our upstreamed patches + Resolves: #1040015 +- Uses udev for device enumeration + Resolves: #1026571 +- Correct "charge" theme description + +* Fri Nov 08 2013 Ray Strode 0.8.9-0.2013.03.26.4 +- Fix unlock screen + Related: #1002219 + Resolves: #1027263 + +* Fri Oct 25 2013 Ray Strode 0.8.9-0.2013.03.26.3 +- Add features to facilitate new charge design + Related: #1002219 + +* Fri Oct 25 2013 Ray Strode 0.8.9-0.2013.03.26.2 +- Drop old compat goo +- Add improved man pages + Resolves: #948892 + +* Fri Apr 12 2013 Ray Strode 0.8.9-0.2013.03.26.1 +- Colors + Related: #796861 + +* Tue Mar 26 2013 Ray Strode 0.8.9-0.2013.03.26.0 +- Update to snapshot to fix systemd vconsole issue + +* Fri Mar 15 2013 Dave Airlie 0.8.8-7 +- drm: use dirty fb ioctl to allow plymouth work on qxl + +* Thu Feb 21 2013 Peter Robinson 0.8.8-6 +- Merge newer F18 release into rawhide + +* Thu Dec 13 2012 Ray Strode 0.8.8-5 +- Ensure fedup gets right splash screen + Related: #879295 + +* Thu Nov 15 2012 Ray Strode 0.8.8-4 +- Drop set-default-plugin compat script +- Just use upstream update-initrd + +* Fri Nov 02 2012 Ray Strode 0.8.8-3 +- More boot blocking fixes + Related: #870695 + +* Thu Nov 01 2012 Ray Strode 0.8.8-2 +- Fix crash when deactivating multiple times + Related: #870695 + +* Fri Oct 26 2012 Ray Strode 0.8.8-1 +- Latest upstream release +- includes systemd fixes and system update fixes + +* Tue Aug 21 2012 Ray Strode 0.8.7-1 +- Latest upstream release +- includes systemd fixes + +* Tue Aug 21 2012 Dave Airlie 0.8.6.2-1.2012.07.23 +- fix plymouth race at bootup breaking efi/vesa handoff. +- fix version number - its against fedora package policy to have 0.year + +* Mon Jul 23 2012 Ray Strode 0.8.6.2-0.2012.07.23 +- One more crack at #830482 (will probably need additional fixes tomorrow) + +* Mon Jul 23 2012 Tom Callaway - 0.8.6.1-3 +- fix bz704658 (thanks to Ian Pilcher for the patch), resolves issue where spinfinity theme + never goes idle and thus, never exits to gdm + +* Sat Jul 21 2012 Fedora Release Engineering - 0.8.6.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Tue Jul 10 2012 Ray Strode 0.8.6.1-1 +- Update to 0.8.6.1 since I mucked up 0.8.6 + Resolves: #830482 + +* Mon Jul 09 2012 Ray Strode 0.8.6-1 +- Update to 0.8.6 +- Fixes encrypted fs bug + Resolves: #830482 +- Adds support for offline package updates + +* Mon Jun 25 2012 Adam Jackson 0.8.5.1-3 +- Rebuild without libkms + +* Wed Jun 06 2012 Ray Strode 0.8.5.1-2 +- Add %{_prefix} to systemd service path + +* Wed Jun 06 2012 Ray Strode 0.8.5.1-1 +- Update to latest release +- Ship systemd service files +- Conflict with old systemd + +* Tue Apr 24 2012 Richard Hughes 0.8.4-0.20120319.3 +- Disable the nouveau driver as I've broken it with the new libdrm ABI + +* Tue Mar 20 2012 Daniel Drake 0.8.4-0.20120319.1 +- Don't try to build against libdrm_intel on non-intel architectures + +* Mon Mar 19 2012 Ray Strode 0.8.4-0.20120319.1 +- Update to latest snapshot + +* Mon Mar 12 2012 Ray Strode 0.8.4-0.20110810.6 +- Don't require libdrm_intel on non intel arches + +* Mon Feb 20 2012 Adam Williamson 0.8.4-0.20110810.5 +- make plymouth-scripts require plymouth (RH #794894) + +* Wed Jan 25 2012 Harald Hoyer 0.8.4-0.20110810.4 +- install everything in /usr + https://fedoraproject.org/wiki/Features/UsrMove + +* Sat Jan 14 2012 Fedora Release Engineering - 0.8.4-0.20110810.3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Thu Dec 15 2011 Ray Strode 0.8.4-0.20110809.3 +- Change spec based on suggestion from Nicolas Chauvet + to fix scriptlet error during livecd creation + Resolves: #666419 + +* Tue Nov 08 2011 Adam Jackson 0.8.4-0.20110822.3 +- Rebuild for libpng 1.5 + +* Fri Sep 02 2011 Ray Strode 0.8.4-0.20110822.2 +- Make plymouth background dark gray at the request of Mo / design + team. + +* Mon Aug 22 2011 Ray Strode 0.8.4-0.20110822.1 +- Update to latest git snapshot +- Reintroduce accidentally dropped spinner theme and systemd integration + +* Tue Aug 09 2011 Ray Strode 0.8.4-0.20110809.1 +- Rebuild + +* Fri Mar 04 2011 Ray Strode 0.8.4-0.1.20110304.1 +- retry reopening tty if we get EIO + Hopefully Resolves: #681167 + +* Fri Feb 18 2011 Ray Strode 0.8.4-0.20110419.1 +- unlock tty when reopening in case it spontaenously goes bonkers + and we need to fix it up + Resolves: #655538 + +* Wed Feb 09 2011 Christopher Aillon 0.8.4-0.20110209.2 +- Fix up obsoletes typo + +* Wed Feb 09 2011 Ray Strode 0.8.4-0.20110209.1 +- Update to latest snapshot + +* Wed Feb 09 2011 Fedora Release Engineering - 0.8.4-0.20101120.4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Fri Feb 04 2011 Ray Strode 0.8.4-0.20101119.4 +- Drop log viewer + +* Sat Jan 29 2011 Ville Skyttä - 0.8.4-0.20101119.3 +- Dir ownership fixes (#645044). + +* Fri Nov 19 2010 Ray Strode 0.8.4-0.20101119.2 +- Fix serial console issue eparis was seeing + +* Fri Nov 19 2010 Ray Strode 0.8.4-0.20101119.1 +- Update to recent snapshot + +* Tue Nov 02 2010 Ray Strode 0.8.4-0.20101002.1 +- Update to recent snapshot + +* Wed Sep 01 2010 Ray Strode 0.8.4-0.20100823.4 +- Add more Requirse + +* Thu Aug 26 2010 Ray Strode 0.8.4-0.20100823.3 +- Add more Requires + +* Thu Aug 26 2010 Ray Strode 0.8.4-0.20100823.2 +- Fix plymouth-update-initrd + It's regressed to the pre-dracut version. This commit fixes that. + +* Mon Aug 23 2010 Ray Strode 0.8.4-0.20100823.1 +- Update to newer pre-release snapshot of 0.8.4 +- Generate separate initrd in /boot + +* Sat Aug 21 2010 Ray Strode 0.8.4-0.20100821.1 +- Update to newer pre-release snapshot of 0.8.4 +- Fix bizarre-o animation during boot up. + +* Fri Jul 23 2010 Ray Strode 0.8.4-0.20100723.1 +- Update to pre-release snapshot of 0.8.4 + +* Thu Jan 14 2010 Ray Strode 0.8.0-0.20100114.2 +- Don't link plymouthd against libpng either + +* Thu Jan 14 2010 Ray Strode 0.8.0-0.20100114.1 +- Make it possible to do a basic plymouth installations without + libpng + +* Thu Jan 07 2010 Ray Strode 0.8.0-0.2009129.2 +- Drop nash dep + +* Tue Dec 22 2009 Dave Airlie 0.8.0-0.2009129.1 +- rebuild for API bump in libdrm + +* Wed Dec 09 2009 Ray Strode 0.8.0-0.2009129 +- Update to latest snapshot + +* Tue Sep 29 2009 Ray Strode 0.8.0-0.2009.10.05 +- Add new x11-renderer plugin from Charlie Brej for debugging + +* Tue Sep 29 2009 Ray Strode 0.8.0-0.2009.29.09 +- Fix escape and ask-for-password + +* Mon Sep 28 2009 Ray Strode 0.8.0-0.2009.28.09 +- Add prerelease of 0.8.0 for multihead support + +* Fri Sep 11 2009 Ray Strode 0.7.1-7 +- Go back to blue charge background (bug 522460) + +* Fri Sep 11 2009 Ray Strode 0.7.1-6 +- Remove duplicate Provides: plymouth(system-theme) + +* Thu Sep 10 2009 Ray Strode 0.7.1-5 +- Fix set_verbose error reported by yaneti. + +* Wed Sep 9 2009 Ray Strode 0.7.1-4 +- Look for inst() in dracut as well as mkinitrd bash source file +- Drop plymouth initrd for now. + +* Fri Aug 28 2009 Ray Strode 0.7.1-3 +- Create plymouth supplementary initrd in post (bug 515589) + +* Tue Aug 25 2009 Ray Strode 0.7.1-2 +- Get plugin path from plymouth instead of trying + to guess. Should fix bug 502667 + +* Tue Aug 25 2009 Ray Strode 0.7.1-1 +- Update to 0.7.1 + +* Mon Aug 24 2009 Adam Jackson 0.7.0-2 +- Set charge bgcolor to black. (#519052) + +* Tue Aug 11 2009 Ray Strode 0.7.0-1 +- Update to 0.7.0 + +* Sun Jul 26 2009 Fedora Release Engineering - 0.7.0-0.2010.05.15.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Fri May 15 2009 Ray Strode 0.7.0-0.2009.05.15.1 +- Fix spinfinity theme to point to the right image directory + (bug 500994) + +* Thu May 14 2009 Ray Strode 0.7.0-0.2009.05.14.1 +- Update to new snapshot that renames plugins to fix upgrades + somewhat (bug 499940) + +* Fri May 08 2009 Ray Strode 0.7.0-0.2009.05.08.1 +- Add some fixes for shutdown + +* Fri May 08 2009 Ray Strode 0.7.0-0.2009.05.06.4 +- Don't slow down progress updating at the end of boot + +* Thu May 07 2009 Ray Strode 0.7.0-0.2009.05.06.3 +- Change colors to transition better to gdm + +* Wed May 06 2009 Ray Strode 0.7.0-0.2009.05.06.2 +- Make "charge" theme require two-step plugin instead of solar (oops) + +* Wed May 06 2009 Ray Strode 0.7.0-0.2009.05.06.1 +- Update to "plugin-rework" branch from git + +* Wed Apr 08 2009 Jesse Keating - 0.7.0-0.2009.03.10.3 +- Drop the version on system-logos requires for now, causing hell with + other -logos providers not having the same version. + +* Wed Mar 18 2009 Ray Strode 0.7.0-0.2009.03.10.2 +- Destroy terminal on detach (may help with bug 490965) + +* Tue Mar 10 2009 Ray Strode 0.7.0-0.2009.03.10.1 +- Address one more issue with password handling. It wasn't working + well for secondary devices when using the "details" plugin. + +* Mon Mar 9 2009 Ray Strode 0.7.0-0.2009.03.09.1 +- Attempt to address some problems with password handling in the + 0.7.0 snapshots + +* Fri Mar 6 2009 Ray Strode 0.7.0-0.2009.03.06.2 +- Fix set default script + +* Fri Mar 6 2009 Ray Strode 0.7.0-0.2009.03.06.1 +- more scriptlet changes to move from solar to spinfinity + +* Fri Mar 6 2009 Ray Strode 0.7.0-0.2009.03.06 +- Updated to development snapshot +- Guess progress better on second boot of persistent live images +- Drop upstream patches +- swap "solar" and "spinfinity" scriptlet behavior + +* Tue Feb 24 2009 Ray Strode 0.6.0-3 +- Add fix-heap-corruptor patch from master. Problem + spotted by Mr. McCann. + +* Wed Dec 17 2008 Ray Strode 0.6.0-2 +- Add patch from drop-nash branch for jeremy + +* Wed Dec 3 2008 Ray Strode 0.6.0-1 +- Update to 0.6.0 + +* Sat Nov 22 2008 Matthias Clasen 0.6.0-0.2008.11.17.3.1 +- Strip %%name from %%summary + +* Mon Nov 17 2008 Ray Strode 0.6.0-0.2008.11.17.3 +- don't give error about missing default.so +- rework packaging of boot-duration to prevent .rpmnew droppings + (bug 469752) + +* Mon Nov 17 2008 Ray Strode 0.6.0-0.2008.11.17.2 +- Don't tell gdm to transition unless booting into runlevel 3 + (bug 471785) + +* Mon Nov 17 2008 Ray Strode 0.6.0-0.2008.11.17.1 +- Crawl progress bar if boot is way off course (Charlie, bug 471089) + +* Fri Nov 14 2008 Ray Strode 0.6.0-0.2008.11.14.2 +- Don't loop forever when tty returns NUL byte (bug 471498) + +* Fri Nov 14 2008 Ray Strode 0.6.0-0.2008.11.14.1 +- Generate solar background dynamically to reduce ondisk size, and + look better at various resolutions (Charlie, bug 471227) + +* Thu Nov 13 2008 Ray Strode 0.6.0-0.2008.11.12.4 +- Move Obsoletes: plymouth-text-and-details-only to base package + so people who had it installed don't end up solar on upgrade + +* Wed Nov 12 2008 Ray Strode 0.6.0-0.2008.11.12.3 +- Redo packaging to work better with minimal installs + (bug 471314) + +* Wed Nov 12 2008 Ray Strode 0.6.0-0.2008.11.12.2 +- Fix plymouth-set-default-plugin to allow external $LIB + +* Wed Nov 12 2008 Ray Strode 0.6.0-0.2008.11.12.1 +- Fix star image (Charlie, bug 471113) + +* Tue Nov 11 2008 Ray Strode 0.6.0-0.2008.11.11.2 +- Improve solar flares (Charlie) +- redirect tty again on --show-splash +- ignore subsequent --hide-splash calls after the first one +- turn off kernel printks during boot up + +* Tue Nov 11 2008 Ray Strode 0.6.0-0.2008.11.11.1 +- Disconnect from tty when init=/bin/bash (bug 471007) + +* Mon Nov 10 2008 Ray Strode 0.6.0-0.2008.11.10.5 +- Force the right arch when calling plymouth-set-default-plugin + (bug 470732) + +* Mon Nov 10 2008 Ray Strode 0.6.0-0.2008.11.10.4 +- Drop comet (bug 468705) +- make boot-duration config(noreplace) + +* Mon Nov 10 2008 Ray Strode 0.6.0-0.2008.11.10.3 +- Don't abort if no splash when root is mounted +- Actually move patches upstream + +* Mon Nov 10 2008 Ray Strode 0.6.0-0.2008.11.10.1 +- Fix feedback loop with plymouth:debug +- Move patches upstream +- Improve comet animation + +* Sun Nov 9 2008 Ray Strode 0.6.0-0.2008.11.06.4 +- Fix up more-debug patch to not assert with plymouth:nolog + (bug 470569) + +* Fri Nov 7 2008 Ray Strode 0.6.0-0.2008.11.06.3 +- add some more debug spew to help debug a problem jlaska is having + +* Thu Nov 6 2008 Ray Strode 0.6.0-0.2008.11.06.2 +- show details plugin on --hide-splash so people can see why the splash + got hidden. + +* Thu Nov 6 2008 Ray Strode 0.6.0-0.2008.11.06.1 +- Don't exit on plymouth --show-splash after sulogin +- Properly retake console after that --show-splash + +* Wed Nov 5 2008 Ray Strode 0.6.0-0.2008.11.05.1 +- reset colors on quit --retain-splash +- fix off by one in damage calculation for label + +* Tue Nov 4 2008 Ray Strode 0.6.0-0.2008.10.30.5 +- Add a sample boot-duration for livecds and first time boots + (bug 469752) + +* Mon Nov 3 2008 Jeremy Katz - 0.6.0-0.2008.10.30.4 +- Allow pre-setting the default plugin when calling plymouth-populate-initrd + +* Fri Oct 31 2008 Ray Strode 0.6.0-0.2008.10.30.3 +- Add pango minimum version to buildrequires + +* Thu Oct 30 2008 Ray Strode 0.6.0-0.2008.10.30.2 +- Update prompt text colors to be legible on new artwork + +* Thu Oct 30 2008 Ray Strode 0.6.0-0.2008.10.30.1 +- Drop upstreamed patches +- Patch from Charlie to update artwork +- Patch from Charlie to make password screen match animation better + (bug 468899) + +* Thu Oct 30 2008 Ray Strode 0.6.0-0.2008.10.27.8 +- Fix escape at password prompt (bug 467533) + +* Tue Oct 28 2008 Ray Strode 0.6.0-0.2008.10.27.7 +- Don't require /bin/plymouth before it's installed (bug 468925) + +* Tue Oct 28 2008 Ray Strode 0.6.0-0.2008.10.27.6 +- Force raw mode for keyboard input with solar and fade-in + (bug 468880) +- make sure windows get closed on exit + +* Mon Oct 27 2008 Ray Strode 0.6.0-0.2008.10.27.5 +- Make "Solar" lock icon the same as the "Spinfinity" one. + +* Mon Oct 27 2008 Ray Strode 0.6.0-0.2008.10.27.4 +- Make plymouth-libs own /usr/lib/plymouth (bug 458071) + +* Mon Oct 27 2008 Ray Strode 0.6.0-0.2008.10.27.3 +- Default to "Solar" instead of "Spinfinity" + +* Mon Oct 27 2008 Ray Strode 0.6.0-0.2008.10.27.2 +- Don't set plymouth default plugin to text in %%post + +* Mon Oct 27 2008 Ray Strode 0.6.0-0.2008.10.27.1 +- Add Charlie patch to dither in lower color modes (bug 468276) + +* Sun Oct 26 2008 Jeremy Katz - 0.6.0-0.2008.10.24.2 +- More requires changing to avoid loops (#467356) + +* Fri Oct 24 2008 Ray Strode 0.6.0-0.2008.10.24.1 +- Add updated progress bar for solar plugin from Charlie +- Log plymouth:debug output to boot log +- Ignore sigpipe signals in daemon + +* Thu Oct 23 2008 Ray Strode 0.6.0-0.2008.10.23.2 +- Bump so name of libply to hopefully force plymouth to get installed + before kernel (or at least make plymouth-libs and plymouth get installed + on the same side of kernel in the transaction). + +* Thu Oct 23 2008 Ray Strode 0.6.0-0.2008.10.23.1 +- Add patch from Charlie to align progress bar to milestones during boot up +- force tty to be sane on exit (bug 467207) + +* Thu Oct 23 2008 Ray Strode 0.6.0-0.2008.10.21.3 +- add empty files section for text-and-details-only so the subpackage + shows up. + +* Wed Oct 22 2008 Ray Strode 0.6.0-0.2008.10.21.2 +- add text-and-details-only subpackage so davej can uninstall + spinfinity, pango, cairo etc from his router. + +* Tue Oct 21 2008 Ray Strode 0.6.0-0.2008.10.21.1 +- Minor event loop changes +- drop upstream patches +- Charlie Brej fix for progress bar resetting when escape gets pressed + +* Tue Oct 21 2008 Ray Strode 0.6.0-0.2008.10.17.4 +- Don't make plymouth-libs require plymouth (more fun with 467356) + +* Mon Oct 20 2008 Ray Strode 0.6.0-0.2008.10.17.3 +- Add initscripts requires (bug 461322) + +* Mon Oct 20 2008 Ray Strode 0.6.0-0.2008.10.17.2 +- Put tty1 back in "cooked" mode when going into runlevel 3 + (bug 467207) + +* Fri Oct 17 2008 Ray Strode 0.6.0-0.2008.10.17.1 +- Clear screen in details plugin when it's done +- Make plymouth-update-initrd a small wrapper around mkinitrd instead + of the broken monstrosity it was before. + +* Fri Oct 17 2008 Ray Strode 0.6.0-0.2008.10.15.3 +- Move plymouth-set-default-plugin, plymouth-update-initrd, and + plymouth-populate-initrd to plymouth-scripts subpackage + (the last fix didn't actually help with bug 467356) + +* Fri Oct 17 2008 Ray Strode 0.6.0-0.2008.10.15.2 +- Move plymouth-set-default-plugin to -libs (might help with bug 467356) +- Fix up requires, provides and postun scripts + +* Wed Oct 15 2008 Ray Strode 0.6.0-0.2008.10.15.1 +- Don't free windows on --hide-splash (fix from Jeremy) + +* Tue Oct 14 2008 Ray Strode 0.6.0-0.2008.10.14.1 +- Solar fixes from Charlie Brej +- Better cpu usage from Charlie + +* Fri Oct 10 2008 Ray Strode 0.6.0-0.2008.10.08.2 +- Add Requires(post): nash (bug 466500) + +* Wed Oct 08 2008 Ray Strode 0.6.0-0.2008.10.08.1 +- Rework how "console=" args done again, to hopefully fix + bug 460565 + +* Mon Oct 06 2008 Ray Strode 0.6.0-0.2008.10.06.1 +- Add "Solar" plugin from Charles Brej +- Move things around so computers with separate /usr boot + (hopefully this won't break things, but it probably will) +- Make GDM show up on vt1 for all plugins + +* Tue Sep 30 2008 Jeremy Katz 0.6.0-0.2008.09.25.2 +- Remove mkinitrd requires to break the dep loop and ensure things + get installed in the right order + +* Thu Sep 25 2008 Ray Strode 0.6.0-0.2008.09.25.1 +- Add new snapshot to fold in Will Woods progress bar, and + move ajax's splash upstream, putting the old text splash + in a "pulser" subpackage + +* Tue Sep 23 2008 Ray Strode 0.6.0-0.2008.09.23.1 +- Last snapshot was broken + +* Mon Sep 22 2008 Ray Strode 0.6.0-0.2008.09.22.1 +- Update to latest snapshot to get better transition support + +* Fri Sep 19 2008 Ray Strode 0.6.0-0.2008.09.15.2 +- Turn on gdm trigger for transition + +* Mon Sep 15 2008 Ray Strode 0.6.0-0.2008.09.15.1 +- add quit command with --retain-splash option to client + +* Wed Sep 10 2008 Ray Strode 0.6.0-0.2008.09.10.1 +- Fix text rendering for certain machines + +* Mon Sep 8 2008 Ray Strode 0.6.0-0.2008.09.05.4 +- More serial console fixes (bug 460565 again) + +* Fri Sep 5 2008 Bill Nottingham 0.6.0-0.2008.09.05.3 +- make the text plugin use the system release info rather than a hardcoded 'Fedora 10' + +* Fri Sep 5 2008 Ray Strode 0.6.0-0.2008.09.05.2 +- Try to support multiple serial consoles better + (bug 460565) + +* Fri Sep 5 2008 Ray Strode 0.6.0-0.2008.09.05.1 +- Fix some confusion with password handling in details plugin + +* Wed Aug 27 2008 Ray Strode 0.6.0-0.2008.08.27.1 +- Fix another crasher for users with encrypted disks (this time in + the text plugin, not the client) + +* Wed Aug 27 2008 Ray Strode 0.6.0-0.2008.08.27 +- Update to latest snapshot +- Add the ability to show text prompts in graphical plugin +- Fix crasher for users with encrypted disks + +* Fri Aug 23 2008 Ray Strode 0.6.0-0.2008.08.22 +- Update to latest snapshot + +* Wed Aug 13 2008 Ray Strode 0.5.0-20.2008.08.13 +- Update previous patch to remove some assertions + +* Wed Aug 13 2008 Ray Strode 0.5.0-19.2008.08.13 +- add a patch that may help serial console users + +* Wed Aug 13 2008 Ray Strode 0.5.0-18.2008.08.13 +- add spool directory to file list + +* Wed Aug 13 2008 Ray Strode 0.5.0-17.2008.08.13 +- Make plymouth-gdm-hooks require plymouth-utils + +* Wed Aug 13 2008 Ray Strode 0.5.0-16.2008.08.13 +- Add a boot failure viewer to login screen (written by Matthias) + +* Tue Aug 12 2008 Adam Jackson 0.5.0-15.2008.08.08 +- plymouth-0.5.0-textbar-hotness.patch: Change the text plugin to a slightly + more traditional progress bar, to maintain the illusion of progress better + than the eternally oscillating cylon. Note: still incomplete. + +* Fri Aug 8 2008 Ray Strode - 0.5.0-14.2008.08.08 +- Don't require a modifiable text color map (may fix serial consoles) + +* Thu Aug 7 2008 Ray Strode - 0.5.0-13.2008.08.07 +- Update to new snapshot which when combined with a new mkinitrd should + make unlocking encrypted root partitions work again + +* Wed Aug 6 2008 Ray Strode - 0.5.0-12.2008.08.06 +- Update to new snapshot which fixes some assertion failures in the + client code + +* Wed Aug 6 2008 Ray Strode - 0.5.0-11.2008.08.01 +- Add Requires(post): plymouth to plugins so they get plymouth-set-default-plugin (bug 458071) + +* Tue Aug 5 2008 Ray Strode - 0.5.0-10.2008.08.01 +- Add plymouth dirs to file list (bug 457871) + +* Fri Aug 1 2008 Ray Strode - 0.5.0-9.2008.08.01 +- new plymout-populate-initrd features don't work with the set -e at the + top of it. + +* Thu Jul 31 2008 Ray Strode - 0.5.0-8.2008.08.01 +- Update to another snapshot to actually get new + plymouth-populate-initrd features + +* Thu Jul 31 2008 Ray Strode - 0.5.0-8.2008.07.31 +- Update to snapshot to get new plymouth-populate-initrd features +- Make removing rhgb use details plugin instead of exiting + +* Thu Jul 31 2008 Peter Jones - 0.5.0-7 +- Make it a mkinitrd requires instead of a nash requires (that will + still pull in nash, but we need mkinitrd for newer plymouth-populate-initrd) + +* Wed Jul 30 2008 Ray Strode - 0.5.0-6 +- Add nash requires + +* Wed Jul 9 2008 Ray Strode - 0.5.0-5 +- Use a new heuristic for finding libdir, since the old + one falls over on ia64 + +* Wed Jul 9 2008 Ray Strode - 0.5.0-4 +- add ctrl-r to rotate text color palette back to stock values + +* Tue Jul 8 2008 Ray Strode - 0.5.0-3 +- Fix populate script on ppc (bug 454353) + +* Tue Jul 1 2008 Ray Strode - 0.5.0-2 +- Pull in spinfinity by default. This whole "figure out + which plugin to use" set of scripts and scriptlets + needs work. We need to separate distro default from + user choice. + +* Thu Jul 1 2008 Ray Strode - 0.5.0-1 +- Add new client "ask-for-password" command which feeds + the user input to a program instead of standard output, + and loops when the program returns non-zero exit status. + +* Thu Jun 26 2008 Ray Strode - 0.4.5-1 +- Update to version 0.4.5 +- Make text plugin blue and less 80s + +* Wed Jun 25 2008 Ray Strode - 0.4.0-4 +- Make "Password: " show up correctly in text plugin + +* Wed Jun 25 2008 Ray Strode - 0.4.0-3 +- Require elfutils (bug 452797) + +* Sun Jun 22 2008 Ray Strode - 0.4.0-2 +- Make plymouth-set-default-plugin --reset choose the latest + installed plugin, not the earliest + +* Sun Jun 22 2008 Ray Strode - 0.4.0-1 +- Update to version 0.4.0 +- Only run if rhgb is on kernel command line +- Make text plugin more animated + +* Mon Jun 16 2008 Ray Strode - 0.3.2-2 +- dont go back to text mode on exit + +* Mon Jun 16 2008 Ray Strode - 0.3.2-1 +- Update to version 0.3.2 +- show gradient in spinfinity plugin +- Drop fade out in spinfinity plugin +- fix throbber placement +- rename graphical.so to default.so + +* Thu Jun 12 2008 Ray Strode - 0.3.1-3 +- scriplet should be preun, not postun + +* Thu Jun 12 2008 Ray Strode - 0.3.1-2 +- Fix postun scriptlet + +* Thu Jun 12 2008 Ray Strode - 0.3.1-1 +- Update to version 0.3.1 +- Don't ship generated initrd scripts in tarball + +* Thu Jun 12 2008 Ray Strode - 0.3.0-1 +- Update to version 0.3.0 +- Better plugin handling +- Better integration with mkinitrd (pending mkinitrd changes) +- random bug fixes + +* Mon Jun 9 2008 Ray Strode - 0.2.0-1 +- Update to version 0.2.0 +- Integrate more tightly with nash (pending nash changes) +- ship libs for out of tree splash plugins +- gradient support +- random bug fixes + +* Fri May 30 2008 Ray Strode - 0.1.0-1 +- Initial import, version 0.1.0