aboutsummaryrefslogtreecommitdiffstats
path: root/community/plymouth
diff options
context:
space:
mode:
authorLeo <thinkabit.ukim@gmail.com>2020-01-29 00:19:19 +0100
committerLeo <thinkabit.ukim@gmail.com>2020-01-29 00:19:19 +0100
commit7b666d29c84d5cad788815a1c9133a5c38c5f410 (patch)
tree7e0e9f567ea66bc0c2629499454d07545f6d674b /community/plymouth
parentc10f2d9b183c51fddfcb61024d01a5bd21197694 (diff)
downloadaports-7b666d29c84d5cad788815a1c9133a5c38c5f410.tar.bz2
aports-7b666d29c84d5cad788815a1c9133a5c38c5f410.tar.xz
Remove stale patches in community/
Diffstat (limited to 'community/plymouth')
-rw-r--r--community/plymouth/plymouth-add-sysmacros.patch10
-rw-r--r--community/plymouth/plymouth-git-master-20170123.patch5399
2 files changed, 0 insertions, 5409 deletions
diff --git a/community/plymouth/plymouth-add-sysmacros.patch b/community/plymouth/plymouth-add-sysmacros.patch
deleted file mode 100644
index 90c011955f..0000000000
--- a/community/plymouth/plymouth-add-sysmacros.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/src/libply-splash-core/ply-terminal.c
-+++ b/src/libply-splash-core/ply-terminal.c
-@@ -32,6 +32,7 @@
- #include <sys/socket.h>
- #include <sys/stat.h>
- #include <sys/types.h>
-+#include <sys/sysmacros.h>
- #include <termios.h>
- #include <unistd.h>
- #include <wchar.h>
diff --git a/community/plymouth/plymouth-git-master-20170123.patch b/community/plymouth/plymouth-git-master-20170123.patch
deleted file mode 100644
index 6ab412fa5d..0000000000
--- a/community/plymouth/plymouth-git-master-20170123.patch
+++ /dev/null
@@ -1,5399 +0,0 @@
-diff --git a/Makefile.am b/Makefile.am
-index 395c91b..cb6eedb 100644
---- a/Makefile.am
-+++ b/Makefile.am
-@@ -4,7 +4,7 @@ if BUILD_DOCUMENTATION
- SUBDIRS += docs
- endif
-
--DISTCHECK_CONFIGURE_FLAGS = --disable-tests --without-system-root-install
-+DISTCHECK_CONFIGURE_FLAGS = --disable-tests --disable-systemd-integration
-
- EXTRA_DIST = ChangeLog \
- README
-diff --git a/configure.ac b/configure.ac
-index aad673e..d145c69 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -1,4 +1,4 @@
--AC_INIT([plymouth],[0.9.2],[https://bugs.freedesktop.org/enter_bug.cgi?product=plymouth])
-+AC_INIT([plymouth],[0.9.3],[https://bugs.freedesktop.org/enter_bug.cgi?product=plymouth])
- AC_CONFIG_SRCDIR(src/main.c)
- AC_CONFIG_HEADER(config.h)
- AC_CONFIG_AUX_DIR(build-tools)
-@@ -11,7 +11,7 @@ AM_PROG_CC_C_O
- AC_HEADER_STDC
- AC_C_CONST
-
--AM_INIT_AUTOMAKE([dist-bzip2 no-dist-gzip])
-+AM_INIT_AUTOMAKE([dist-xz no-dist-gzip])
- m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
- AM_MAINTAINER_MODE([enable])
-
-@@ -38,9 +38,18 @@ PKG_CHECK_MODULES(IMAGE, [libpng >= 1.2.16 ])
- AC_SUBST(IMAGE_CFLAGS)
- AC_SUBST(IMAGE_LIBS)
-
--PKG_CHECK_MODULES(UDEV, [libudev]);
--AC_SUBST(UDEV_CFLAGS)
--AC_SUBST(UDEV_LIBS)
-+AC_ARG_WITH(udev, AS_HELP_STRING([--with-udev], [Add udev support]),, with_udev=yes)
-+
-+if test "x$with_udev" != "xno" ; then
-+ PKG_CHECK_MODULES(UDEV, [libudev], have_udev=yes, have_udev=no)
-+ AC_SUBST(UDEV_CFLAGS)
-+ AC_SUBST(UDEV_LIBS)
-+ if test "x$have_udev" = "xyes"; then
-+ AC_DEFINE(HAVE_UDEV, 1, [Define if have udev support])
-+ else
-+ AC_MSG_ERROR([libudev is required unless --without-udev is passed])
-+ fi
-+fi
-
- PLYMOUTH_CFLAGS=""
- PLYMOUTH_LIBS="-lm -lrt -ldl"
-@@ -117,16 +126,21 @@ if test x$enable_upstart_monitoring = xyes; then
- fi
- AM_CONDITIONAL(ENABLE_UPSTART_MONITORING, [test "$enable_upstart_monitoring" = yes])
-
--AC_ARG_ENABLE(systemd-integration, AS_HELP_STRING([--enable-systemd-integration],[coordinate boot up with systemd]),enable_systemd_integration=$enableval,enable_systemd_integration=no)
-+AC_ARG_ENABLE(systemd-integration, AS_HELP_STRING([--enable-systemd-integration],[coordinate boot up with systemd]),enable_systemd_integration=$enableval,enable_systemd_integration=yes)
- AM_CONDITIONAL(ENABLE_SYSTEMD_INTEGRATION, [test "$enable_systemd_integration" = yes])
-
- if test x$enable_systemd_integration = xyes; then
- AC_DEFINE(PLY_ENABLE_SYSTEMD_INTEGRATION, 1, [Coordinate boot up with systemd])
-- SYSTEMD_UNIT_DIR=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)
-+ AC_ARG_WITH([systemdunitdir], AC_HELP_STRING([--with-systemdunitdir=DIR],
-+ [path to systemd service directory]), [path_systemdunit=${withval}],
-+ [path_systemdunit="`$PKG_CONFIG --variable=systemdsystemunitdir systemd`"])
-+ if (test -n "${path_systemdunit}"); then
-+ SYSTEMD_UNIT_DIR="${path_systemdunit}"
-+ fi
- AC_SUBST(SYSTEMD_UNIT_DIR)
- fi
-
--AC_ARG_WITH(system-root-install, AS_HELP_STRING([--with-system-root-install],[Install client in /bin and daemon in /sbin]),with_system_root_install=${withval},with_system_root_install=yes)
-+AC_ARG_WITH(system-root-install, AS_HELP_STRING([--with-system-root-install],[Install client in /bin and daemon in /sbin]),with_system_root_install=${withval},with_system_root_install=no)
- AM_CONDITIONAL(WITH_SYSTEM_ROOT_INSTALL, [test "$with_system_root_install" = yes])
-
- if test x$with_system_root_install = xyes; then
-diff --git a/scripts/plymouth-populate-initrd.in b/scripts/plymouth-populate-initrd.in
-index 43c7f22..e3326e9 100755
---- a/scripts/plymouth-populate-initrd.in
-+++ b/scripts/plymouth-populate-initrd.in
-@@ -392,6 +392,9 @@ fi
- if [ $THEME_OVERRIDE ]; then
- conf=$INITRDDIR/${PLYMOUTH_CONFDIR}/plymouthd.conf
- echo "modifying plymouthd.conf: Theme=$PLYMOUTH_THEME_NAME" > /dev/stderr
-+ # make sure the section and key exist so we can modify them
-+ grep -q "^ *\[Daemon\]" $conf || echo "[Daemon]" >> $conf
-+ grep -q "^ *Theme *=" $conf || echo "Theme=fade-in" >> $conf
- sed -i "s/^ *Theme *=.*/# theme modified by plymouth-populate-initrd\nTheme=$PLYMOUTH_THEME_NAME/" $conf
- fi
-
-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
-@@ -21,7 +21,6 @@ libply_splash_core_HEADERS = \
- 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 \
-@@ -47,7 +46,6 @@ libply_splash_core_la_SOURCES = \
- ply-terminal.c \
- ply-pixel-buffer.c \
- ply-renderer.c \
-- ply-seat.c \
- ply-boot-splash.c
-
- MAINTAINERCLEANFILES = Makefile.in
-diff --git a/src/libply-splash-core/ply-boot-splash.c b/src/libply-splash-core/ply-boot-splash.c
-index 310d4d5..87a7a0c 100644
---- a/src/libply-splash-core/ply-boot-splash.c
-+++ b/src/libply-splash-core/ply-boot-splash.c
-@@ -57,7 +57,10 @@ struct _ply_boot_splash
- 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;
-@@ -94,160 +97,102 @@ ply_boot_splash_new (const char *theme_path,
- 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;
-+ int number_of_columns, number_of_rows;
-
-- node = ply_list_find_node (splash->seats, seat);
--
-- 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;
--
-- node = ply_list_find_node (splash->seats, seat);
-+ int number_of_columns, number_of_rows;
-
-- 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
-@@ -378,23 +323,60 @@ ply_boot_splash_unload (ply_boot_splash_t *splash)
- }
-
- 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;
-+
-+ ply_trace ("removing text displays");
-
-- node = ply_list_get_first_node (splash->seats);
-+ 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_trace ("Removing %dx%d text display", number_of_columns, number_of_rows);
-
-- ply_list_remove_node (splash->seats, node);
-+ splash->plugin_interface->remove_text_display (splash->plugin, display);
-
- node = next_node;
- }
-@@ -419,11 +401,17 @@ ply_boot_splash_free (ply_boot_splash_t *splash)
- splash);
- }
-
-- detach_from_seats (splash);
-- ply_list_free (splash->seats);
-+ 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);
-
-- if (splash->module_handle != NULL)
- ply_boot_splash_unload (splash);
-+ }
-
- if (splash->idle_trigger != NULL)
- ply_trigger_free (splash->idle_trigger);
-diff --git a/src/libply-splash-core/ply-boot-splash.h b/src/libply-splash-core/ply-boot-splash.h
-index 0ad6f22..b66ca47 100644
---- a/src/libply-splash-core/ply-boot-splash.h
-+++ b/src/libply-splash-core/ply-boot-splash.h
-@@ -33,12 +33,10 @@
- #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);
-
-@@ -50,10 +48,17 @@ ply_boot_splash_t *ply_boot_splash_new (const char *theme_path,
- bool ply_boot_splash_load (ply_boot_splash_t *splash);
- bool ply_boot_splash_load_built_in (ply_boot_splash_t *splash);
- void ply_boot_splash_unload (ply_boot_splash_t *splash);
--void ply_boot_splash_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);
-diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c
-index 67eba32..b4c33d4 100644
---- a/src/libply-splash-core/ply-device-manager.c
-+++ b/src/libply-splash-core/ply-device-manager.c
-@@ -30,7 +30,9 @@
- #include <sys/stat.h>
- #include <sys/types.h>
-
-+#ifdef HAVE_UDEV
- #include <libudev.h>
-+#endif
-
- #include "ply-logger.h"
- #include "ply-event-loop.h"
-@@ -41,27 +43,40 @@
- #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);
-+#ifdef HAVE_UDEV
-+static void create_devices_from_udev (ply_device_manager_t *manager);
-+#endif
-+
-+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;
-+ uint32_t serial_consoles_detected : 1;
-+ uint32_t renderers_activated : 1;
-+ uint32_t keyboards_activated : 1;
- };
-
- static void
-@@ -87,64 +102,66 @@ 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 bool
--drm_device_in_use (ply_device_manager_t *manager,
-- const char *device_path)
-+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->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) {
-- renderer_device_path = ply_renderer_get_device_name (renderer);
-+ 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);
-
-- if (renderer_device_path != NULL) {
-- if (strcmp (device_path, renderer_device_path) == 0) {
-- return true;
-- }
-- }
- }
-
- node = next_node;
- }
-+}
-
-- return false;
-+static void
-+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);
-+}
-+
-+#ifdef HAVE_UDEV
-+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
-@@ -196,19 +213,10 @@ fb_device_has_drm_device (ply_device_manager_t *manager,
- }
-
- 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);
-
-@@ -231,7 +239,13 @@ create_seat_for_udev_device (ply_device_manager_t *manager,
- }
-
- if (renderer_type != PLY_RENDERER_TYPE_NONE) {
-- create_seat_for_terminal_and_renderer_type (manager,
-+ 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);
-@@ -240,64 +254,26 @@ create_seat_for_udev_device (ply_device_manager_t *manager,
- }
-
- 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)
-+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 objects for %s devices",
- strcmp (subsystem, SUBSYSTEM_FRAME_BUFFER) == 0 ?
- "frame buffer" :
- subsystem);
-@@ -326,7 +302,7 @@ create_seats_for_subsystem (ply_device_manager_t *manager,
- if (udev_device_get_is_initialized (device)) {
- ply_trace ("device is initialized");
-
-- /* We only care about devices assigned to a (any) seat. Floating
-+ /* We only care about devices assigned to a (any) devices. Floating
- * devices should be ignored.
- */
- if (udev_device_has_tag (device, "seat")) {
-@@ -335,10 +311,10 @@ create_seats_for_subsystem (ply_device_manager_t *manager,
- 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");
-+ ply_trace ("device doesn't have a devices tag");
- }
- } else {
- ply_trace ("it's not initialized");
-@@ -371,17 +347,19 @@ on_udev_event (ply_device_manager_t *manager)
-
- 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);
-- else
-- ply_trace ("ignoring since we only handle subsystem %s devices after coldplug completes", subsystem);
-+ if (strcmp (subsystem, SUBSYSTEM_DRM) == 0) {
-+ if (manager->local_console_managed && manager->local_console_is_text)
-+ ply_trace ("ignoring since we're already using text splash for local console");
-+ else
-+ create_devices_for_udev_device (manager, device);
-+ } else {
-+ ply_trace ("ignoring since we only handle subsystem %s devices after timeout", 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);
-@@ -413,30 +391,7 @@ watch_for_udev_events (ply_device_manager_t *manager)
- 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;
-- }
--}
-+#endif
-
- static void
- free_terminal (char *device,
-@@ -473,6 +428,10 @@ get_terminal (ply_device_manager_t *manager,
- 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;
- }
-
-@@ -491,6 +450,23 @@ done:
- 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)
-@@ -500,15 +476,19 @@ ply_device_manager_new (const char *default_tty,
- 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);
-- ply_hashtable_insert (manager->terminals,
-- (void *) ply_terminal_get_name (manager->local_console_terminal),
-- manager->local_console_terminal);
-- 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;
-
-+#ifdef HAVE_UDEV
- if (!(flags & PLY_DEVICE_MANAGER_FLAGS_IGNORE_UDEV))
- manager->udev_context = udev_new ();
-+#else
-+ manager->flags |= PLY_DEVICE_MANAGER_FLAGS_IGNORE_UDEV;
-+#endif
-
- attach_to_event_loop (manager, ply_event_loop_get_default ());
-
-@@ -527,17 +507,24 @@ ply_device_manager_free (ply_device_manager_t *manager)
- (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);
-+
-+#ifdef HAVE_UDEV
-+ ply_event_loop_stop_watching_for_timeout (manager->loop,
-+ (ply_event_loop_timeout_handler_t)
-+ create_devices_from_udev, manager);
-+
- if (manager->udev_monitor != NULL)
- udev_monitor_unref (manager->udev_monitor);
-
- if (manager->udev_context != NULL)
- udev_unref (manager->udev_context);
-+#endif
-
- free (manager);
- }
-@@ -615,53 +602,161 @@ add_consoles_from_file (ply_device_manager_t *manager,
- }
-
- 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_seat_t *seat;
-- bool is_local_terminal = false;
-+ ply_list_t *heads;
-+ ply_list_node_t *node;
-+
-+ heads = ply_renderer_get_heads (renderer);
-
-- if (terminal != NULL && manager->local_console_terminal == terminal)
-- is_local_terminal = true;
-+ 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_text_display_t *display;
-
-- if (is_local_terminal && manager->local_console_seat != NULL) {
-- ply_trace ("trying to create seat for local console when one already exists");
-+ 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;
-+
-+ if (device_path != 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;
- }
-
-- 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)) {
-- ply_trace ("could not create seat");
-- ply_seat_free (seat);
-- return;
-+ if (renderer_type != PLY_RENDERER_TYPE_NONE) {
-+ ply_renderer_t *old_renderer = NULL;
-+ renderer = ply_renderer_new (renderer_type, device_path, terminal);
-+
-+ if (renderer != NULL && !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) {
-+ old_renderer = ply_hashtable_lookup (manager->renderers,
-+ (void *) ply_renderer_get_device_name (renderer));
-+
-+ if (old_renderer != NULL) {
-+ ply_trace ("ignoring device %s since it's alerady managed",
-+ ply_renderer_get_device_name (renderer));
-+ ply_renderer_free (renderer);
-+
-+ renderer = NULL;
-+ 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 (ply_renderer_get_device_name (renderer)), renderer);
-+ create_pixel_displays_for_renderer (manager, renderer);
-+
-+ if (manager->renderers_activated) {
-+ ply_trace ("activating renderer");
-+ ply_renderer_activate (renderer);
-+ }
-+
-+ if (terminal != NULL)
-+ ply_terminal_refresh_geometry (terminal);
-+ } 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);
- }
-
-- ply_list_append_data (manager->seats, seat);
-+ if (terminal != NULL) {
-+ create_text_displays_for_terminal (manager, terminal);
-
-- if (is_local_terminal)
-- manager->local_console_seat = seat;
-+ if (terminal == manager->local_console_terminal) {
-+ manager->local_console_is_text = renderer == NULL;
-+ manager->local_console_managed = true;
-+ }
-+ }
-
-- if (manager->seat_added_handler != NULL)
-- manager->seat_added_handler (manager->seat_event_handler_data, seat);
-+ if (keyboard != NULL && manager->keyboards_activated) {
-+ ply_trace ("activating keyboards");
-+ ply_keyboard_watch_for_input (keyboard);
-+ }
- }
-
- 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,
-+ NULL,
-+ 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;
-
-@@ -676,9 +771,11 @@ create_seats_from_terminals (ply_device_manager_t *manager)
-
- 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_seat_for_terminal,
-+ create_devices_for_terminal,
- manager);
- return true;
- }
-@@ -686,145 +783,104 @@ create_seats_from_terminals (ply_device_manager_t *manager)
- return false;
- }
-
-+#ifdef HAVE_UDEV
- 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");
-+ ply_trace ("Timeout elapsed, 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);
--}
--
--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);
-+ ply_trace ("Creating non-graphical devices, since there's no suitable graphics hardware");
-+ create_devices_for_terminal_and_renderer_type (manager,
-+ NULL,
-+ manager->local_console_terminal,
-+ PLY_RENDERER_TYPE_NONE);
- }
-+#endif
-
- static void
--on_udev_queue_changed (ply_device_manager_t *manager)
-+create_fallback_devices (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);
--}
--
--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| 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);
-+ create_devices_for_terminal_and_renderer_type (manager,
-+ NULL,
-+ manager->local_console_terminal,
-+ PLY_RENDERER_TYPE_AUTO);
- }
-
- 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;
--
-- manager->seat_added_handler = seat_added_handler;
-- manager->seat_removed_handler = seat_removed_handler;
-- manager->seat_event_handler_data = data;
--
-- /* Try to create seats for each serial device right away, if possible
-+ply_device_manager_watch_devices (ply_device_manager_t *manager,
-+ double device_timeout,
-+ 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_devices_setup;
-+
-+ 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 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;
- }
-
-+#ifdef HAVE_UDEV
- watch_for_udev_events (manager);
-- watch_for_coldplug_completion (manager);
-+ create_devices_for_subsystem (manager, SUBSYSTEM_DRM);
-+ ply_event_loop_watch_for_timeout (manager->loop,
-+ device_timeout,
-+ (ply_event_loop_timeout_handler_t)
-+ create_devices_from_udev, manager);
-+#endif
- }
-
- 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 *
-@@ -833,44 +889,49 @@ 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_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_hashtable_foreach (manager->renderers,
-+ (ply_hashtable_foreach_func_t *)
-+ activate_renderer,
-+ manager);
-
-- ply_seat_activate_renderer (seat);
-+ manager->renderers_activated = true;
-+}
-
-- 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);
-+ ply_hashtable_foreach (manager->renderers,
-+ (ply_hashtable_foreach_func_t *)
-+ deactivate_renderer,
-+ manager);
-
-- node = next_node;
-- }
-+ manager->renderers_activated = false;
- }
-
- void
-@@ -879,18 +940,20 @@ 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;
- }
-+
-+ manager->keyboards_activated = true;
- }
-
- void
-@@ -899,16 +962,18 @@ 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;
- }
-+
-+ manager->keyboards_activated = false;
- }
-diff --git a/src/libply-splash-core/ply-device-manager.h b/src/libply-splash-core/ply-device-manager.h
-index c3e6487..058f6e8 100644
---- a/src/libply-splash-core/ply-device-manager.h
-+++ b/src/libply-splash-core/ply-device-manager.h
-@@ -21,7 +21,11 @@
- #define PLY_DEVICE_MANAGER_H
-
- #include <stdbool.h>
--#include "ply-seat.h"
-+
-+#include "ply-keyboard.h"
-+#include "ply-pixel-display.h"
-+#include "ply-renderer.h"
-+#include "ply-text-display.h"
-
- typedef enum
- {
-@@ -31,20 +35,30 @@ typedef enum
- } 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,
-+ double device_timeout,
-+ 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);
-diff --git a/src/libply-splash-core/ply-keyboard.c b/src/libply-splash-core/ply-keyboard.c
-index ccf08e8..80f7694 100644
---- a/src/libply-splash-core/ply-keyboard.c
-+++ b/src/libply-splash-core/ply-keyboard.c
-@@ -93,6 +93,8 @@ struct _ply_keyboard
- 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);
-@@ -323,6 +325,12 @@ ply_keyboard_stop_watching_for_renderer_input (ply_keyboard_t *keyboard)
- 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)
- {
-@@ -369,15 +377,20 @@ 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
-@@ -385,6 +398,9 @@ 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);
-@@ -394,6 +410,8 @@ ply_keyboard_stop_watching_for_input (ply_keyboard_t *keyboard)
- ply_keyboard_stop_watching_for_terminal_input (keyboard);
- break;
- }
-+
-+ keyboard->is_active = false;
- }
-
- void
-diff --git a/src/libply-splash-core/ply-keyboard.h b/src/libply-splash-core/ply-keyboard.h
-index 23497d9..6147cc7 100644
---- a/src/libply-splash-core/ply-keyboard.h
-+++ b/src/libply-splash-core/ply-keyboard.h
-@@ -71,6 +71,7 @@ void ply_keyboard_remove_enter_handler (ply_keyboard_t *keyboard,
-
- 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
-
-diff --git a/src/libply-splash-core/ply-pixel-buffer.c b/src/libply-splash-core/ply-pixel-buffer.c
-index c1825cc..52a3f86 100644
---- a/src/libply-splash-core/ply-pixel-buffer.c
-+++ b/src/libply-splash-core/ply-pixel-buffer.c
-@@ -37,14 +37,19 @@
- #include <stdlib.h>
- #include <unistd.h>
-
-+#define ALPHA_MASK 0xff000000
-+
- struct _ply_pixel_buffer
- {
- uint32_t *bytes;
-
-- ply_rectangle_t area;
-- ply_list_t *clip_areas;
-+ ply_rectangle_t area; /* in device pixels */
-+ ply_rectangle_t logical_area; /* in logical pixels */
-+ ply_list_t *clip_areas; /* in device pixels */
-
-- ply_region_t *updated_areas;
-+ ply_region_t *updated_areas; /* in device pixels */
-+ uint32_t is_opaque : 1;
-+ int device_scale;
- };
-
- static inline void ply_pixel_buffer_blend_value_at_pixel (ply_pixel_buffer_t *buffer,
-@@ -166,6 +171,34 @@ ply_pixel_buffer_blend_value_at_pixel (ply_pixel_buffer_t *buffer,
- }
-
- static void
-+ply_rectangle_upscale (ply_rectangle_t *area,
-+ int scale)
-+{
-+ area->x *= scale;
-+ area->y *= scale;
-+ area->width *= scale;
-+ area->height *= scale;
-+}
-+
-+static void
-+ply_rectangle_downscale (ply_rectangle_t *area,
-+ int scale)
-+{
-+ area->x /= scale;
-+ area->y /= scale;
-+ area->width /= scale;
-+ area->height /= scale;
-+}
-+
-+static void
-+ply_pixel_buffer_adjust_area_for_device_scale (ply_pixel_buffer_t *buffer,
-+ ply_rectangle_t *area)
-+{
-+ ply_rectangle_upscale (area, buffer->device_scale);
-+}
-+
-+/* this function will also convert logical pixels to device pixels */
-+static void
- ply_pixel_buffer_crop_area_to_clip_area (ply_pixel_buffer_t *buffer,
- ply_rectangle_t *area,
- ply_rectangle_t *cropped_area)
-@@ -173,6 +206,7 @@ ply_pixel_buffer_crop_area_to_clip_area (ply_pixel_buffer_t *buffer,
- ply_list_node_t *node;
-
- *cropped_area = *area;
-+ ply_pixel_buffer_adjust_area_for_device_scale (buffer, cropped_area);
-
- node = ply_list_get_first_node (buffer->clip_areas);
- while (node != NULL) {
-@@ -196,8 +230,19 @@ ply_pixel_buffer_fill_area_with_pixel_value (ply_pixel_buffer_t *buffer,
- unsigned long row, column;
- ply_rectangle_t cropped_area;
-
-+ if (fill_area == NULL)
-+ fill_area = &buffer->logical_area;
-+
- ply_pixel_buffer_crop_area_to_clip_area (buffer, fill_area, &cropped_area);
-
-+ /* If we're filling the entire buffer with a fully opaque color,
-+ * then make note of it
-+ */
-+ if (fill_area == &buffer->area &&
-+ (pixel_value >> 24) == 0xff) {
-+ buffer->is_opaque = true;
-+ }
-+
- for (row = cropped_area.y; row < cropped_area.y + cropped_area.height; row++) {
- for (column = cropped_area.x; column < cropped_area.x + cropped_area.width; column++) {
- ply_pixel_buffer_blend_value_at_pixel (buffer,
-@@ -205,6 +250,8 @@ ply_pixel_buffer_fill_area_with_pixel_value (ply_pixel_buffer_t *buffer,
- pixel_value);
- }
- }
-+
-+ ply_region_add_rectangle (buffer->updated_areas, &cropped_area);
- }
-
- void
-@@ -216,6 +263,8 @@ ply_pixel_buffer_push_clip_area (ply_pixel_buffer_t *buffer,
- new_clip_area = malloc (sizeof(*new_clip_area));
-
- *new_clip_area = *clip_area;
-+ ply_pixel_buffer_adjust_area_for_device_scale (buffer, new_clip_area);
-+
- ply_list_append_data (buffer->clip_areas, new_clip_area);
- }
-
-@@ -241,9 +290,12 @@ ply_pixel_buffer_new (unsigned long width,
- buffer->bytes = (uint32_t *) calloc (height, width * sizeof(uint32_t));
- buffer->area.width = width;
- buffer->area.height = height;
-+ buffer->logical_area = buffer->area;
-+ buffer->device_scale = 1;
-
- buffer->clip_areas = ply_list_new ();
- ply_pixel_buffer_push_clip_area (buffer, &buffer->area);
-+ buffer->is_opaque = false;
-
- return buffer;
- }
-@@ -278,21 +330,36 @@ ply_pixel_buffer_get_size (ply_pixel_buffer_t *buffer,
- assert (buffer != NULL);
- assert (size != NULL);
-
-- *size = buffer->area;
-+ *size = buffer->logical_area;
- }
-
- unsigned long
- ply_pixel_buffer_get_width (ply_pixel_buffer_t *buffer)
- {
- assert (buffer != NULL);
-- return buffer->area.width;
-+ return buffer->logical_area.width;
- }
-
- unsigned long
- ply_pixel_buffer_get_height (ply_pixel_buffer_t *buffer)
- {
- assert (buffer != NULL);
-- return buffer->area.height;
-+ return buffer->logical_area.height;
-+}
-+
-+bool
-+ply_pixel_buffer_is_opaque (ply_pixel_buffer_t *buffer)
-+{
-+ assert (buffer != NULL);
-+ return buffer->is_opaque;
-+}
-+
-+void
-+ply_pixel_buffer_set_opaque (ply_pixel_buffer_t *buffer,
-+ bool is_opaque)
-+{
-+ assert (buffer != NULL);
-+ buffer->is_opaque = is_opaque;
- }
-
- ply_region_t *
-@@ -359,7 +426,7 @@ ply_pixel_buffer_fill_with_gradient (ply_pixel_buffer_t *buffer,
- ply_rectangle_t cropped_area;
-
- if (fill_area == NULL)
-- fill_area = &buffer->area;
-+ fill_area = &buffer->logical_area;
-
- ply_pixel_buffer_crop_area_to_clip_area (buffer, fill_area, &cropped_area);
-
-@@ -430,24 +497,16 @@ ply_pixel_buffer_fill_with_color (ply_pixel_buffer_t *buffer,
- double alpha)
- {
- uint32_t pixel_value;
-- ply_rectangle_t cropped_area;
-
- assert (buffer != NULL);
-
-- if (fill_area == NULL)
-- fill_area = &buffer->area;
--
-- ply_pixel_buffer_crop_area_to_clip_area (buffer, fill_area, &cropped_area);
--
- red *= alpha;
- green *= alpha;
- blue *= alpha;
-
- pixel_value = PLY_PIXEL_BUFFER_COLOR_TO_PIXEL_VALUE (red, green, blue, alpha);
-
-- ply_pixel_buffer_fill_area_with_pixel_value (buffer, &cropped_area, pixel_value);
--
-- ply_region_add_rectangle (buffer->updated_areas, &cropped_area);
-+ ply_pixel_buffer_fill_area_with_pixel_value (buffer, fill_area, pixel_value);
- }
-
- void
-@@ -456,7 +515,6 @@ ply_pixel_buffer_fill_with_hex_color_at_opacity (ply_pixel_buffer_t *buffer,
- uint32_t hex_color,
- double opacity)
- {
-- ply_rectangle_t cropped_area;
- uint32_t pixel_value;
- double red;
- double green;
-@@ -465,11 +523,6 @@ ply_pixel_buffer_fill_with_hex_color_at_opacity (ply_pixel_buffer_t *buffer,
-
- assert (buffer != NULL);
-
-- if (fill_area == NULL)
-- fill_area = &buffer->area;
--
-- ply_pixel_buffer_crop_area_to_clip_area (buffer, fill_area, &cropped_area);
--
- /* if they only gave an rgb hex number, assume an alpha of 0xff
- */
- if ((hex_color & 0xff000000) == 0)
-@@ -488,9 +541,7 @@ ply_pixel_buffer_fill_with_hex_color_at_opacity (ply_pixel_buffer_t *buffer,
-
- pixel_value = PLY_PIXEL_BUFFER_COLOR_TO_PIXEL_VALUE (red, green, blue, alpha);
-
-- ply_pixel_buffer_fill_area_with_pixel_value (buffer, &cropped_area, pixel_value);
--
-- ply_region_add_rectangle (buffer->updated_areas, &cropped_area);
-+ ply_pixel_buffer_fill_area_with_pixel_value (buffer, fill_area, pixel_value);
- }
-
- void
-@@ -502,48 +553,120 @@ ply_pixel_buffer_fill_with_hex_color (ply_pixel_buffer_t *buffer,
- hex_color, 1.0);
- }
-
-+static inline uint32_t
-+ply_pixels_interpolate (uint32_t *bytes,
-+ int width,
-+ int height,
-+ double x,
-+ double y)
-+{
-+ int ix;
-+ int iy;
-+ int i;
-+ int offset_x;
-+ int offset_y;
-+ uint32_t pixels[2][2];
-+ uint32_t reply = 0;
-+
-+ for (offset_y = 0; offset_y < 2; offset_y++) {
-+ for (offset_x = 0; offset_x < 2; offset_x++) {
-+ ix = x + offset_x;
-+ iy = y + offset_y;
-+
-+ if (ix < 0 || ix >= width || iy < 0 || iy >= height)
-+ pixels[offset_y][offset_x] = 0x00000000;
-+ else
-+ pixels[offset_y][offset_x] = bytes[ix + iy * width];
-+ }
-+ }
-+ if (!pixels[0][0] && !pixels[0][1] && !pixels[1][0] && !pixels[1][1]) return 0;
-+
-+ ix = x;
-+ iy = y;
-+ x -= ix;
-+ y -= iy;
-+ for (i = 0; i < 4; i++) {
-+ uint32_t value = 0;
-+ uint32_t mask = 0xFF << (i * 8);
-+ value += ((pixels[0][0]) & mask) * (1 - x) * (1 - y);
-+ value += ((pixels[0][1]) & mask) * x * (1 - y);
-+ value += ((pixels[1][0]) & mask) * (1 - x) * y;
-+ value += ((pixels[1][1]) & mask) * x * y;
-+ reply |= value & mask;
-+ }
-+ return reply;
-+}
-+
- void
--ply_pixel_buffer_fill_with_argb32_data_at_opacity_with_clip (ply_pixel_buffer_t *buffer,
-- ply_rectangle_t *fill_area,
-- ply_rectangle_t *clip_area,
-- uint32_t *data,
-- double opacity)
-+ply_pixel_buffer_fill_with_argb32_data_at_opacity_with_clip_and_scale (ply_pixel_buffer_t *buffer,
-+ ply_rectangle_t *fill_area,
-+ ply_rectangle_t *clip_area,
-+ uint32_t *data,
-+ double opacity,
-+ int scale)
- {
- unsigned long row, column;
- uint8_t opacity_as_byte;
-+ ply_rectangle_t logical_fill_area;
- ply_rectangle_t cropped_area;
- unsigned long x;
- unsigned long y;
-+ double scale_factor;
-
- assert (buffer != NULL);
-
-- if (fill_area == NULL)
-- fill_area = &buffer->area;
-+ if (fill_area == NULL) {
-+ fill_area = &buffer->logical_area;
-+ logical_fill_area = buffer->logical_area;
-+ } else {
-+ logical_fill_area = *fill_area;
-+ ply_rectangle_downscale (&logical_fill_area, scale);
-+ }
-
-- ply_pixel_buffer_crop_area_to_clip_area (buffer, fill_area, &cropped_area);
-+ ply_pixel_buffer_crop_area_to_clip_area (buffer, &logical_fill_area, &cropped_area);
-+
-+ if (clip_area) {
-+ ply_rectangle_t device_clip_area;
-
-- if (clip_area)
-- ply_rectangle_intersect (&cropped_area, clip_area, &cropped_area);
-+ device_clip_area = *clip_area;
-+ ply_rectangle_downscale (&device_clip_area, scale);
-+ ply_pixel_buffer_adjust_area_for_device_scale (buffer, &device_clip_area);
-+ ply_rectangle_intersect (&cropped_area, &device_clip_area, &cropped_area);
-+ }
-
- if (cropped_area.width == 0 || cropped_area.height == 0)
- return;
-
-- x = cropped_area.x - fill_area->x;
-- y = cropped_area.y - fill_area->y;
- opacity_as_byte = (uint8_t) (opacity * 255.0);
-+ scale_factor = (double)scale / buffer->device_scale;
-+ x = cropped_area.x;
-+ y = cropped_area.y;
-
-+ /* column, row are the point we want to write into, in
-+ pixel_buffer coordinate space (device pixels)
-+
-+ scale_factor * (column - fill_area->x), scale_factor * (row - fill_area->y)
-+ is the point we want to source from, in the data coordinate
-+ space */
- for (row = y; row < y + cropped_area.height; row++) {
- for (column = x; column < x + cropped_area.width; column++) {
- uint32_t pixel_value;
-
-- pixel_value = data[fill_area->width * row + column];
-+ if (buffer->device_scale == scale)
-+ pixel_value = data[fill_area->width * (row - fill_area->y) +
-+ column - fill_area->x];
-+ else
-+ pixel_value = ply_pixels_interpolate (data,
-+ fill_area->width,
-+ fill_area->height,
-+ scale_factor * column - fill_area->x,
-+ scale_factor * row - fill_area->y);
- if ((pixel_value >> 24) == 0x00)
- continue;
-
- pixel_value = make_pixel_value_translucent (pixel_value, opacity_as_byte);
- ply_pixel_buffer_blend_value_at_pixel (buffer,
-- cropped_area.x + (column - x),
-- cropped_area.y + (row - y),
-+ column, row,
- pixel_value);
- }
- }
-@@ -552,15 +675,30 @@ ply_pixel_buffer_fill_with_argb32_data_at_opacity_with_clip (ply_pixel_buffer_t
- }
-
- void
-+ply_pixel_buffer_fill_with_argb32_data_at_opacity_with_clip (ply_pixel_buffer_t *buffer,
-+ ply_rectangle_t *fill_area,
-+ ply_rectangle_t *clip_area,
-+ uint32_t *data,
-+ double opacity)
-+{
-+ ply_pixel_buffer_fill_with_argb32_data_at_opacity_with_clip_and_scale (buffer,
-+ fill_area,
-+ clip_area,
-+ data,
-+ opacity,
-+ 1);
-+}
-+
-+void
- ply_pixel_buffer_fill_with_argb32_data_at_opacity (ply_pixel_buffer_t *buffer,
- ply_rectangle_t *fill_area,
- uint32_t *data,
- double opacity)
- {
-- ply_pixel_buffer_fill_with_argb32_data_at_opacity_with_clip (buffer,
-- fill_area,
-- NULL,
-- data, opacity);
-+ ply_pixel_buffer_fill_with_argb32_data_at_opacity_with_clip_and_scale (buffer,
-+ fill_area,
-+ NULL,
-+ data, opacity, 1);
- }
-
- void
-@@ -568,10 +706,10 @@ ply_pixel_buffer_fill_with_argb32_data (ply_pixel_buffer_t *buffer,
- ply_rectangle_t *fill_area,
- uint32_t *data)
- {
-- ply_pixel_buffer_fill_with_argb32_data_at_opacity_with_clip (buffer,
-- fill_area,
-- NULL,
-- data, 1.0);
-+ ply_pixel_buffer_fill_with_argb32_data_at_opacity_with_clip_and_scale (buffer,
-+ fill_area,
-+ NULL,
-+ data, 1.0, 1);
- }
-
- void
-@@ -580,10 +718,25 @@ ply_pixel_buffer_fill_with_argb32_data_with_clip (ply_pixel_buffer_t *buffer,
- ply_rectangle_t *clip_area,
- uint32_t *data)
- {
-- ply_pixel_buffer_fill_with_argb32_data_at_opacity_with_clip (buffer,
-- fill_area,
-- clip_area,
-- data, 1.0);
-+ ply_pixel_buffer_fill_with_argb32_data_at_opacity_with_clip_and_scale (buffer,
-+ fill_area,
-+ clip_area,
-+ data, 1.0, 1);
-+}
-+
-+static void
-+ply_pixel_buffer_copy_area (ply_pixel_buffer_t *canvas,
-+ ply_pixel_buffer_t *source,
-+ int x, int y,
-+ ply_rectangle_t *cropped_area)
-+{
-+ unsigned long row;
-+
-+ for (row = y; row < y + cropped_area->height; row++) {
-+ memcpy (canvas->bytes + (cropped_area->y + row - y) * canvas->area.width + cropped_area->x,
-+ source->bytes + (row * source->area.width) + x,
-+ cropped_area->width * 4);
-+ }
- }
-
- void
-@@ -594,51 +747,51 @@ ply_pixel_buffer_fill_with_buffer_at_opacity_with_clip (ply_pixel_buffer_t *canv
- ply_rectangle_t *clip_area,
- float opacity)
- {
-- unsigned long row, column;
-- uint8_t opacity_as_byte;
-- ply_rectangle_t cropped_area;
-+ ply_rectangle_t fill_area;
- unsigned long x;
- unsigned long y;
-
- assert (canvas != NULL);
- assert (source != NULL);
-
-- cropped_area.x = x_offset;
-- cropped_area.y = y_offset;
-- cropped_area.width = source->area.width;
-- cropped_area.height = source->area.height;
-+ /* Fast path to memcpy if we need no blending or scaling */
-+ if (opacity == 1.0 && ply_pixel_buffer_is_opaque (source) &&
-+ canvas->device_scale == source->device_scale) {
-+ ply_rectangle_t cropped_area;
-
-- ply_pixel_buffer_crop_area_to_clip_area (canvas, &cropped_area, &cropped_area);
-+ cropped_area.x = x_offset;
-+ cropped_area.y = y_offset;
-+ cropped_area.width = source->logical_area.width;
-+ cropped_area.height = source->logical_area.height;
-
-- if (clip_area)
-- ply_rectangle_intersect (&cropped_area, clip_area, &cropped_area);
-+ ply_pixel_buffer_crop_area_to_clip_area (canvas, &cropped_area, &cropped_area);
-
-- if (cropped_area.width == 0 || cropped_area.height == 0)
-- return;
--
-- x = cropped_area.x - x_offset;
-- y = cropped_area.y - y_offset;
-- opacity_as_byte = (uint8_t) (opacity * 255.0);
--
-- for (row = y; row < y + cropped_area.height; row++) {
-- for (column = x; column < x + cropped_area.width; column++) {
-- uint32_t pixel_value;
-+ /* clip_area is in source device pixels, which are also canvas device pixels */
-+ if (clip_area)
-+ ply_rectangle_intersect (&cropped_area, clip_area, &cropped_area);
-
-- pixel_value = source->bytes[row * source->area.width + column];
-+ if (cropped_area.width == 0 || cropped_area.height == 0)
-+ return;
-
-- pixel_value = make_pixel_value_translucent (pixel_value, opacity_as_byte);
-+ x = cropped_area.x - x_offset;
-+ y = cropped_area.y - y_offset;
-
-- if ((pixel_value >> 24) == 0x00)
-- continue;
-+ ply_pixel_buffer_copy_area (canvas, source, x, y, &cropped_area);
-
-- ply_pixel_buffer_blend_value_at_pixel (canvas,
-- cropped_area.x + (column - x),
-- cropped_area.y + (row - y),
-- pixel_value);
-- }
-+ ply_region_add_rectangle (canvas->updated_areas, &cropped_area);
-+ } else {
-+ fill_area.x = x_offset * source->device_scale;
-+ fill_area.y = y_offset * source->device_scale;
-+ fill_area.width = source->area.width;
-+ fill_area.height = source->area.height;
-+
-+ ply_pixel_buffer_fill_with_argb32_data_at_opacity_with_clip_and_scale (canvas,
-+ &fill_area,
-+ clip_area,
-+ source->bytes,
-+ opacity,
-+ source->device_scale);
- }
--
-- ply_region_add_rectangle (canvas->updated_areas, &cropped_area);
- }
-
- void
-@@ -696,52 +849,15 @@ ply_pixel_buffer_interpolate (ply_pixel_buffer_t *buffer,
- double x,
- double y)
- {
-- int ix;
-- int iy;
- int width;
- int height;
--
-- int i;
--
-- int offset_x;
-- int offset_y;
-- uint32_t pixels[2][2];
-- uint32_t reply = 0;
- uint32_t *bytes;
-
- width = buffer->area.width;
- height = buffer->area.height;
--
--
- bytes = ply_pixel_buffer_get_argb32_data (buffer);
-
-- for (offset_y = 0; offset_y < 2; offset_y++) {
-- for (offset_x = 0; offset_x < 2; offset_x++) {
-- ix = x + offset_x;
-- iy = y + offset_y;
--
-- if (ix < 0 || ix >= width || iy < 0 || iy >= height)
-- pixels[offset_y][offset_x] = 0x00000000;
-- else
-- pixels[offset_y][offset_x] = bytes[ix + iy * width];
-- }
-- }
-- if (!pixels[0][0] && !pixels[0][1] && !pixels[1][0] && !pixels[1][1]) return 0;
--
-- ix = x;
-- iy = y;
-- x -= ix;
-- y -= iy;
-- for (i = 0; i < 4; i++) {
-- uint32_t value = 0;
-- uint32_t mask = 0xFF << (i * 8);
-- value += ((pixels[0][0]) & mask) * (1 - x) * (1 - y);
-- value += ((pixels[0][1]) & mask) * x * (1 - y);
-- value += ((pixels[1][0]) & mask) * (1 - x) * y;
-- value += ((pixels[1][1]) & mask) * x * y;
-- reply |= value & mask;
-- }
-- return reply;
-+ return ply_pixels_interpolate (bytes, width, height, x, y);
- }
-
- ply_pixel_buffer_t *
-@@ -753,7 +869,7 @@ ply_pixel_buffer_resize (ply_pixel_buffer_t *old_buffer,
- int x, y;
- double old_x, old_y;
- int old_width, old_height;
-- float scale_x, scale_y;
-+ double scale_x, scale_y;
- uint32_t *bytes;
-
- buffer = ply_pixel_buffer_new (width, height);
-@@ -852,4 +968,20 @@ ply_pixel_buffer_tile (ply_pixel_buffer_t *old_buffer,
- return buffer;
- }
-
-+int
-+ply_pixel_buffer_get_device_scale (ply_pixel_buffer_t *buffer)
-+{
-+ return buffer->device_scale;
-+}
-+
-+void
-+ply_pixel_buffer_set_device_scale (ply_pixel_buffer_t *buffer,
-+ int scale)
-+{
-+ buffer->device_scale = scale;
-+
-+ buffer->logical_area.width = buffer->area.width / scale;
-+ buffer->logical_area.height = buffer->area.height / scale;
-+}
-+
- /* 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-pixel-buffer.h b/src/libply-splash-core/ply-pixel-buffer.h
-index 7848a98..595e9bd 100644
---- a/src/libply-splash-core/ply-pixel-buffer.h
-+++ b/src/libply-splash-core/ply-pixel-buffer.h
-@@ -43,10 +43,17 @@ ply_pixel_buffer_t *ply_pixel_buffer_new (unsigned long width,
- void ply_pixel_buffer_free (ply_pixel_buffer_t *buffer);
- void ply_pixel_buffer_get_size (ply_pixel_buffer_t *buffer,
- ply_rectangle_t *size);
-+int ply_pixel_buffer_get_device_scale (ply_pixel_buffer_t *buffer);
-+void ply_pixel_buffer_set_device_scale (ply_pixel_buffer_t *buffer,
-+ int scale);
-
- unsigned long ply_pixel_buffer_get_width (ply_pixel_buffer_t *buffer);
- unsigned long ply_pixel_buffer_get_height (ply_pixel_buffer_t *buffer);
-
-+bool ply_pixel_buffer_is_opaque (ply_pixel_buffer_t *buffer);
-+void ply_pixel_buffer_set_opaque (ply_pixel_buffer_t *buffer,
-+ bool is_opaque);
-+
- ply_region_t *ply_pixel_buffer_get_updated_areas (ply_pixel_buffer_t *buffer);
-
- void ply_pixel_buffer_fill_with_color (ply_pixel_buffer_t *buffer,
-@@ -86,6 +93,12 @@ void ply_pixel_buffer_fill_with_argb32_data_at_opacity_with_clip (ply_pixel_buff
- ply_rectangle_t *clip_area,
- uint32_t *data,
- double opacity);
-+void ply_pixel_buffer_fill_with_argb32_data_at_opacity_with_clip_and_scale (ply_pixel_buffer_t *buffer,
-+ ply_rectangle_t *fill_area,
-+ ply_rectangle_t *clip_area,
-+ uint32_t *data,
-+ double opacity,
-+ int scale);
-
- void ply_pixel_buffer_fill_with_buffer_at_opacity_with_clip (ply_pixel_buffer_t *canvas,
- ply_pixel_buffer_t *source,
-diff --git a/src/libply-splash-core/ply-pixel-display.c b/src/libply-splash-core/ply-pixel-display.c
-index b061bfc..cb01a2c 100644
---- a/src/libply-splash-core/ply-pixel-display.c
-+++ b/src/libply-splash-core/ply-pixel-display.c
-@@ -81,6 +81,18 @@ ply_pixel_display_new (ply_renderer_t *renderer,
- 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)
- {
-diff --git a/src/libply-splash-core/ply-pixel-display.h b/src/libply-splash-core/ply-pixel-display.h
-index 62a36da..675c181 100644
---- a/src/libply-splash-core/ply-pixel-display.h
-+++ b/src/libply-splash-core/ply-pixel-display.h
-@@ -46,6 +46,9 @@ ply_pixel_display_t *ply_pixel_display_new (ply_renderer_t *renderer,
-
- void ply_pixel_display_free (ply_pixel_display_t *display);
-
-+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);
-+
- unsigned long ply_pixel_display_get_width (ply_pixel_display_t *display);
- unsigned long ply_pixel_display_get_height (ply_pixel_display_t *display);
-
-diff --git a/src/libply-splash-core/ply-renderer-plugin.h b/src/libply-splash-core/ply-renderer-plugin.h
-index 82ef913..f1455d3 100644
---- a/src/libply-splash-core/ply-renderer-plugin.h
-+++ b/src/libply-splash-core/ply-renderer-plugin.h
-@@ -66,6 +66,8 @@ typedef struct
-
- void (*close_input_source)(ply_renderer_backend_t *backend,
- ply_renderer_input_source_t *input_source);
-+
-+ const char * (*get_device_name)(ply_renderer_backend_t *backend);
- } ply_renderer_plugin_interface_t;
-
- #endif /* PLY_RENDERER_PLUGIN_H */
-diff --git a/src/libply-splash-core/ply-renderer.c b/src/libply-splash-core/ply-renderer.c
-index f64eac5..b9059ef 100644
---- a/src/libply-splash-core/ply-renderer.c
-+++ b/src/libply-splash-core/ply-renderer.c
-@@ -55,6 +55,7 @@ struct _ply_renderer
-
- uint32_t input_source_is_open : 1;
- uint32_t is_mapped : 1;
-+ uint32_t is_active : 1;
- };
-
- typedef const ply_renderer_plugin_interface_t *
-@@ -154,6 +155,11 @@ ply_renderer_load_plugin (ply_renderer_t *renderer,
- return false;
- }
-
-+ if (renderer->plugin_interface->get_device_name != NULL) {
-+ free (renderer->device_name);
-+ renderer->device_name = strdup (renderer->plugin_interface->get_device_name (renderer->backend));
-+ }
-+
- return true;
- }
-
-@@ -268,15 +274,19 @@ ply_renderer_open (ply_renderer_t *renderer)
- { 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;
-+ if (ply_renderer_open_plugin (renderer, known_plugins[i].path)) {
-+ renderer->is_active = true;
-+ goto out;
-+ }
- }
-
- ply_trace ("could not find suitable rendering plugin");
-- return false;
-+out:
-+ return renderer->is_active;
- }
-
- void
-@@ -284,6 +294,7 @@ ply_renderer_close (ply_renderer_t *renderer)
- {
- ply_renderer_unmap_from_device (renderer);
- ply_renderer_close_device (renderer);
-+ renderer->is_active = false;
- }
-
- void
-@@ -291,7 +302,11 @@ 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
-@@ -302,6 +317,12 @@ ply_renderer_deactivate (ply_renderer_t *renderer)
- return renderer->plugin_interface->deactivate (renderer->backend);
- }
-
-+bool
-+ply_renderer_is_active (ply_renderer_t *renderer)
-+{
-+ return renderer->is_active;
-+}
-+
- ply_list_t *
- ply_renderer_get_heads (ply_renderer_t *renderer)
- {
-diff --git a/src/libply-splash-core/ply-renderer.h b/src/libply-splash-core/ply-renderer.h
-index a019a4d..59391e1 100644
---- a/src/libply-splash-core/ply-renderer.h
-+++ b/src/libply-splash-core/ply-renderer.h
-@@ -57,6 +57,7 @@ bool ply_renderer_open (ply_renderer_t *renderer);
- void ply_renderer_close (ply_renderer_t *renderer);
- void ply_renderer_activate (ply_renderer_t *renderer);
- void ply_renderer_deactivate (ply_renderer_t *renderer);
-+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,
-diff --git a/src/libply-splash-core/ply-seat.c b/src/libply-splash-core/ply-seat.c
-deleted file mode 100644
-index 700332f..0000000
---- a/src/libply-splash-core/ply-seat.c
-+++ /dev/null
-@@ -1,381 +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 <rstrode@redhat.com>
-- */
--#include "config.h"
--#include "ply-seat.h"
--
--#include <assert.h>
--#include <errno.h>
--#include <stdint.h>
--#include <stdio.h>
--#include <stdlib.h>
--#include <unistd.h>
--
--#include "ply-boot-splash.h"
--#include "ply-event-loop.h"
--#include "ply-keyboard.h"
--#include "ply-pixel-display.h"
--#include "ply-text-display.h"
--#include "ply-list.h"
--#include "ply-logger.h"
--#include "ply-utils.h"
--
--struct _ply_seat
--{
-- ply_event_loop_t *loop;
--
-- ply_boot_splash_t *splash;
-- ply_terminal_t *terminal;
-- ply_renderer_t *renderer;
-- ply_keyboard_t *keyboard;
-- ply_list_t *text_displays;
-- ply_list_t *pixel_displays;
--
-- uint32_t renderer_active : 1;
-- uint32_t keyboard_active : 1;
--};
--
--ply_seat_t *
--ply_seat_new (ply_terminal_t *terminal)
--{
-- ply_seat_t *seat;
--
-- seat = calloc (1, sizeof(ply_seat_t));
--
-- seat->loop = ply_event_loop_get_default ();
-- seat->terminal = terminal;
-- seat->text_displays = ply_list_new ();
-- seat->pixel_displays = ply_list_new ();
--
-- return seat;
--}
--
--static void
--add_pixel_displays (ply_seat_t *seat)
--{
-- ply_list_t *heads;
-- ply_list_node_t *node;
--
-- heads = ply_renderer_get_heads (seat->renderer);
--
-- ply_trace ("Adding displays for %d heads",
-- ply_list_get_length (heads));
--
-- node = ply_list_get_first_node (heads);
-- while (node != NULL) {
-- ply_list_node_t *next_node;
-- ply_renderer_head_t *head;
-- ply_pixel_display_t *display;
--
-- head = ply_list_node_get_data (node);
-- next_node = ply_list_get_next_node (heads, node);
--
-- display = ply_pixel_display_new (seat->renderer, head);
--
-- ply_list_append_data (seat->pixel_displays, display);
--
-- node = next_node;
-- }
--}
--
--static void
--add_text_displays (ply_seat_t *seat)
--{
-- ply_text_display_t *display;
--
-- 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;
-- }
-- }
--
-- 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 keyboard");
-- ply_keyboard_stop_watching_for_input (seat->keyboard);
--}
--
--void
--ply_seat_deactivate_renderer (ply_seat_t *seat)
--{
-- if (!seat->renderer_active)
-- return;
--
-- seat->renderer_active = false;
--
-- if (seat->renderer == NULL)
-- return;
--
-- ply_trace ("deactivating renderer");
-- ply_renderer_deactivate (seat->renderer);
--}
--
--void
--ply_seat_activate_keyboard (ply_seat_t *seat)
--{
-- if (seat->keyboard_active)
-- return;
--
-- if (seat->keyboard == NULL)
-- return;
--
-- ply_trace ("activating keyboard");
-- ply_keyboard_watch_for_input (seat->keyboard);
--
-- seat->keyboard_active = true;
--}
--
--void
--ply_seat_activate_renderer (ply_seat_t *seat)
--{
-- if (seat->renderer_active)
-- return;
--
-- if (seat->renderer == NULL)
-- return;
--
-- ply_trace ("activating renderer");
-- ply_renderer_activate (seat->renderer);
--
-- seat->renderer_active = true;
--}
--
--void
--ply_seat_refresh_displays (ply_seat_t *seat)
--{
-- ply_list_node_t *node;
--
-- node = ply_list_get_first_node (seat->pixel_displays);
-- while (node != NULL) {
-- ply_pixel_display_t *display;
-- ply_list_node_t *next_node;
-- unsigned long width, height;
--
-- display = ply_list_node_get_data (node);
-- next_node = ply_list_get_next_node (seat->pixel_displays, node);
--
-- width = ply_pixel_display_get_width (display);
-- height = ply_pixel_display_get_height (display);
--
-- ply_pixel_display_draw_area (display, 0, 0, width, height);
-- node = next_node;
-- }
--
-- node = ply_list_get_first_node (seat->text_displays);
-- while (node != NULL) {
-- ply_text_display_t *display;
-- ply_list_node_t *next_node;
-- int number_of_columns, number_of_rows;
--
-- display = ply_list_node_get_data (node);
-- next_node = ply_list_get_next_node (seat->text_displays, node);
--
-- number_of_columns = ply_text_display_get_number_of_columns (display);
-- number_of_rows = ply_text_display_get_number_of_rows (display);
--
-- ply_text_display_draw_area (display, 0, 0,
-- number_of_columns,
-- number_of_rows);
-- node = next_node;
-- }
--}
--
--void
--ply_seat_close (ply_seat_t *seat)
--{
-- if (seat->renderer == NULL)
-- return;
--
-- ply_trace ("destroying renderer");
-- ply_renderer_close (seat->renderer);
-- ply_renderer_free (seat->renderer);
-- seat->renderer = NULL;
--}
--
--void
--ply_seat_set_splash (ply_seat_t *seat,
-- ply_boot_splash_t *splash)
--{
-- if (seat->splash == splash)
-- return;
--
-- if (seat->splash != NULL)
-- ply_boot_splash_detach_from_seat (splash, seat);
--
-- if (splash != NULL)
-- ply_boot_splash_attach_to_seat (splash, seat);
--
-- seat->splash = splash;
--}
--
--static void
--free_pixel_displays (ply_seat_t *seat)
--{
-- ply_list_node_t *node;
--
-- ply_trace ("freeing %d pixel displays", ply_list_get_length (seat->pixel_displays));
-- node = ply_list_get_first_node (seat->pixel_displays);
-- while (node != NULL) {
-- ply_list_node_t *next_node;
-- ply_pixel_display_t *display;
--
-- next_node = ply_list_get_next_node (seat->pixel_displays, node);
-- display = ply_list_node_get_data (node);
-- ply_pixel_display_free (display);
--
-- ply_list_remove_node (seat->pixel_displays, node);
--
-- node = next_node;
-- }
--}
--
--static void
--free_text_displays (ply_seat_t *seat)
--{
-- ply_list_node_t *node;
--
-- ply_trace ("freeing %d text displays", ply_list_get_length (seat->text_displays));
-- node = ply_list_get_first_node (seat->text_displays);
-- while (node != NULL) {
-- ply_list_node_t *next_node;
-- ply_text_display_t *display;
--
-- next_node = ply_list_get_next_node (seat->text_displays, node);
-- display = ply_list_node_get_data (node);
-- ply_text_display_free (display);
--
-- ply_list_remove_node (seat->text_displays, node);
--
-- node = next_node;
-- }
--}
--
--void
--ply_seat_free (ply_seat_t *seat)
--{
-- if (seat == NULL)
-- return;
--
-- free_pixel_displays (seat);
-- free_text_displays (seat);
-- ply_keyboard_free (seat->keyboard);
--
-- free (seat);
--}
--
--ply_list_t *
--ply_seat_get_pixel_displays (ply_seat_t *seat)
--{
-- return seat->pixel_displays;
--}
--
--ply_list_t *
--ply_seat_get_text_displays (ply_seat_t *seat)
--{
-- return seat->text_displays;
--}
--
--ply_keyboard_t *
--ply_seat_get_keyboard (ply_seat_t *seat)
--{
-- return seat->keyboard;
--}
--
--ply_renderer_t *
--ply_seat_get_renderer (ply_seat_t *seat)
--{
-- return seat->renderer;
--}
--
--/* vim: set ts=4 sw=4 et ai ci cino={.5s,^-2,+.5s,t0,g0,e-2,n-2,p2s,(0,=.5s,:.5s */
-diff --git a/src/libply-splash-core/ply-seat.h b/src/libply-splash-core/ply-seat.h
-deleted file mode 100644
-index f9ed15d..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 <rstrode@redhat.com>
-- */
--#ifndef PLY_SEAT_H
--#define PLY_SEAT_H
--
--#include <stdarg.h>
--#include <stdbool.h>
--#include <stdint.h>
--#include <unistd.h>
--
--#include "ply-boot-splash.h"
--#include "ply-buffer.h"
--#include "ply-event-loop.h"
--#include "ply-keyboard.h"
--#include "ply-list.h"
--#include "ply-pixel-display.h"
--#include "ply-terminal.h"
--#include "ply-text-display.h"
--
--typedef struct _ply_boot_splash ply_boot_splash_t;
--typedef struct _ply_seat ply_seat_t;
--
--#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
--ply_seat_t *ply_seat_new (ply_terminal_t *terminal);
--
--void ply_seat_free (ply_seat_t *seat);
--bool ply_seat_open (ply_seat_t *seat,
-- ply_renderer_type_t renderer_type,
-- const char *device);
--bool ply_seat_is_open (ply_seat_t *seat);
--void ply_seat_deactivate_keyboard (ply_seat_t *seat);
--void ply_seat_activate_keyboard (ply_seat_t *seat);
--void ply_seat_deactivate_renderer (ply_seat_t *seat);
--void ply_seat_activate_renderer (ply_seat_t *seat);
--void ply_seat_refresh_displays (ply_seat_t *seat);
--void ply_seat_close (ply_seat_t *seat);
--void ply_seat_set_splash (ply_seat_t *seat,
-- ply_boot_splash_t *splash);
--
--ply_list_t *ply_seat_get_pixel_displays (ply_seat_t *seat);
--ply_list_t *ply_seat_get_text_displays (ply_seat_t *seat);
--ply_keyboard_t *ply_seat_get_keyboard (ply_seat_t *seat);
--ply_renderer_t *ply_seat_get_renderer (ply_seat_t *seat);
--#endif
--
--#endif /* PLY_SEAT_H */
--/* vim: set ts=4 sw=4 et ai ci cino={.5s,^-2,+.5s,t0,g0,e-2,n-2,p2s,(0,=.5s,:.5s */
-diff --git a/src/libply-splash-core/ply-terminal.c b/src/libply-splash-core/ply-terminal.c
-index 1bbeb42..a0954f2 100644
---- a/src/libply-splash-core/ply-terminal.c
-+++ b/src/libply-splash-core/ply-terminal.c
-@@ -387,8 +387,8 @@ on_tty_disconnected (ply_terminal_t *terminal)
- ply_terminal_reopen_device (terminal);
- }
-
--static bool
--ply_terminal_look_up_geometry (ply_terminal_t *terminal)
-+bool
-+ply_terminal_refresh_geometry (ply_terminal_t *terminal)
- {
- struct winsize terminal_size;
-
-@@ -551,7 +551,7 @@ ply_terminal_open_device (ply_terminal_t *terminal)
- assert (terminal->fd < 0);
- assert (terminal->fd_watch == NULL);
-
-- terminal->fd = open (terminal->name, O_RDWR | O_NOCTTY);
-+ terminal->fd = open (terminal->name, O_RDWR | O_NOCTTY | O_NONBLOCK);
-
- if (terminal->fd < 0) {
- ply_trace ("Unable to open terminal device '%s': %m", terminal->name);
-@@ -570,6 +570,8 @@ ply_terminal_open_device (ply_terminal_t *terminal)
- return PLY_TERMINAL_OPEN_RESULT_FAILURE;
- }
-
-+ ply_set_fd_as_blocking (terminal->fd);
-+
- terminal->fd_watch = ply_event_loop_watch_fd (terminal->loop, terminal->fd,
- PLY_EVENT_LOOP_FD_STATUS_HAS_DATA,
- (ply_event_handler_t) on_tty_input,
-@@ -605,7 +607,7 @@ ply_terminal_open (ply_terminal_t *terminal)
- return false;
- }
-
-- ply_terminal_look_up_geometry (terminal);
-+ ply_terminal_refresh_geometry (terminal);
-
- ply_terminal_look_up_color_palette (terminal);
- ply_terminal_save_color_palette (terminal);
-@@ -613,7 +615,7 @@ ply_terminal_open (ply_terminal_t *terminal)
- ply_event_loop_watch_signal (terminal->loop,
- SIGWINCH,
- (ply_event_handler_t)
-- ply_terminal_look_up_geometry,
-+ ply_terminal_refresh_geometry,
- terminal);
-
- if (ply_terminal_is_vt (terminal)) {
-diff --git a/src/libply-splash-core/ply-terminal.h b/src/libply-splash-core/ply-terminal.h
-index dc83ec3..7cfcc59 100644
---- a/src/libply-splash-core/ply-terminal.h
-+++ b/src/libply-splash-core/ply-terminal.h
-@@ -69,6 +69,7 @@ void ply_terminal_reset_colors (ply_terminal_t *terminal);
-
- bool ply_terminal_set_unbuffered_input (ply_terminal_t *terminal);
- bool ply_terminal_set_buffered_input (ply_terminal_t *terminal);
-+bool ply_terminal_refresh_geometry (ply_terminal_t *terminal);
-
- __attribute__((__format__ (__printf__, 2, 3)))
- void ply_terminal_write (ply_terminal_t *terminal,
-diff --git a/src/libply-splash-graphics/ply-animation.c b/src/libply-splash-graphics/ply-animation.c
-index 81348f9..323d9ed 100644
---- a/src/libply-splash-graphics/ply-animation.c
-+++ b/src/libply-splash-graphics/ply-animation.c
-@@ -353,6 +353,11 @@ ply_animation_stop_now (ply_animation_t *animation)
- 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;
-diff --git a/src/libply-splash-graphics/ply-image.c b/src/libply-splash-graphics/ply-image.c
-index f838601..8b46978 100644
---- a/src/libply-splash-graphics/ply-image.c
-+++ b/src/libply-splash-graphics/ply-image.c
-@@ -99,10 +99,13 @@ transform_to_argb32 (png_struct *png,
- blue = data[i + 2];
- alpha = data[i + 3];
-
-- red = (uint8_t) CLAMP (((red / 255.0) * (alpha / 255.0)) * 255.0, 0, 255.0);
-- green = (uint8_t) CLAMP (((green / 255.0) * (alpha / 255.0)) * 255.0,
-- 0, 255.0);
-- blue = (uint8_t) CLAMP (((blue / 255.0) * (alpha / 255.0)) * 255.0, 0, 255.0);
-+ /* pre-multiply the alpha if there's translucency */
-+ if (alpha != 0xff) {
-+ red = (uint8_t) CLAMP (((red / 255.0) * (alpha / 255.0)) * 255.0, 0, 255.0);
-+ green = (uint8_t) CLAMP (((green / 255.0) * (alpha / 255.0)) * 255.0,
-+ 0, 255.0);
-+ blue = (uint8_t) CLAMP (((blue / 255.0) * (alpha / 255.0)) * 255.0, 0, 255.0);
-+ }
-
- pixel_value = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
- memcpy (data + i, &pixel_value, sizeof(uint32_t));
-diff --git a/src/libply-splash-graphics/ply-throbber.c b/src/libply-splash-graphics/ply-throbber.c
-index c9c5bbd..f18feb6 100644
---- a/src/libply-splash-graphics/ply-throbber.c
-+++ b/src/libply-splash-graphics/ply-throbber.c
-@@ -337,6 +337,15 @@ 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;
-diff --git a/src/libply/ply-logger.h b/src/libply/ply-logger.h
-index de23181..545e64c 100644
---- a/src/libply/ply-logger.h
-+++ b/src/libply/ply-logger.h
-@@ -92,7 +92,7 @@ bool ply_logger_is_tracing_enabled (ply_logger_t *logger);
- ply_logger_flush (logger); \
- errno = _old_errno; \
- ply_logger_inject (logger, \
-- "[%s:%d] %45.45s:" format "\r\n", \
-+ "[%s:%d] %45.45s:" format "\n", \
- __FILE__, __LINE__, __func__, ## args); \
- ply_logger_flush (logger); \
- errno = _old_errno; \
-diff --git a/src/libply/ply-utils.c b/src/libply/ply-utils.c
-index 5c8510c..89e37e9 100644
---- a/src/libply/ply-utils.c
-+++ b/src/libply/ply-utils.c
-@@ -78,6 +78,8 @@
- static int errno_stack[PLY_ERRNO_STACK_SIZE];
- static int errno_stack_position = 0;
-
-+static int overridden_device_scale = 0;
-+
- bool
- ply_open_unidirectional_pipe (int *sender_fd,
- int *receiver_fd)
-@@ -421,6 +423,29 @@ ply_fd_may_block (int fd)
- return (flags & O_NONBLOCK) != 0;
- }
-
-+bool
-+ply_set_fd_as_blocking (int fd)
-+{
-+ int flags;
-+ int ret = 0;
-+
-+ assert (fd >= 0);
-+
-+ flags = fcntl (fd, F_GETFL);
-+
-+ if (flags == -1) {
-+ return false;
-+ }
-+
-+ if (flags & O_NONBLOCK) {
-+ flags &= ~O_NONBLOCK;
-+
-+ ret = fcntl (fd, F_SETFL, flags);
-+ }
-+
-+ return ret == 0;
-+}
-+
- char **
- ply_copy_string_array (const char *const *array)
- {
-@@ -936,4 +961,58 @@ out:
-
- return (pid_t) ppid;
- }
-+
-+void
-+ply_set_device_scale (int device_scale)
-+{
-+ overridden_device_scale = device_scale;
-+ ply_trace ("Device scale is set to %d", device_scale);
-+}
-+
-+/* The minimum resolution at which we turn on a device-scale of 2 */
-+#define HIDPI_LIMIT 192
-+#define HIDPI_MIN_HEIGHT 1200
-+
-+int
-+ply_get_device_scale (uint32_t width,
-+ uint32_t height,
-+ uint32_t width_mm,
-+ uint32_t height_mm)
-+{
-+ int device_scale;
-+ double dpi_x, dpi_y;
-+ const char *force_device_scale;
-+
-+ device_scale = 1;
-+
-+ if ((force_device_scale = getenv ("PLYMOUTH_FORCE_SCALE")))
-+ return strtoul (force_device_scale, NULL, 0);
-+
-+ if (overridden_device_scale != 0)
-+ return overridden_device_scale;
-+
-+ if (height < HIDPI_MIN_HEIGHT)
-+ return 1;
-+
-+ /* Somebody encoded the aspect ratio (16/9 or 16/10)
-+ * instead of the physical size */
-+ if ((width_mm == 160 && height_mm == 90) ||
-+ (width_mm == 160 && height_mm == 100) ||
-+ (width_mm == 16 && height_mm == 9) ||
-+ (width_mm == 16 && height_mm == 10))
-+ return 1;
-+
-+ if (width_mm > 0 && height_mm > 0) {
-+ dpi_x = (double)width / (width_mm / 25.4);
-+ dpi_y = (double)height / (height_mm / 25.4);
-+ /* We don't completely trust these values so both
-+ must be high, and never pick higher ratio than
-+ 2 automatically */
-+ if (dpi_x > HIDPI_LIMIT && dpi_y > HIDPI_LIMIT)
-+ device_scale = 2;
-+ }
-+
-+ return device_scale;
-+}
-+
- /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */
-diff --git a/src/libply/ply-utils.h b/src/libply/ply-utils.h
-index b9a28d0..c46603e 100644
---- a/src/libply/ply-utils.h
-+++ b/src/libply/ply-utils.h
-@@ -82,6 +82,7 @@ bool ply_read_uint32 (int fd,
- bool ply_fd_has_data (int fd);
- bool ply_fd_can_take_data (int fd);
- bool ply_fd_may_block (int fd);
-+bool ply_set_fd_as_blocking (int fd);
- char **ply_copy_string_array (const char *const *array);
- void ply_free_string_array (char **array);
- bool ply_string_has_prefix (const char *string,
-@@ -120,6 +121,13 @@ int ply_utf8_string_get_length (const char *string,
- char *ply_get_process_command_line (pid_t pid);
- pid_t ply_get_process_parent_pid (pid_t pid);
-
-+void ply_set_device_scale (int device_scale);
-+
-+int ply_get_device_scale (uint32_t width,
-+ uint32_t height,
-+ uint32_t width_mm,
-+ uint32_t height_mm);
-+
- #endif
-
- #endif /* PLY_UTILS_H */
-diff --git a/src/main.c b/src/main.c
-index da6e95d..0864e5e 100644
---- a/src/main.c
-+++ b/src/main.c
-@@ -107,6 +107,7 @@ typedef struct
-
- double start_time;
- double splash_delay;
-+ double device_timeout;
-
- char kernel_command_line[PLY_MAX_COMMAND_LINE_SIZE];
- uint32_t kernel_command_line_is_set : 1;
-@@ -136,8 +137,8 @@ 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 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);
-@@ -293,8 +294,8 @@ load_settings (state_t *state,
- char **theme_path)
- {
- ply_key_file_t *key_file = NULL;
-- const char *delay_string;
- bool settings_loaded = false;
-+ const char *scale_string;
- const char *splash_string;
-
- ply_trace ("Trying to load %s", path);
-@@ -313,6 +314,8 @@ load_settings (state_t *state,
- splash_string, splash_string);
-
- if (isnan (state->splash_delay)) {
-+ const char *delay_string;
-+
- delay_string = ply_key_file_get_value (key_file, "Daemon", "ShowDelay");
-
- if (delay_string != NULL) {
-@@ -321,6 +324,23 @@ load_settings (state_t *state,
- }
- }
-
-+ if (isnan (state->device_timeout)) {
-+ const char *timeout_string;
-+
-+ timeout_string = ply_key_file_get_value (key_file, "Daemon", "DeviceTimeout");
-+
-+ if (timeout_string != NULL) {
-+ state->device_timeout = atof (timeout_string);
-+ ply_trace ("Device timeout is set to %lf", state->device_timeout);
-+ }
-+ }
-+
-+ scale_string = ply_key_file_get_value (key_file, "Daemon", "DeviceScale");
-+
-+ if (scale_string != NULL) {
-+ ply_set_device_scale (strtoul (scale_string, NULL, 0));
-+ }
-+
- settings_loaded = true;
- out:
- ply_key_file_free (key_file);
-@@ -345,6 +365,8 @@ show_detailed_splash (state_t *state)
- }
-
- state->boot_splash = splash;
-+
-+ show_messages (state);
- update_display (state);
- }
-
-@@ -419,6 +441,17 @@ find_override_splash (state_t *state)
- }
-
- static void
-+find_force_scale (state_t *state)
-+{
-+ const char *scale_string;
-+
-+ scale_string = command_line_get_string_after_prefix (state->kernel_command_line, "plymouth.force-scale=");
-+
-+ if (scale_string != NULL)
-+ ply_set_device_scale (strtoul (scale_string, NULL, 0));
-+}
-+
-+static void
- find_system_default_splash (state_t *state)
- {
- if (state->system_default_splash_path != NULL)
-@@ -492,6 +525,7 @@ show_default_splash (state_t *state)
- return;
- }
-
-+ show_messages (state);
- update_display (state);
- }
-
-@@ -520,14 +554,14 @@ on_ask_for_password (state_t *state,
- * 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) {
-- ply_trace ("seats open now, showing splash immediately");
-+ if (has_displays) {
-+ ply_trace ("displays available now, showing splash immediately");
- show_splash (state);
- } else {
- ply_trace ("splash still coming up, waiting a bit");
-@@ -891,7 +925,7 @@ plymouth_should_show_default_splash (state_t *state)
- 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");
-@@ -910,49 +944,20 @@ on_show_splash (state_t *state)
- }
-
- 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) {
-- ply_trace ("at least one seat already open, so loading splash");
-+ if (has_displays) {
-+ 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)
-@@ -991,23 +996,9 @@ show_splash (state_t *state)
- }
-
- 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 && !state->is_inactive) {
-- 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)
-@@ -1024,6 +1015,90 @@ on_seat_added (state_t *state,
- 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);
-+
-+ 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
-@@ -1033,12 +1108,25 @@ 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);
-+ ply_device_manager_watch_devices (state->device_manager,
-+ state->device_timeout,
-+ (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
-@@ -1507,22 +1595,52 @@ on_enter (state_t *state,
- }
-
- 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_seat_t *seat;
-+ ply_pixel_display_t *pixel_display;
- ply_list_node_t *next_node;
-
-- seat = ply_list_node_get_data (node);
-- next_node = ply_list_get_next_node (seats, node);
-+ pixel_display = ply_list_node_get_data (node);
-+ next_node = ply_list_get_next_node (pixel_displays, node);
-
-- ply_boot_splash_attach_to_seat (splash, seat);
-+ 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_text_display_t *text_display;
-+ ply_list_node_t *next_node;
-+
-+ text_display = ply_list_node_get_data (node);
-+ next_node = ply_list_get_next_node (text_displays, node);
-+
-+ ply_boot_splash_add_text_display (splash, text_display);
-
- node = next_node;
- }
-@@ -1623,7 +1741,7 @@ show_theme (state_t *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);
-
- splash_mode = get_splash_mode_from_mode (state->mode);
-@@ -1641,7 +1759,6 @@ show_theme (state_t *state,
- #endif
-
- ply_device_manager_activate_keyboards (state->device_manager);
-- show_messages (state);
-
- return splash;
- }
-@@ -1978,12 +2095,15 @@ 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;
-@@ -2191,6 +2311,7 @@ main (int argc,
-
- state.progress = ply_progress_new ();
- state.splash_delay = NAN;
-+ state.device_timeout = NAN;
-
- ply_progress_load_cache (state.progress,
- get_cache_file_for_mode (state.mode));
-@@ -2223,6 +2344,8 @@ main (int argc,
- state.splash_delay = NAN;
- }
-
-+ find_force_scale (&state);
-+
- load_devices (&state, device_manager_flags);
-
- ply_trace ("entering event loop");
-diff --git a/src/plugins/controls/label/plugin.c b/src/plugins/controls/label/plugin.c
-index 5edce3b..acba52b 100644
---- a/src/plugins/controls/label/plugin.c
-+++ b/src/plugins/controls/label/plugin.c
-@@ -113,15 +113,18 @@ get_cairo_context_for_pixel_buffer (ply_label_plugin_control_t *label,
- cairo_t *cairo_context;
- unsigned char *data;
- ply_rectangle_t size;
-+ uint32_t scale;
-
- data = (unsigned char *) ply_pixel_buffer_get_argb32_data (pixel_buffer);
- ply_pixel_buffer_get_size (pixel_buffer, &size);
-+ scale = ply_pixel_buffer_get_device_scale (pixel_buffer);
-
- cairo_surface = cairo_image_surface_create_for_data (data,
- CAIRO_FORMAT_ARGB32,
-- size.width,
-- size.height,
-- size.width * 4);
-+ size.width * scale,
-+ size.height * scale,
-+ size.width * scale * 4);
-+ cairo_surface_set_device_scale (cairo_surface, scale, scale);
- cairo_context = cairo_create (cairo_surface);
- cairo_surface_destroy (cairo_surface);
-
-diff --git a/src/plugins/renderers/drm/Makefile.am b/src/plugins/renderers/drm/Makefile.am
-index 747f202..271b17f 100644
---- a/src/plugins/renderers/drm/Makefile.am
-+++ b/src/plugins/renderers/drm/Makefile.am
-@@ -16,12 +16,7 @@ drm_la_LDFLAGS = -module -avoid-version -export-dynamic
- drm_la_LIBADD = $(PLYMOUTH_LIBS) $(DRM_LIBS) \
- ../../../libply/libply.la \
- ../../../libply-splash-core/libply-splash-core.la
--drm_la_SOURCES = $(srcdir)/plugin.c \
-- $(srcdir)/ply-renderer-driver.h
--drm_la_SOURCES += $(srcdir)/ply-renderer-generic-driver.h \
-- $(srcdir)/ply-renderer-generic-driver.c
--
--
-+drm_la_SOURCES = $(srcdir)/plugin.c
-
- endif
-
-diff --git a/src/plugins/renderers/drm/plugin.c b/src/plugins/renderers/drm/plugin.c
-index 45aab7d..b93e8e4 100644
---- a/src/plugins/renderers/drm/plugin.c
-+++ b/src/plugins/renderers/drm/plugin.c
-@@ -54,12 +54,11 @@
- #include "ply-hashtable.h"
- #include "ply-rectangle.h"
- #include "ply-region.h"
-+#include "ply-utils.h"
- #include "ply-terminal.h"
-
- #include "ply-renderer.h"
- #include "ply-renderer-plugin.h"
--#include "ply-renderer-driver.h"
--#include "ply-renderer-generic-driver.h"
-
- #define BYTES_PER_PIXEL (4)
-
-@@ -92,15 +91,27 @@ struct _ply_renderer_input_source
- void *user_data;
- };
-
-+typedef struct
-+{
-+ uint32_t id;
-+
-+ uint32_t handle;
-+ uint32_t width;
-+ uint32_t height;
-+ uint32_t row_stride;
-+
-+ void *map_address;
-+ uint32_t map_size;
-+ int map_count;
-+
-+ uint32_t added_fb : 1;
-+} ply_renderer_buffer_t;
-+
- struct _ply_renderer_backend
- {
- ply_event_loop_t *loop;
- ply_terminal_t *terminal;
-
-- ply_renderer_driver_interface_t *driver_interface;
-- ply_renderer_driver_t *driver;
-- uint32_t driver_supports_mapping_console;
--
- int device_fd;
- char *device_name;
- drmModeRes *resources;
-@@ -109,11 +120,14 @@ struct _ply_renderer_backend
- ply_list_t *heads;
- ply_hashtable_t *heads_by_connector_id;
-
-+ ply_hashtable_t *output_buffers;
-+
- int32_t dither_red;
- int32_t dither_green;
- int32_t dither_blue;
-
- uint32_t is_active : 1;
-+ uint32_t requires_explicit_flushing : 1;
- };
-
- ply_renderer_plugin_interface_t *ply_renderer_backend_get_interface (void);
-@@ -127,6 +141,233 @@ static void flush_head (ply_renderer_backend_t *backend,
- ply_renderer_head_t *head);
-
- static bool
-+ply_renderer_buffer_map (ply_renderer_backend_t *backend,
-+ ply_renderer_buffer_t *buffer)
-+{
-+ struct drm_mode_map_dumb map_dumb_buffer_request;
-+ void *map_address;
-+
-+ if (buffer->map_address != MAP_FAILED) {
-+ buffer->map_count++;
-+ return true;
-+ }
-+
-+ memset (&map_dumb_buffer_request, 0, sizeof(struct drm_mode_map_dumb));
-+ map_dumb_buffer_request.handle = buffer->handle;
-+ if (drmIoctl (backend->device_fd, DRM_IOCTL_MODE_MAP_DUMB, &map_dumb_buffer_request) < 0) {
-+ ply_trace ("Could not map GEM object %u: %m", buffer->handle);
-+ return false;
-+ }
-+
-+ map_address = mmap (0, buffer->map_size,
-+ PROT_READ | PROT_WRITE, MAP_SHARED,
-+ backend->device_fd, map_dumb_buffer_request.offset);
-+
-+ if (map_address == MAP_FAILED)
-+ return false;
-+
-+ buffer->map_address = map_address;
-+ buffer->map_count++;
-+
-+ return true;
-+}
-+
-+static void
-+ply_renderer_buffer_unmap (ply_renderer_backend_t *backend,
-+ ply_renderer_buffer_t *buffer)
-+{
-+ buffer->map_count--;
-+
-+ assert (buffer->map_count >= 0);
-+}
-+
-+static ply_renderer_buffer_t *
-+ply_renderer_buffer_new (ply_renderer_backend_t *backend,
-+ uint32_t width,
-+ uint32_t height)
-+{
-+ ply_renderer_buffer_t *buffer;
-+ struct drm_mode_create_dumb create_dumb_buffer_request;
-+
-+ buffer = calloc (1, sizeof(ply_renderer_buffer_t));
-+ buffer->width = width;
-+ buffer->height = height;
-+ buffer->map_address = MAP_FAILED;
-+
-+ memset (&create_dumb_buffer_request, 0, sizeof(struct drm_mode_create_dumb));
-+
-+ create_dumb_buffer_request.width = width;
-+ create_dumb_buffer_request.height = height;
-+ create_dumb_buffer_request.bpp = 32;
-+ create_dumb_buffer_request.flags = 0;
-+
-+ if (drmIoctl (backend->device_fd,
-+ DRM_IOCTL_MODE_CREATE_DUMB,
-+ &create_dumb_buffer_request) < 0) {
-+ free (buffer);
-+ ply_trace ("Could not allocate GEM object for frame buffer: %m");
-+ return NULL;
-+ }
-+
-+ buffer->handle = create_dumb_buffer_request.handle;
-+ buffer->row_stride = create_dumb_buffer_request.pitch;
-+ buffer->map_size = create_dumb_buffer_request.size;
-+
-+ ply_trace ("returning %ux%u buffer with stride %u",
-+ width, height, buffer->row_stride);
-+
-+ return buffer;
-+}
-+
-+static void
-+ply_renderer_buffer_free (ply_renderer_backend_t *backend,
-+ ply_renderer_buffer_t *buffer)
-+{
-+ struct drm_mode_destroy_dumb destroy_dumb_buffer_request;
-+
-+ if (buffer->added_fb)
-+ drmModeRmFB (backend->device_fd, buffer->id);
-+
-+ if (buffer->map_address != MAP_FAILED) {
-+ munmap (buffer->map_address, buffer->map_size);
-+ buffer->map_address = MAP_FAILED;
-+ }
-+
-+ memset (&destroy_dumb_buffer_request, 0, sizeof(struct drm_mode_destroy_dumb));
-+ destroy_dumb_buffer_request.handle = buffer->handle;
-+
-+ if (drmIoctl (backend->device_fd,
-+ DRM_IOCTL_MODE_DESTROY_DUMB,
-+ &destroy_dumb_buffer_request) < 0)
-+ ply_trace ("Could not deallocate GEM object %u: %m", buffer->handle);
-+
-+ free (buffer);
-+}
-+
-+static ply_renderer_buffer_t *
-+get_buffer_from_id (ply_renderer_backend_t *backend,
-+ uint32_t id)
-+{
-+ static ply_renderer_buffer_t *buffer;
-+
-+ buffer = ply_hashtable_lookup (backend->output_buffers, (void *) (uintptr_t) id);
-+
-+ return buffer;
-+}
-+
-+static uint32_t
-+create_output_buffer (ply_renderer_backend_t *backend,
-+ unsigned long width,
-+ unsigned long height,
-+ unsigned long *row_stride)
-+{
-+ ply_renderer_buffer_t *buffer;
-+
-+ buffer = ply_renderer_buffer_new (backend, width, height);
-+
-+ if (buffer == NULL) {
-+ ply_trace ("Could not allocate GEM object for frame buffer: %m");
-+ return 0;
-+ }
-+
-+ if (drmModeAddFB (backend->device_fd, width, height,
-+ 24, 32, buffer->row_stride, buffer->handle,
-+ &buffer->id) != 0) {
-+ ply_trace ("Could not set up GEM object as frame buffer: %m");
-+ ply_renderer_buffer_free (backend, buffer);
-+ return 0;
-+ }
-+
-+ *row_stride = buffer->row_stride;
-+
-+ buffer->added_fb = true;
-+ ply_hashtable_insert (backend->output_buffers,
-+ (void *) (uintptr_t) buffer->id,
-+ buffer);
-+
-+ return buffer->id;
-+}
-+
-+static bool
-+map_buffer (ply_renderer_backend_t *backend,
-+ uint32_t buffer_id)
-+{
-+ ply_renderer_buffer_t *buffer;
-+
-+ buffer = get_buffer_from_id (backend, buffer_id);
-+
-+ assert (buffer != NULL);
-+
-+ return ply_renderer_buffer_map (backend, buffer);
-+}
-+
-+static void
-+unmap_buffer (ply_renderer_backend_t *backend,
-+ uint32_t buffer_id)
-+{
-+ ply_renderer_buffer_t *buffer;
-+
-+ buffer = get_buffer_from_id (backend, buffer_id);
-+
-+ assert (buffer != NULL);
-+
-+ ply_renderer_buffer_unmap (backend, buffer);
-+}
-+
-+static char *
-+begin_flush (ply_renderer_backend_t *backend,
-+ uint32_t buffer_id)
-+{
-+ ply_renderer_buffer_t *buffer;
-+
-+ buffer = get_buffer_from_id (backend, buffer_id);
-+
-+ assert (buffer != NULL);
-+
-+ return buffer->map_address;
-+}
-+
-+static void
-+end_flush (ply_renderer_backend_t *backend,
-+ uint32_t buffer_id)
-+{
-+ ply_renderer_buffer_t *buffer;
-+
-+ buffer = get_buffer_from_id (backend, buffer_id);
-+
-+ assert (buffer != NULL);
-+
-+ if (backend->requires_explicit_flushing) {
-+ struct drm_clip_rect flush_area;
-+ int ret;
-+
-+ flush_area.x1 = 0;
-+ flush_area.y1 = 0;
-+ flush_area.x2 = buffer->width;
-+ flush_area.y2 = buffer->height;
-+
-+ ret = drmModeDirtyFB (backend->device_fd, buffer->id, &flush_area, 1);
-+
-+ if (ret == -ENOSYS)
-+ backend->requires_explicit_flushing = false;
-+ }
-+}
-+
-+static void
-+destroy_output_buffer (ply_renderer_backend_t *backend,
-+ uint32_t buffer_id)
-+{
-+ ply_renderer_buffer_t *buffer;
-+
-+ buffer = ply_hashtable_remove (backend->output_buffers,
-+ (void *) (uintptr_t) buffer_id);
-+
-+ assert (buffer != NULL);
-+
-+ ply_renderer_buffer_free (backend, buffer);
-+}
-+
-+static bool
- ply_renderer_head_add_connector (ply_renderer_head_t *head,
- drmModeConnector *connector,
- int connector_mode_index)
-@@ -185,6 +426,11 @@ ply_renderer_head_new (ply_renderer_backend_t *backend,
- assert (ply_array_get_size (head->connector_ids) > 0);
-
- head->pixel_buffer = ply_pixel_buffer_new (head->area.width, head->area.height);
-+ ply_pixel_buffer_set_device_scale (head->pixel_buffer,
-+ ply_get_device_scale (head->area.width,
-+ head->area.height,
-+ connector->mmWidth,
-+ connector->mmHeight));
-
- ply_trace ("Creating %ldx%ld renderer head", head->area.width, head->area.height);
- ply_pixel_buffer_fill_with_color (head->pixel_buffer, NULL,
-@@ -241,25 +487,21 @@ ply_renderer_head_map (ply_renderer_backend_t *backend,
-
- assert (backend != NULL);
- assert (backend->device_fd >= 0);
-- assert (backend->driver_interface != NULL);
-- assert (backend->driver != NULL);
-+ assert (backend != NULL);
-
- assert (head != NULL);
-
- ply_trace ("Creating buffer for %ldx%ld renderer head", head->area.width, head->area.height);
-- head->scan_out_buffer_id =
-- backend->driver_interface->create_buffer (backend->driver,
-- head->area.width, head->area.height,
-- &head->row_stride);
-+ head->scan_out_buffer_id = create_output_buffer (backend,
-+ head->area.width, head->area.height,
-+ &head->row_stride);
-
- if (head->scan_out_buffer_id == 0)
- return false;
-
- ply_trace ("Mapping buffer for %ldx%ld renderer head", head->area.width, head->area.height);
-- if (!backend->driver_interface->map_buffer (backend->driver,
-- head->scan_out_buffer_id)) {
-- backend->driver_interface->destroy_buffer (backend->driver,
-- head->scan_out_buffer_id);
-+ if (!map_buffer (backend, head->scan_out_buffer_id)) {
-+ destroy_output_buffer (backend, head->scan_out_buffer_id);
- head->scan_out_buffer_id = 0;
- return false;
- }
-@@ -271,8 +513,7 @@ ply_renderer_head_map (ply_renderer_backend_t *backend,
-
- scan_out_set = reset_scan_out_buffer_if_needed (backend, head);
- if (!scan_out_set && backend->is_active) {
-- backend->driver_interface->destroy_buffer (backend->driver,
-- head->scan_out_buffer_id);
-+ destroy_output_buffer (backend, head->scan_out_buffer_id);
- head->scan_out_buffer_id = 0;
- return false;
- }
-@@ -285,11 +526,9 @@ ply_renderer_head_unmap (ply_renderer_backend_t *backend,
- ply_renderer_head_t *head)
- {
- ply_trace ("unmapping %ldx%ld renderer head", head->area.width, head->area.height);
-- backend->driver_interface->unmap_buffer (backend->driver,
-- head->scan_out_buffer_id);
-+ unmap_buffer (backend, head->scan_out_buffer_id);
-
-- backend->driver_interface->destroy_buffer (backend->driver,
-- head->scan_out_buffer_id);
-+ destroy_output_buffer (backend, head->scan_out_buffer_id);
- head->scan_out_buffer_id = 0;
- }
-
-@@ -375,10 +614,19 @@ create_backend (const char *device_name,
- backend->heads = ply_list_new ();
- backend->input_source.key_buffer = ply_buffer_new ();
- backend->terminal = terminal;
-+ backend->requires_explicit_flushing = true;
-+ backend->output_buffers = ply_hashtable_new (ply_hashtable_direct_hash,
-+ ply_hashtable_direct_compare);
-
- return backend;
- }
-
-+static const char *
-+get_device_name (ply_renderer_backend_t *backend)
-+{
-+ return backend->device_name;
-+}
-+
- static void
- destroy_backend (ply_renderer_backend_t *backend)
- {
-@@ -386,6 +634,9 @@ destroy_backend (ply_renderer_backend_t *backend)
- free_heads (backend);
-
- free (backend->device_name);
-+ ply_hashtable_free (backend->output_buffers);
-+
-+ drmModeFreeResources (backend->resources);
-
- free (backend);
- }
-@@ -455,44 +706,29 @@ load_driver (ply_renderer_backend_t *backend)
- 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)
-+unload_backend (ply_renderer_backend_t *backend)
- {
-- if (backend->driver == NULL)
-+ if (backend == 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;
-+ ply_trace ("unloading backend");
-
- if (backend->device_fd >= 0) {
- drmClose (backend->device_fd);
- backend->device_fd = -1;
- }
-+
-+ destroy_backend (backend);
-+ backend = NULL;
-+
- }
-
- static bool
-@@ -540,7 +776,7 @@ close_device (ply_renderer_backend_t *backend)
- backend);
- }
-
-- unload_driver (backend);
-+ unload_backend (backend);
- }
-
- static drmModeCrtc *
-@@ -732,34 +968,6 @@ create_heads_for_active_connectors (ply_renderer_backend_t *backend)
-
- ply_hashtable_free (heads_by_controller_id);
-
--#ifdef PLY_ENABLE_DEPRECATED_GDM_TRANSITION
-- /* If the driver doesn't support mapping the fb console
-- * then we can't get a smooth crossfade transition to
-- * the display manager unless we use the /dev/fb interface
-- * or the plymouth deactivate interface.
-- *
-- * In multihead configurations, we'd rather have working
-- * multihead, but otherwise bail now.
-- */
-- if (!backend->driver_supports_mapping_console &&
-- ply_list_get_length (backend->heads) == 1) {
-- ply_list_node_t *node;
-- ply_renderer_head_t *head;
--
-- node = ply_list_get_first_node (backend->heads);
-- head = (ply_renderer_head_t *) ply_list_node_get_data (node);
--
-- if (ply_array_get_size (head->connector_ids) == 1) {
-- ply_trace ("Only one monitor configured, and driver doesn't "
-- "support mapping console, so letting frame-buffer "
-- "take over");
--
-- free_heads (backend);
-- return false;
-- }
-- }
--#endif
--
- return ply_list_get_length (backend->heads) > 0;
- }
-
-@@ -774,7 +982,7 @@ has_32bpp_support (ply_renderer_backend_t *backend)
- min_width = backend->resources->min_width;
- min_height = backend->resources->min_height;
-
-- /* Some drivers set min_width/min_height to 0,
-+ /* Some backends set min_width/min_height to 0,
- * but 0x0 sized buffers don't work.
- */
- if (min_width == 0)
-@@ -783,10 +991,7 @@ has_32bpp_support (ply_renderer_backend_t *backend)
- if (min_height == 0)
- min_height = 1;
-
-- buffer_id = backend->driver_interface->create_buffer (backend->driver,
-- min_width,
-- min_height,
-- &row_stride);
-+ buffer_id = create_output_buffer (backend, min_width, min_height, &row_stride);
-
- if (buffer_id == 0) {
- ply_trace ("Could not create minimal (%ux%u) 32bpp dummy buffer",
-@@ -795,8 +1000,7 @@ has_32bpp_support (ply_renderer_backend_t *backend)
- return false;
- }
-
-- backend->driver_interface->destroy_buffer (backend->driver,
-- buffer_id);
-+ destroy_output_buffer (backend, buffer_id);
-
- return true;
- }
-@@ -860,93 +1064,10 @@ map_to_device (ply_renderer_backend_t *backend)
- return head_mapped;
- }
-
--static bool
--ply_renderer_head_set_scan_out_buffer_to_console (ply_renderer_backend_t *backend,
-- ply_renderer_head_t *head,
-- bool should_set_to_black)
--{
-- unsigned long width;
-- unsigned long height;
-- unsigned long row_stride;
-- uint32_t *shadow_buffer;
-- ply_pixel_buffer_t *pixel_buffer;
-- char *map_address;
-- ply_rectangle_t area;
--
-- if (!backend->driver_interface->fetch_buffer (backend->driver,
-- head->console_buffer_id,
-- &width, &height, &row_stride))
-- return false;
--
-- if (!backend->driver_interface->map_buffer (backend->driver,
-- head->console_buffer_id)) {
-- backend->driver_interface->destroy_buffer (backend->driver,
-- head->console_buffer_id);
-- return false;
-- }
--
-- if (head->area.width != width || head->area.height != height) {
-- /* Force black if the fb console resolution doesn't match our resolution
-- */
-- area.x = 0;
-- area.y = 0;
-- area.width = width;
-- area.height = height;
--
-- should_set_to_black = true;
-- ply_trace ("Console fb is %ldx%ld and screen contents are %ldx%ld. "
-- "They aren't the same dimensions; forcing black",
-- width, height, head->area.width, head->area.height);
-- } else {
-- area = head->area;
-- }
--
-- if (should_set_to_black) {
-- pixel_buffer = ply_pixel_buffer_new (width, height);
-- shadow_buffer = ply_pixel_buffer_get_argb32_data (pixel_buffer);
-- } else {
-- pixel_buffer = NULL;
-- shadow_buffer = ply_pixel_buffer_get_argb32_data (head->pixel_buffer);
-- }
--
-- ply_trace ("Drawing %s to console fb", should_set_to_black ? "black" : "screen contents");
-- map_address =
-- backend->driver_interface->begin_flush (backend->driver,
-- head->console_buffer_id);
--
-- flush_area ((char *) shadow_buffer, area.width * 4,
-- map_address, row_stride, &area);
--
-- backend->driver_interface->end_flush (backend->driver,
-- head->console_buffer_id);
--
-- backend->driver_interface->unmap_buffer (backend->driver,
-- head->console_buffer_id);
--
-- ply_trace ("Setting scan out hardware to console fb");
-- ply_renderer_head_set_scan_out_buffer (backend,
-- head, head->console_buffer_id);
--
-- backend->driver_interface->destroy_buffer (backend->driver,
-- head->console_buffer_id);
--
-- if (pixel_buffer != NULL)
-- ply_pixel_buffer_free (pixel_buffer);
--
-- return true;
--}
--
- static void
- unmap_from_device (ply_renderer_backend_t *backend)
- {
- ply_list_node_t *node;
-- bool should_set_to_black;
--
-- /* We only copy what's on screen back to the fb console
-- * if there's one head (since in multihead set ups the fb console
-- * is cloned).
-- */
-- should_set_to_black = ply_list_get_length (backend->heads) > 1;
-
- node = ply_list_get_first_node (backend->heads);
- while (node != NULL) {
-@@ -956,13 +1077,6 @@ unmap_from_device (ply_renderer_backend_t *backend)
- head = (ply_renderer_head_t *) ply_list_node_get_data (node);
- next_node = ply_list_get_next_node (backend->heads, node);
-
-- if (backend->is_active) {
-- ply_trace ("scanning out %s directly to console",
-- should_set_to_black ? "black" : "splash");
-- ply_renderer_head_set_scan_out_buffer_to_console (backend, head,
-- should_set_to_black);
-- }
--
- ply_renderer_head_unmap (backend, head);
-
- node = next_node;
-@@ -1019,9 +1133,7 @@ flush_head (ply_renderer_backend_t *backend,
- updated_region = ply_pixel_buffer_get_updated_areas (pixel_buffer);
- areas_to_flush = ply_region_get_sorted_rectangle_list (updated_region);
-
-- map_address =
-- backend->driver_interface->begin_flush (backend->driver,
-- head->scan_out_buffer_id);
-+ map_address = begin_flush (backend, head->scan_out_buffer_id);
-
- node = ply_list_get_first_node (areas_to_flush);
- while (node != NULL) {
-@@ -1041,8 +1153,7 @@ flush_head (ply_renderer_backend_t *backend,
- node = next_node;
- }
-
-- backend->driver_interface->end_flush (backend->driver,
-- head->scan_out_buffer_id);
-+ end_flush (backend, head->scan_out_buffer_id);
-
- ply_region_clear (updated_region);
- }
-@@ -1180,7 +1291,8 @@ ply_renderer_backend_get_interface (void)
- .get_input_source = get_input_source,
- .open_input_source = open_input_source,
- .set_handler_for_input_source = set_handler_for_input_source,
-- .close_input_source = close_input_source
-+ .close_input_source = close_input_source,
-+ .get_device_name = get_device_name
- };
-
- return &plugin_interface;
-diff --git a/src/plugins/renderers/drm/ply-renderer-driver.h b/src/plugins/renderers/drm/ply-renderer-driver.h
-deleted file mode 100644
-index f3febcf..0000000
---- a/src/plugins/renderers/drm/ply-renderer-driver.h
-+++ /dev/null
-@@ -1,66 +0,0 @@
--/* ply-renderer-driver.h
-- *
-- * Copyright (C) 2009 Red Hat, Inc.
-- *
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License as published by
-- * the Free Software Foundation; either version 2, or (at your option)
-- * any later version.
-- *
-- * This program is distributed in the hope that it will be useful,
-- * but WITHOUT ANY WARRANTY; without even the implied warranty of
-- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- * GNU General Public License for more details.
-- *
-- * You should have received a copy of the GNU General Public License
-- * along with this program; if not, write to the Free Software
-- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-- * 02111-1307, USA.
-- *
-- * Written By: Ray Strode <rstrode@redhat.com>
-- */
--#ifndef PLY_RENDERER_DRIVER_H
--#define PLY_RENDERER_DRIVER_H
--
--#include <stdbool.h>
--#include <stdint.h>
--
--#include "ply-list.h"
--#include "ply-rectangle.h"
--#include "ply-utils.h"
--
--typedef struct _ply_renderer_driver ply_renderer_driver_t;
--
--typedef struct
--{
-- ply_renderer_driver_t * (*create_driver)(int device_fd);
--
-- void (*destroy_driver)(ply_renderer_driver_t *driver);
--
-- uint32_t (*create_buffer)(ply_renderer_driver_t *driver,
-- unsigned long width,
-- unsigned long height,
-- unsigned long *row_stride);
-- bool (*fetch_buffer)(ply_renderer_driver_t *driver,
-- uint32_t buffer_id,
-- unsigned long *width,
-- unsigned long *height,
-- unsigned long *row_stride);
--
-- bool (*map_buffer)(ply_renderer_driver_t *driver,
-- uint32_t buffer_id);
--
-- void (*unmap_buffer)(ply_renderer_driver_t *driver,
-- uint32_t buffer_id);
--
-- char * (*begin_flush)(ply_renderer_driver_t * driver,
-- uint32_t buffer_id);
-- void (*end_flush)(ply_renderer_driver_t *driver,
-- uint32_t buffer_id);
--
-- void (*destroy_buffer)(ply_renderer_driver_t *driver,
-- uint32_t buffer_id);
--} ply_renderer_driver_interface_t;
--
--#endif /* PLY_RENDERER_DRIVER_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/plugins/renderers/drm/ply-renderer-generic-driver.c b/src/plugins/renderers/drm/ply-renderer-generic-driver.c
-deleted file mode 100644
-index b1be714..0000000
---- a/src/plugins/renderers/drm/ply-renderer-generic-driver.c
-+++ /dev/null
-@@ -1,385 +0,0 @@
--/* ply-renderer-generic-driver.c - interface to generic drm kms api
-- *
-- * Copyright (C) 2012 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: Dave Airlie
-- * Based on other renderer drivers written by Ray Strode
-- */
--#include "config.h"
--
--#include "ply-renderer-generic-driver.h"
--
--#include <arpa/inet.h>
--#include <assert.h>
--#include <errno.h>
--#include <fcntl.h>
--#include <signal.h>
--#include <string.h>
--#include <stdbool.h>
--#include <stdint.h>
--#include <stdio.h>
--#include <stdlib.h>
--#include <sys/ioctl.h>
--#include <sys/mman.h>
--#include <sys/stat.h>
--#include <sys/types.h>
--#include <values.h>
--#include <unistd.h>
--
--#include <drm.h>
--#include <xf86drm.h>
--#include <xf86drmMode.h>
--
--#include "ply-hashtable.h"
--#include "ply-logger.h"
--#include "ply-renderer-driver.h"
--
--typedef struct _ply_renderer_buffer ply_renderer_buffer_t;
--
--struct _ply_renderer_buffer
--{
-- uint32_t id;
--
-- uint32_t handle;
-- uint32_t width;
-- uint32_t height;
-- uint32_t row_stride;
--
-- void *map_address;
-- uint32_t map_size;
-- int map_count;
--
-- uint32_t added_fb : 1;
--};
--
--struct _ply_renderer_driver
--{
-- int device_fd;
-- ply_hashtable_t *buffers;
--
-- uint32_t requires_explicit_flushing : 1;
--};
--
--static bool
--ply_renderer_buffer_map (ply_renderer_driver_t *driver,
-- ply_renderer_buffer_t *buffer)
--{
-- struct drm_mode_map_dumb map_dumb_buffer_request;
-- void *map_address;
--
-- if (buffer->map_address != MAP_FAILED) {
-- buffer->map_count++;
-- return true;
-- }
--
-- memset (&map_dumb_buffer_request, 0, sizeof(struct drm_mode_map_dumb));
-- map_dumb_buffer_request.handle = buffer->handle;
-- if (drmIoctl (driver->device_fd, DRM_IOCTL_MODE_MAP_DUMB, &map_dumb_buffer_request) < 0) {
-- ply_trace ("Could not map GEM object %u: %m", buffer->handle);
-- return false;
-- }
--
-- map_address = mmap (0, buffer->map_size,
-- PROT_READ | PROT_WRITE, MAP_SHARED,
-- driver->device_fd, map_dumb_buffer_request.offset);
--
-- if (map_address == MAP_FAILED)
-- return false;
--
-- buffer->map_address = map_address;
-- buffer->map_count++;
--
-- return true;
--}
--
--static void
--ply_renderer_buffer_unmap (ply_renderer_driver_t *driver,
-- ply_renderer_buffer_t *buffer)
--{
-- buffer->map_count--;
--
-- assert (buffer->map_count >= 0);
--}
--
--static ply_renderer_driver_t *
--create_driver (int device_fd)
--{
-- ply_renderer_driver_t *driver;
--
-- driver = calloc (1, sizeof(ply_renderer_driver_t));
-- driver->device_fd = device_fd;
-- driver->requires_explicit_flushing = true;
-- driver->buffers = ply_hashtable_new (ply_hashtable_direct_hash,
-- ply_hashtable_direct_compare);
--
-- return driver;
--}
--
--static void
--destroy_driver (ply_renderer_driver_t *driver)
--{
-- ply_hashtable_free (driver->buffers);
--
-- free (driver);
--}
--
--static ply_renderer_buffer_t *
--ply_renderer_buffer_new (ply_renderer_driver_t *driver,
-- uint32_t width,
-- uint32_t height)
--{
-- ply_renderer_buffer_t *buffer;
-- struct drm_mode_create_dumb create_dumb_buffer_request;
--
-- buffer = calloc (1, sizeof(ply_renderer_buffer_t));
-- buffer->width = width;
-- buffer->height = height;
-- buffer->map_address = MAP_FAILED;
--
-- memset (&create_dumb_buffer_request, 0, sizeof(struct drm_mode_create_dumb));
--
-- create_dumb_buffer_request.width = width;
-- create_dumb_buffer_request.height = height;
-- create_dumb_buffer_request.bpp = 32;
-- create_dumb_buffer_request.flags = 0;
--
-- if (drmIoctl (driver->device_fd,
-- DRM_IOCTL_MODE_CREATE_DUMB,
-- &create_dumb_buffer_request) < 0) {
-- free (buffer);
-- ply_trace ("Could not allocate GEM object for frame buffer: %m");
-- return NULL;
-- }
--
-- buffer->handle = create_dumb_buffer_request.handle;
-- buffer->row_stride = create_dumb_buffer_request.pitch;
-- buffer->map_size = create_dumb_buffer_request.size;
--
-- ply_trace ("returning %ux%u buffer with stride %u",
-- width, height, buffer->row_stride);
--
-- return buffer;
--}
--
--static void
--ply_renderer_buffer_free (ply_renderer_driver_t *driver,
-- ply_renderer_buffer_t *buffer)
--{
-- struct drm_mode_destroy_dumb destroy_dumb_buffer_request;
--
-- if (buffer->added_fb)
-- drmModeRmFB (driver->device_fd, buffer->id);
--
-- if (buffer->map_address != MAP_FAILED) {
-- munmap (buffer->map_address, buffer->map_size);
-- buffer->map_address = MAP_FAILED;
-- }
--
-- memset (&destroy_dumb_buffer_request, 0, sizeof(struct drm_mode_destroy_dumb));
-- destroy_dumb_buffer_request.handle = buffer->handle;
--
-- if (drmIoctl (driver->device_fd,
-- DRM_IOCTL_MODE_DESTROY_DUMB,
-- &destroy_dumb_buffer_request) < 0)
-- ply_trace ("Could not deallocate GEM object %u: %m", buffer->handle);
--
-- free (buffer);
--}
--
--static ply_renderer_buffer_t *
--get_buffer_from_id (ply_renderer_driver_t *driver,
-- uint32_t id)
--{
-- static ply_renderer_buffer_t *buffer;
--
-- buffer = ply_hashtable_lookup (driver->buffers, (void *) (uintptr_t) id);
--
-- return buffer;
--}
--
--static bool
--fetch_buffer (ply_renderer_driver_t *driver,
-- uint32_t buffer_id,
-- unsigned long *width,
-- unsigned long *height,
-- unsigned long *row_stride)
--{
-- ply_renderer_buffer_t *buffer;
--
-- buffer = get_buffer_from_id (driver, buffer_id);
--
-- if (buffer == NULL) {
-- ply_trace ("could not fetch buffer %u", buffer_id);
-- return false;
-- }
--
-- if (width != NULL)
-- *width = buffer->width;
--
-- if (height != NULL)
-- *height = buffer->height;
--
-- if (row_stride != NULL)
-- *row_stride = buffer->row_stride;
--
-- ply_trace ("fetched %ux%u buffer with stride %u",
-- buffer->width, buffer->height, buffer->row_stride);
-- return true;
--}
--
--static uint32_t
--create_buffer (ply_renderer_driver_t *driver,
-- unsigned long width,
-- unsigned long height,
-- unsigned long *row_stride)
--{
-- ply_renderer_buffer_t *buffer;
--
-- buffer = ply_renderer_buffer_new (driver, width, height);
--
-- if (buffer == NULL) {
-- ply_trace ("Could not allocate GEM object for frame buffer: %m");
-- return 0;
-- }
--
-- if (drmModeAddFB (driver->device_fd, width, height,
-- 24, 32, buffer->row_stride, buffer->handle,
-- &buffer->id) != 0) {
-- ply_trace ("Could not set up GEM object as frame buffer: %m");
-- ply_renderer_buffer_free (driver, buffer);
-- return 0;
-- }
--
-- *row_stride = buffer->row_stride;
--
-- buffer->added_fb = true;
-- ply_hashtable_insert (driver->buffers,
-- (void *) (uintptr_t) buffer->id,
-- buffer);
--
-- return buffer->id;
--}
--
--static bool
--map_buffer (ply_renderer_driver_t *driver,
-- uint32_t buffer_id)
--{
-- ply_renderer_buffer_t *buffer;
--
-- buffer = get_buffer_from_id (driver, buffer_id);
--
-- assert (buffer != NULL);
--
-- return ply_renderer_buffer_map (driver, buffer);
--}
--
--static void
--unmap_buffer (ply_renderer_driver_t *driver,
-- uint32_t buffer_id)
--{
-- ply_renderer_buffer_t *buffer;
--
-- buffer = get_buffer_from_id (driver, buffer_id);
--
-- assert (buffer != NULL);
--
-- ply_renderer_buffer_unmap (driver, buffer);
--}
--
--static char *
--begin_flush (ply_renderer_driver_t *driver,
-- uint32_t buffer_id)
--{
-- ply_renderer_buffer_t *buffer;
--
-- buffer = get_buffer_from_id (driver, buffer_id);
--
-- assert (buffer != NULL);
--
-- return buffer->map_address;
--}
--
--static void
--end_flush (ply_renderer_driver_t *driver,
-- uint32_t buffer_id)
--{
-- ply_renderer_buffer_t *buffer;
--
-- buffer = get_buffer_from_id (driver, buffer_id);
--
-- assert (buffer != NULL);
--
-- if (driver->requires_explicit_flushing) {
-- struct drm_clip_rect flush_area;
-- int ret;
--
-- flush_area.x1 = 0;
-- flush_area.y1 = 0;
-- flush_area.x2 = buffer->width;
-- flush_area.y2 = buffer->height;
--
-- ret = drmModeDirtyFB (driver->device_fd, buffer->id, &flush_area, 1);
--
-- if (ret == -ENOSYS)
-- driver->requires_explicit_flushing = false;
-- }
--}
--
--static void
--destroy_buffer (ply_renderer_driver_t *driver,
-- uint32_t buffer_id)
--{
-- ply_renderer_buffer_t *buffer;
--
-- buffer = ply_hashtable_remove (driver->buffers,
-- (void *) (uintptr_t) buffer_id);
--
-- assert (buffer != NULL);
--
-- ply_renderer_buffer_free (driver, buffer);
--}
--
--ply_renderer_driver_interface_t *
--ply_renderer_generic_driver_get_interface (int device_fd)
--{
-- uint64_t supports_dumb_buffers;
--
-- static ply_renderer_driver_interface_t driver_interface =
-- {
-- .create_driver = create_driver,
-- .destroy_driver = destroy_driver,
-- .create_buffer = create_buffer,
-- .fetch_buffer = fetch_buffer,
-- .map_buffer = map_buffer,
-- .unmap_buffer = unmap_buffer,
-- .begin_flush = begin_flush,
-- .end_flush = end_flush,
-- .destroy_buffer = destroy_buffer,
-- };
--
--
-- if (drmGetCap (device_fd, DRM_CAP_DUMB_BUFFER, &supports_dumb_buffers) < 0)
-- return NULL;
--
-- if (!supports_dumb_buffers)
-- return NULL;
--
-- return &driver_interface;
--}
--
--/* 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/plugins/renderers/drm/ply-renderer-generic-driver.h b/src/plugins/renderers/drm/ply-renderer-generic-driver.h
-deleted file mode 100644
-index 053587a..0000000
---- a/src/plugins/renderers/drm/ply-renderer-generic-driver.h
-+++ /dev/null
-@@ -1,33 +0,0 @@
--/* ply-renderer-generic-driver.h
-- *
-- * Copyright (C) 2012 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: Dave Airlie
-- * Based on other renderer drivers written by Ray Strode
-- */
--#ifndef PLY_RENDERER_DUMB_DRIVER_H
--#define PLY_RENDERER_DUMB_DRIVER_H
--
--#include "ply-renderer-driver.h"
--
--#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
--ply_renderer_driver_interface_t *ply_renderer_generic_driver_get_interface (int device_fd);
--#endif
--
--#endif /* PLY_RENDERER_GENERIC_DRIVER_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/plugins/renderers/frame-buffer/plugin.c b/src/plugins/renderers/frame-buffer/plugin.c
-index 418855a..41ad6cd 100644
---- a/src/plugins/renderers/frame-buffer/plugin.c
-+++ b/src/plugins/renderers/frame-buffer/plugin.c
-@@ -365,6 +365,12 @@ open_device (ply_renderer_backend_t *backend)
- return true;
- }
-
-+static const char *
-+get_device_name (ply_renderer_backend_t *backend)
-+{
-+ return backend->device_name;
-+}
-+
- static void
- close_device (ply_renderer_backend_t *backend)
- {
-@@ -732,7 +738,8 @@ ply_renderer_backend_get_interface (void)
- .get_input_source = get_input_source,
- .open_input_source = open_input_source,
- .set_handler_for_input_source = set_handler_for_input_source,
-- .close_input_source = close_input_source
-+ .close_input_source = close_input_source,
-+ .get_device_name = get_device_name
- };
-
- return &plugin_interface;
-diff --git a/src/plugins/renderers/x11/plugin.c b/src/plugins/renderers/x11/plugin.c
-index 1e1fe31..8948f69 100644
---- a/src/plugins/renderers/x11/plugin.c
-+++ b/src/plugins/renderers/x11/plugin.c
-@@ -56,6 +56,7 @@
- #include "ply-logger.h"
- #include "ply-rectangle.h"
- #include "ply-region.h"
-+#include "ply-utils.h"
-
- #include "ply-renderer.h"
- #include "ply-renderer-plugin.h"
-@@ -64,9 +65,10 @@ struct _ply_renderer_head
- {
- ply_renderer_backend_t *backend;
- ply_pixel_buffer_t *pixel_buffer;
-- ply_rectangle_t area;
-+ ply_rectangle_t area; /* in device pixels */
- GtkWidget *window;
- cairo_surface_t *image;
-+ uint32_t scale;
- uint32_t is_fullscreen : 1;
- };
-
-@@ -148,9 +150,14 @@ open_device (ply_renderer_backend_t *backend)
- Display *display;
- int display_fd;
-
-+ gdk_set_allowed_backends ("x11");
-+
- if (!gtk_init_check (0, NULL))
- return false;
-
-+ /* Force gtk+ to deal in device pixels */
-+ gdk_x11_display_set_window_scale (gdk_display_get_default (), 1);
-+
- display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
- display_fd = ConnectionNumber (display);
- backend->display_watch = ply_event_loop_watch_fd (backend->loop,
-@@ -163,6 +170,12 @@ open_device (ply_renderer_backend_t *backend)
- return true;
- }
-
-+static const char *
-+get_device_name (ply_renderer_backend_t *backend)
-+{
-+ return gdk_display_get_name (gdk_display_get_default ());
-+}
-+
- static void
- close_device (ply_renderer_backend_t *backend)
- {
-@@ -183,7 +196,9 @@ create_fake_multi_head_setup (ply_renderer_backend_t *backend)
- head->area.y = 0;
- head->area.width = 800; /* FIXME hardcoded */
- head->area.height = 600;
-+ head->scale = 1;
- head->pixel_buffer = ply_pixel_buffer_new (head->area.width, head->area.height);
-+ ply_pixel_buffer_set_device_scale (head->pixel_buffer, head->scale);
-
- ply_list_append_data (backend->heads, head);
-
-@@ -194,7 +209,9 @@ create_fake_multi_head_setup (ply_renderer_backend_t *backend)
- head->area.y = 0;
- head->area.width = 640; /* FIXME hardcoded */
- head->area.height = 480;
-+ head->scale = 1;
- head->pixel_buffer = ply_pixel_buffer_new (head->area.width, head->area.height);
-+ ply_pixel_buffer_set_device_scale (head->pixel_buffer, head->scale);
-
- ply_list_append_data (backend->heads, head);
- }
-@@ -204,8 +221,11 @@ create_fullscreen_single_head_setup (ply_renderer_backend_t *backend)
- {
- ply_renderer_head_t *head;
- GdkRectangle monitor_geometry;
-+ int width_mm, height_mm;
-
- gdk_screen_get_monitor_geometry (gdk_screen_get_default (), 0, &monitor_geometry);
-+ width_mm = gdk_screen_get_monitor_width_mm (gdk_screen_get_default (), 0);
-+ height_mm = gdk_screen_get_monitor_height_mm (gdk_screen_get_default (), 0);
-
- head = calloc (1, sizeof(ply_renderer_head_t));
-
-@@ -215,7 +235,11 @@ create_fullscreen_single_head_setup (ply_renderer_backend_t *backend)
- head->area.width = monitor_geometry.width;
- head->area.height = monitor_geometry.height;
- head->is_fullscreen = true;
-+ head->scale = ply_get_device_scale (monitor_geometry.width,
-+ monitor_geometry.height,
-+ width_mm, height_mm);
- head->pixel_buffer = ply_pixel_buffer_new (head->area.width, head->area.height);
-+ ply_pixel_buffer_set_device_scale (head->pixel_buffer, head->scale);
-
- ply_list_append_data (backend->heads, head);
- }
-@@ -380,6 +404,12 @@ flush_head (ply_renderer_backend_t *backend,
- area_to_flush = (ply_rectangle_t *) ply_list_node_get_data (node);
- next_node = ply_list_get_next_node (areas_to_flush, node);
-
-+ cairo_surface_mark_dirty_rectangle (head->image,
-+ area_to_flush->x,
-+ area_to_flush->y,
-+ area_to_flush->width,
-+ area_to_flush->height);
-+
- gtk_widget_queue_draw_area (head->window,
- area_to_flush->x,
- area_to_flush->y,
-@@ -515,7 +545,8 @@ ply_renderer_backend_get_interface (void)
- .get_input_source = get_input_source,
- .open_input_source = open_input_source,
- .set_handler_for_input_source = set_handler_for_input_source,
-- .close_input_source = close_input_source
-+ .close_input_source = close_input_source,
-+ .get_device_name = get_device_name
- };
-
- return &plugin_interface;
-diff --git a/src/plugins/splash/details/plugin.c b/src/plugins/splash/details/plugin.c
-index 8e55d05..f534450 100644
---- a/src/plugins/splash/details/plugin.c
-+++ b/src/plugins/splash/details/plugin.c
-@@ -77,6 +77,8 @@ struct _ply_boot_splash_plugin
- ply_list_t *views;
- ply_boot_splash_display_type_t state;
- ply_list_t *messages;
-+
-+ ply_buffer_t *boot_buffer;
- };
-
- static view_t *
-@@ -239,6 +241,15 @@ add_text_display (ply_boot_splash_plugin_t *plugin,
- 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
-@@ -282,8 +293,9 @@ show_splash_screen (ply_boot_splash_plugin_t *plugin,
- 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);
- }
-
-@@ -330,7 +342,7 @@ display_normal (ply_boot_splash_plugin_t *plugin)
- ply_list_node_t *node;
-
- if (plugin->state != PLY_BOOT_SPLASH_DISPLAY_NORMAL)
-- write_on_views (plugin, "\r\n", strlen ("\r\n"));
-+ write_on_views (plugin, "\n", strlen ("\n"));
-
- plugin->state = PLY_BOOT_SPLASH_DISPLAY_NORMAL;
-
-@@ -343,7 +355,7 @@ display_normal (ply_boot_splash_plugin_t *plugin)
- next_node = ply_list_get_next_node (plugin->messages, node);
-
- write_on_views (plugin, message, strlen (message));
-- write_on_views (plugin, "\r\n", strlen ("\r\n"));
-+ write_on_views (plugin, "\n", strlen ("\n"));
-
- ply_list_remove_node (plugin->messages, node);
- node = next_node;
-@@ -358,7 +370,7 @@ display_password (ply_boot_splash_plugin_t *plugin,
- int i;
-
- if (plugin->state != PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY)
-- write_on_views (plugin, "\r\n", strlen ("\r\n"));
-+ write_on_views (plugin, "\n", strlen ("\n"));
- else
- write_on_views (plugin,
- CLEAR_LINE_SEQUENCE,
-@@ -387,7 +399,7 @@ display_question (ply_boot_splash_plugin_t *plugin,
- const char *entry_text)
- {
- if (plugin->state != PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY)
-- write_on_views (plugin, "\r\n", strlen ("\r\n"));
-+ write_on_views (plugin, "\n", strlen ("\n"));
- else
- write_on_views (plugin,
- CLEAR_LINE_SEQUENCE,
-@@ -407,7 +419,7 @@ display_message (ply_boot_splash_plugin_t *plugin,
- {
- if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_NORMAL) {
- write_on_views (plugin, message, strlen (message));
-- write_on_views (plugin, "\r\n", strlen ("\r\n"));
-+ write_on_views (plugin, "\n", strlen ("\n"));
- } else {
- ply_list_append_data (plugin->messages, strdup (message));
- }
-diff --git a/src/plugins/splash/fade-throbber/plugin.c b/src/plugins/splash/fade-throbber/plugin.c
-index 1643b87..a7ab4ef 100644
---- a/src/plugins/splash/fade-throbber/plugin.c
-+++ b/src/plugins/splash/fade-throbber/plugin.c
-@@ -104,6 +104,7 @@ struct _ply_boot_splash_plugin
- 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);
-@@ -264,6 +265,8 @@ view_free (view_t *view)
- ply_label_free (view->message_label);
- free_stars (view);
-
-+ ply_pixel_display_set_draw_handler (view->display, NULL, NULL);
-+
- free (view);
- }
-
-@@ -293,8 +296,12 @@ load_views (ply_boot_splash_plugin_t *plugin)
- view = ply_list_node_get_data (node);
- next_node = ply_list_get_next_node (plugin->views, node);
-
-- if (view_load (view))
-+ if (view_load (view)) {
- view_loaded = true;
-+ } else {
-+ ply_list_remove_node (plugin->views, node);
-+ view_free (view);
-+ }
-
- node = next_node;
- }
-@@ -745,7 +752,14 @@ add_pixel_display (ply_boot_splash_plugin_t *plugin,
- (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
-@@ -763,7 +777,6 @@ remove_pixel_display (ply_boot_splash_plugin_t *plugin,
- 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;
-@@ -806,6 +819,8 @@ show_splash_screen (ply_boot_splash_plugin_t *plugin,
- return false;
- }
-
-+ plugin->is_visible = true;
-+
- ply_trace ("starting boot animation");
- start_animation (plugin);
-
-@@ -940,6 +955,8 @@ hide_splash_screen (ply_boot_splash_plugin_t *plugin,
- {
- assert (plugin != NULL);
-
-+ plugin->is_visible = false;
-+
- if (plugin->loop != NULL) {
- stop_animation (plugin);
-
-diff --git a/src/plugins/splash/script/script-lib-sprite.c b/src/plugins/splash/script/script-lib-sprite.c
-index f292d90..c49297d 100644
---- a/src/plugins/splash/script/script-lib-sprite.c
-+++ b/src/plugins/splash/script/script-lib-sprite.c
-@@ -416,6 +416,22 @@ static script_return_t sprite_window_set_background_bottom_color (script_state_t
- return script_return_obj_null ();
- }
-
-+static void script_lib_draw_brackground (ply_pixel_buffer_t *pixel_buffer,
-+ ply_rectangle_t *clip_area,
-+ script_lib_sprite_data_t *data)
-+{
-+ if (data->background_color_start == data->background_color_end) {
-+ ply_pixel_buffer_fill_with_hex_color (pixel_buffer,
-+ clip_area,
-+ data->background_color_start);
-+ } else {
-+ ply_pixel_buffer_fill_with_gradient (pixel_buffer,
-+ clip_area,
-+ data->background_color_start,
-+ data->background_color_end);
-+ }
-+}
-+
- static void script_lib_sprite_draw_area (script_lib_display_t *display,
- ply_pixel_buffer_t *pixel_buffer,
- int x,
-@@ -425,6 +441,7 @@ static void script_lib_sprite_draw_area (script_lib_display_t *display,
- {
- ply_rectangle_t clip_area;
- ply_list_node_t *node;
-+ sprite_t *sprite;
- script_lib_sprite_data_t *data = display->data;
-
- clip_area.x = x;
-@@ -432,22 +449,33 @@ static void script_lib_sprite_draw_area (script_lib_display_t *display,
- clip_area.width = width;
- clip_area.height = height;
-
-- if (data->background_color_start == data->background_color_end) {
-- ply_pixel_buffer_fill_with_hex_color (pixel_buffer,
-- &clip_area,
-- data->background_color_start);
-+
-+ node = ply_list_get_first_node (data->sprite_list);
-+ sprite = ply_list_node_get_data (node);
-+
-+ /* Check If the first sprite should be rendered opaque */
-+ if (sprite->image && !sprite->remove_me &&
-+ ply_pixel_buffer_is_opaque (sprite->image) && sprite->opacity == 1.0) {
-+ int position_x = sprite->x - display->x;
-+ int position_y = sprite->y - display->y;
-+
-+ /* In that case only draw the background if the sprite doesn't
-+ * cover the complete area */
-+ if (position_x > x || position_y > y ||
-+ (ply_pixel_buffer_get_width (sprite->image) + position_x) < (x + width) ||
-+ (ply_pixel_buffer_get_height (sprite->image) + position_y) < (y + height))
-+ script_lib_draw_brackground (pixel_buffer, &clip_area, data);
- } else {
-- ply_pixel_buffer_fill_with_gradient (pixel_buffer,
-- &clip_area,
-- data->background_color_start,
-- data->background_color_end);
-+ script_lib_draw_brackground (pixel_buffer, &clip_area, data);
- }
-+
- for (node = ply_list_get_first_node (data->sprite_list);
- node;
- node = ply_list_get_next_node (data->sprite_list, node)) {
-- sprite_t *sprite = ply_list_node_get_data (node);
- int position_x, position_y;
-
-+ sprite = ply_list_node_get_data (node);
-+
- if (!sprite->image) continue;
- if (sprite->remove_me) continue;
- if (sprite->opacity < 0.011) continue;
-diff --git a/src/plugins/splash/space-flares/plugin.c b/src/plugins/splash/space-flares/plugin.c
-index 5212c38..5af99c1 100644
---- a/src/plugins/splash/space-flares/plugin.c
-+++ b/src/plugins/splash/space-flares/plugin.c
-@@ -1387,7 +1387,14 @@ add_pixel_display (ply_boot_splash_plugin_t *plugin,
- (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
-diff --git a/src/plugins/splash/text/plugin.c b/src/plugins/splash/text/plugin.c
-index 468bb89..8260daa 100644
---- a/src/plugins/splash/text/plugin.c
-+++ b/src/plugins/splash/text/plugin.c
-@@ -472,6 +472,9 @@ add_text_display (ply_boot_splash_plugin_t *plugin,
- on_draw, view);
-
- ply_list_append_data (plugin->views, view);
-+
-+ if (plugin->is_animating)
-+ view_start_animation (view);
- }
-
- static void
-@@ -553,7 +556,9 @@ on_boot_progress (ply_boot_splash_plugin_t *plugin,
- next_node = ply_list_get_next_node (plugin->views, node);
-
- ply_text_step_bar_set_percent_done (view->step_bar, percent_done);
-- ply_text_step_bar_draw (view->step_bar);
-+
-+ if (plugin->is_animating)
-+ ply_text_step_bar_draw (view->step_bar);
-
- node = next_node;
- }
-diff --git a/src/plugins/splash/throbgress/plugin.c b/src/plugins/splash/throbgress/plugin.c
-index c105e02..a1c8a90 100644
---- a/src/plugins/splash/throbgress/plugin.c
-+++ b/src/plugins/splash/throbgress/plugin.c
-@@ -625,7 +625,14 @@ add_pixel_display (ply_boot_splash_plugin_t *plugin,
- (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
-diff --git a/src/plugins/splash/tribar/plugin.c b/src/plugins/splash/tribar/plugin.c
-index 0dcd7f8..ecc17ea 100644
---- a/src/plugins/splash/tribar/plugin.c
-+++ b/src/plugins/splash/tribar/plugin.c
-@@ -478,6 +478,9 @@ add_text_display (ply_boot_splash_plugin_t *plugin,
- on_draw, view);
-
- ply_list_append_data (plugin->views, view);
-+
-+ if (plugin->is_animating)
-+ view_start_animation (view);
- }
-
- static void
-@@ -559,7 +562,9 @@ on_boot_progress (ply_boot_splash_plugin_t *plugin,
- 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;
- }
-diff --git a/src/plugins/splash/two-step/plugin.c b/src/plugins/splash/two-step/plugin.c
-index 0899ace..070741d 100644
---- a/src/plugins/splash/two-step/plugin.c
-+++ b/src/plugins/splash/two-step/plugin.c
-@@ -267,11 +267,15 @@ view_load (view_t *view)
-
- view_load_end_animation (view);
-
-- ply_trace ("loading progress animation");
-- if (!ply_progress_animation_load (view->progress_animation)) {
-- ply_trace ("optional progress animation wouldn't load");
-- ply_progress_animation_free (view->progress_animation);
-- view->progress_animation = NULL;
-+ if (view->progress_animation != NULL) {
-+ ply_trace ("loading progress animation");
-+ if (!ply_progress_animation_load (view->progress_animation)) {
-+ ply_trace ("optional progress animation wouldn't load");
-+ ply_progress_animation_free (view->progress_animation);
-+ view->progress_animation = NULL;
-+ }
-+ } else {
-+ ply_trace ("this theme has no progress animation");
- }
-
- if (view->throbber != NULL) {
-@@ -875,7 +879,12 @@ draw_background (view_t *view,
- if (view->background_image != NULL) {
- uint32_t *data;
- data = ply_image_get_data (view->background_image);
-- ply_pixel_buffer_fill_with_argb32_data (pixel_buffer, &area, data);
-+
-+ /* We must pass NULL as fill area, because the fill area
-+ must be sized as the image we're sourcing from, otherwise
-+ sampling does not work
-+ */
-+ ply_pixel_buffer_fill_with_argb32_data_with_clip (pixel_buffer, NULL, NULL, data);
- }
-
- if (plugin->watermark_image != NULL) {
-@@ -986,7 +995,14 @@ add_pixel_display (ply_boot_splash_plugin_t *plugin,
- 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
-@@ -1329,8 +1345,8 @@ system_update (ply_boot_splash_plugin_t *plugin,
-
- view = ply_list_node_get_data (node);
- next_node = ply_list_get_next_node (plugin->views, node);
-- ply_progress_animation_set_percent_done (view->progress_animation,
-- (double) progress / 100.f);
-+ if (view->progress_animation != NULL)
-+ ply_progress_animation_set_percent_done (view->progress_animation, (double) progress / 100.f);
- node = next_node;
- }
- }
-diff --git a/src/plymouthd.defaults b/src/plymouthd.defaults
-index fc48b15..4d3b6d4 100644
---- a/src/plymouthd.defaults
-+++ b/src/plymouthd.defaults
-@@ -3,3 +3,4 @@
- [Daemon]
- Theme=spinner
- ShowDelay=5
-+DeviceTimeout=5
-diff --git a/systemd-units/Makefile.am b/systemd-units/Makefile.am
-index 89355ac..b1d843b 100644
---- a/systemd-units/Makefile.am
-+++ b/systemd-units/Makefile.am
-@@ -50,21 +50,20 @@ install-data-hook:
- $(LN_S) ../plymouth-halt.service)
-
- uninstall-hook:
-- rm -f \
- (cd $(DESTDIR)$(SYSTEMD_UNIT_DIR)/initrd-switch-root.target.wants && \
-- rm -f plymouth-start.service plymouth-switch-root.service) \
-+ rm -f plymouth-start.service plymouth-switch-root.service)
- (cd $(DESTDIR)$(SYSTEMD_UNIT_DIR)/sysinit.target.wants && \
-- rm -f plymouth-start.service plymouth-read-write.service) \
-+ rm -f plymouth-start.service plymouth-read-write.service)
- (cd $(DESTDIR)$(SYSTEMD_UNIT_DIR)/multi-user.target.wants && \
-- rm -f plymouth-quit.service plymouth-quit-wait.service) \
-+ rm -f plymouth-quit.service plymouth-quit-wait.service)
- (cd $(DESTDIR)$(SYSTEMD_UNIT_DIR)/reboot.target.wants && \
-- rm -f plymouth-reboot.service) \
-+ rm -f plymouth-reboot.service)
- (cd $(DESTDIR)$(SYSTEMD_UNIT_DIR)/kexec.target.wants && \
-- rm -f plymouth-kexec.service) \
-+ rm -f plymouth-kexec.service)
- (cd $(DESTDIR)$(SYSTEMD_UNIT_DIR)/poweroff.target.wants && \
-- rm -f plymouth-poweroff.service) \
-+ rm -f plymouth-poweroff.service)
- (cd $(DESTDIR)$(SYSTEMD_UNIT_DIR)/halt.target.wants && \
-- rm -f plymouth-halt.service) \
-+ rm -f plymouth-halt.service)
- rmdir --ignore-fail-on-non-empty \
- $(DESTDIR)$(SYSTEMD_UNIT_DIR)/sysinit.target.wants \
- $(DESTDIR)$(SYSTEMD_UNIT_DIR)/multi-user.target.wants \
-diff --git a/themes/script/script.script b/themes/script/script.script
-index 7ea9d5e..25a2f2b 100644
---- a/themes/script/script.script
-+++ b/themes/script/script.script
-@@ -152,27 +152,19 @@ Plymouth.SetQuitFunction(quit_callback);
-
- #----------------------------------------- Message --------------------------------
-
--message_sprites = [];
--message_sprite_count = 0;
--message_sprite_y = 10;
-+message_sprite = Sprite();
-+message_sprite.SetPosition(10, 10, 10000);
-
- fun display_message_callback (text)
- {
- my_image = Image.Text(text, 1, 1, 1);
-- message_sprites[message_sprite_count] = Sprite(my_image);
-- message_sprites[message_sprite_count].SetPosition(10, message_sprite_y, 10000);
-- message_sprites[message_sprite_count].text = text;
-- message_sprite_count++;
-- message_sprite_y += my_image.GetHeight();
-+ message_sprite.SetImage(my_image);
- }
-
- fun hide_message_callback (text)
- {
-- for (i = 0; i < message_sprite_count; i++)
-- {
-- if (message_sprites[i].text == text)
-- message_sprites[i] = NULL;
-- }
-+ message_sprite = Sprite();
-+ message_sprite.SetPosition(10, 10, 10000);
- }
-
- Plymouth.SetDisplayMessageFunction (display_message_callback);