[packages/plymouth] - added git patch to update the package to current state - removed Fedora junk - removed duplicate s
baggins
baggins at pld-linux.org
Tue Apr 29 19:50:23 CEST 2014
commit 612b1f7781e3faa0950b6e9d8cdf6be7d009849b
Author: Jan Rękorajski <baggins at pld-linux.org>
Date: Tue Apr 29 19:39:57 2014 +0200
- added git patch to update the package to current state
- removed Fedora junk
- removed duplicate services provided upstream
- static libs no longer provided by upstream
- updated patches
- rel 9
charge.plymouth | 13 -
path-udevadm.patch | 11 -
plymouth-git.patch | 11238 ++++++++++++++++++++++++++++++++
plymouth.spec | 121 +-
systemd-ask-password-plymouth.path | 20 -
systemd-ask-password-plymouth.service | 19 -
text-colors.patch | 19 +-
7 files changed, 11294 insertions(+), 147 deletions(-)
---
diff --git a/plymouth.spec b/plymouth.spec
index 3297aeb..894f4f4 100644
--- a/plymouth.spec
+++ b/plymouth.spec
@@ -1,20 +1,15 @@
# TODO
# - integrate with geninitrd
# - pldize recent update (r1.18)
-# - verify if systemd services have to be installed for targets,
-# and remove the symlinks if not
#
# Conditional build:
-%bcond_without drm_intel # disable building with libdrm_intel support
-%bcond_without drm_radeon # disable building with libdrm_radeon support
-%bcond_with drm_nouveau # enable building with libdrm_nouveau support
-%bcond_without kms # disable building with libkms support
+%bcond_without drm # disable building with DRM renderer support
Summary: Graphical Boot Animation and Logger
Summary(pl.UTF-8): Graficzna animacja i logowanie startu systemu
Name: plymouth
Version: 0.8.8
-Release: 8
+Release: 9
License: GPL v2+
Group: Base
Source0: http://www.freedesktop.org/software/plymouth/releases/%{name}-%{version}.tar.bz2
@@ -22,25 +17,20 @@ Source0: http://www.freedesktop.org/software/plymouth/releases/%{name}-%{version
Source1: %{name}-logo.png
# Source1-md5: 6b38a868585adfd3a96a4ad16973c1f8
Source2: %{name}.tmpfiles
-Source3: charge.%{name}
Source4: boot-duration
-Source5: %{name}-set-default-plugin
Source6: %{name}-update-initrd
-Source7: systemd-ask-password-plymouth.path
-Source8: systemd-ask-password-plymouth.service
Patch0: text-colors.patch
-Patch1: path-udevadm.patch
-Patch2: %{name}-restore-suspend.patch
+Patch1: %{name}-restore-suspend.patch
+Patch100: %{name}-git.patch
URL: http://www.freedesktop.org/wiki/Software/Plymouth
BuildRequires: cairo-devel
BuildRequires: gtk+2-devel >= 2:2.12.0
-%if %{with drm_intel} || %{with drm_radeon} || %{with drm_nouveau} || %{with kms}
-BuildRequires: libdrm-devel
-%endif
BuildRequires: xorg-lib-libpciaccess-devel
+%{?with_drm:BuildRequires: libdrm-devel}
BuildRequires: libpng-devel >= 2:1.2.16
BuildRequires: pango-devel >= 1:1.21.0
BuildRequires: pkgconfig
+BuildRequires: udev-devel
Requires: %{name}-graphics-libs = %{version}-%{release}
Requires(post): %{name}-scripts = %{version}-%{release}
Requires: /etc/os-release
@@ -253,23 +243,22 @@ This metapackage tracks the current distribution default theme.
%description system-theme -l pl.UTF-8
Ten metapakiet śledzi domyślny motyw dystrybucji.
-%package theme-charge
-Summary: Plymouth "Charge" theme
-Summary(pl.UTF-8): Motyw Plymouth "Charge"
+%package theme-glow
+Summary: Plymouth "Glow" theme
+Summary(pl.UTF-8): Motyw Plymouth "Glow"
Group: Base
Requires: %{name}-plugin-two-step = %{version}-%{release}
Requires(post): %{name}-scripts = %{version}-%{release}
Provides: %{name}(system-theme) = %{version}-%{release}
+Obsoletes: plymouth-theme-charge
-%description theme-charge
-This package contains the "charge" boot splash theme for Plymouth. It
-features the shadowy hull of a Fedora logo charge up and and finally
-burst into full form.
+%description theme-glow
+This package contains the "Glow" boot splash theme for Plymouth.
+Corporate theme with pie chart boot progress followed by a glowing
+emerging logo.
-%description theme-charge -l pl.UTF-8
-Ten pakiet zawiera motyw ekranu startowego Plymouth "Charge". Odznacza
-się on cieniowaną łupiną loga Fedory, która rośnie, a ostatecznie
-wybucha do pełnej postaci.
+%description theme-glow -l pl.UTF-8
+Ten pakiet zawiera motyw ekranu startowego Plymouth "Glow".
%package theme-fade-in
Summary: Plymouth "Fade-In" theme
@@ -357,21 +346,21 @@ Odznacza się on małym kółkiem kręcącym się na ciemnym tle.
%prep
%setup -q
+%patch100 -p1
%patch0 -p1
%patch1 -p1
-%patch2 -p1
-
-# Change the default theme
-sed -i -e 's/fade-in/charge/g' src/plymouthd.defaults
%build
+%{__aclocal}
+%{__autoconf}
+%{__autoheader}
+%{__automake}
%configure \
- %{__enable_disable drm_intel libdrm_intel} \
- %{__enable_disable drm_radeon libdrm_radeon} \
- %{__enable_disable drm_nouveau libdrm_nouveau} \
- %{__enable_disable kms libkms} \
+ UDEVADM=/sbin/udevadm \
+ SYSTEMD_ASK_PASSWORD_AGENT=/bin/systemd-tty-ask-password-agent \
+ %{__enable_disable drm drm} \
--disable-silent-rules \
- --disable-tests \
+ --enable-documentation \
--disable-gdm-transition \
--enable-systemd-integration \
--enable-tracing \
@@ -392,7 +381,6 @@ install -d $RPM_BUILD_ROOT{%{_bindir},%{_libdir},%{_pixmapsdir},%{systemdtmpfile
%{__make} install \
DESTDIR=$RPM_BUILD_ROOT
-%{__mv} $RPM_BUILD_ROOT/%{_lib}/lib*.a $RPM_BUILD_ROOT%{_libdir}
ln -sf /%{_lib}/$(basename $RPM_BUILD_ROOT/%{_lib}/libply.so.*.*.*) $RPM_BUILD_ROOT%{_libdir}/libply.so
ln -sf /%{_lib}/$(basename $RPM_BUILD_ROOT/%{_lib}/libply-splash-core.so.*.*.*) $RPM_BUILD_ROOT%{_libdir}/libply-splash-core.so
%{__rm} $RPM_BUILD_ROOT/%{_lib}/libply{,-splash-core}.so
@@ -401,47 +389,18 @@ install -d $RPM_BUILD_ROOT%{_localstatedir}/lib/plymouth
cp -p %{SOURCE4} $RPM_BUILD_ROOT%{_datadir}/plymouth/default-boot-duration
> $RPM_BUILD_ROOT%{_localstatedir}/lib/plymouth/boot-duration
-# FC: Add charge, our new default
-install -d $RPM_BUILD_ROOT%{_datadir}/plymouth/themes/charge
-cp %{SOURCE3} $RPM_BUILD_ROOT%{_datadir}/plymouth/themes/charge
-cp $RPM_BUILD_ROOT%{_datadir}/plymouth/themes/glow/{box,bullet,entry,lock}.png $RPM_BUILD_ROOT%{_datadir}/plymouth/themes/charge
-
-# FC: Drop glow, it's not very Fedora-y
-%{__rm} -r $RPM_BUILD_ROOT%{_datadir}/plymouth/themes/glow
-
-# FC: Override plymouth-update-initrd to work dracut or mkinitrd
+# Override plymouth-update-initrd to work with dracut or mkinitrd
cp -p %{SOURCE6} $RPM_BUILD_ROOT%{_libdir}/plymouth/plymouth-update-initrd
-# FC: Add compat script for upgrades
-install -p %{SOURCE5} $RPM_BUILD_ROOT%{_sbindir}
-
%{__rm} $RPM_BUILD_ROOT{/%{_lib},%{_libdir}}/*.la \
- $RPM_BUILD_ROOT%{_libdir}/plymouth/*.{a,la} \
- $RPM_BUILD_ROOT%{_libdir}/plymouth/renderers/*.{a,la}
-
-# Temporary symlink until rc.sysinit is fixed
-ln -sf /bin/plymouth $RPM_BUILD_ROOT%{_bindir}/plymouth
+ $RPM_BUILD_ROOT%{_libdir}/plymouth/*.la \
+ $RPM_BUILD_ROOT%{_libdir}/plymouth/renderers/*.la
install -d $RPM_BUILD_ROOT%{_localstatedir}/lib/plymouth
cp -p %{SOURCE1} $RPM_BUILD_ROOT%{_pixmapsdir}/plymouth-logo.png
cp -p %{SOURCE2} $RPM_BUILD_ROOT%{systemdtmpfilesdir}/%{name}.conf
-cp -p %{SOURCE7} $RPM_BUILD_ROOT%{systemdunitdir}/systemd-ask-password-plymouth.path
-cp -p %{SOURCE8} $RPM_BUILD_ROOT%{systemdunitdir}/systemd-ask-password-plymouth.service
-
-# install plymouth services for targets
-# http://cgit.freedesktop.org/systemd/systemd/commit/?id=26cbf29c52a36b6ad9d1ccc16d8f7adccefeddca
-install -d $RPM_BUILD_ROOT%{systemdunitdir}/{halt,kexec,poweroff,reboot,sysinit,multi-user}.target.wants
-ln -sf ../plymouth-start.service $RPM_BUILD_ROOT%{systemdunitdir}/sysinit.target.wants/plymouth-start.service
-ln -sf ../plymouth-read-write.service $RPM_BUILD_ROOT%{systemdunitdir}/sysinit.target.wants/plymouth-read-write.service
-ln -sf ../plymouth-quit.service $RPM_BUILD_ROOT%{systemdunitdir}/multi-user.target.wants/plymouth-quit.service
-ln -sf ../plymouth-quit-wait.service $RPM_BUILD_ROOT%{systemdunitdir}/multi-user.target.wants/plymouth-quit-wait.service
-ln -sf ../plymouth-reboot.service $RPM_BUILD_ROOT%{systemdunitdir}/reboot.target.wants/plymouth-reboot.service
-ln -sf ../plymouth-kexec.service $RPM_BUILD_ROOT%{systemdunitdir}/kexec.target.wants/plymouth-kexec.service
-ln -sf ../plymouth-poweroff.service $RPM_BUILD_ROOT%{systemdunitdir}/poweroff.target.wants/plymouth-poweroff.service
-ln -sf ../plymouth-halt.service $RPM_BUILD_ROOT%{systemdunitdir}/halt.target.wants/plymouth-halt.service
-
%clean
rm -rf $RPM_BUILD_ROOT
@@ -462,7 +421,6 @@ fi
%files
%defattr(644,root,root,755)
%doc AUTHORS README TODO
-%attr(755,root,root) %{_bindir}/plymouth
%dir %{_sysconfdir}/plymouth
%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/plymouth/plymouthd.conf
%{_mandir}/man8/plymouth.8*
@@ -470,22 +428,27 @@ fi
%attr(755,root,root) /sbin/plymouthd
%attr(755,root,root) %{_libdir}/plymouth/details.so
%attr(755,root,root) %{_libdir}/plymouth/text.so
+%attr(755,root,root) %{_libdir}/plymouth/tribar.so
%attr(755,root,root) %{_libdir}/plymouth/renderers/drm.so
%attr(755,root,root) %{_libdir}/plymouth/renderers/frame-buffer.so
%dir %{_datadir}/plymouth
%dir %{_datadir}/plymouth/themes
%dir %{_datadir}/plymouth/themes/details
%dir %{_datadir}/plymouth/themes/text
+%dir %{_datadir}/plymouth/themes/tribar
%{_datadir}/plymouth/plymouthd.defaults
%{_datadir}/plymouth/default-boot-duration
%{_datadir}/plymouth/themes/details/details.plymouth
%{_datadir}/plymouth/themes/text/text.plymouth
+%{_datadir}/plymouth/themes/tribar/tribar.plymouth
%{_pixmapsdir}/plymouth-logo.png
%{systemdtmpfilesdir}/%{name}.conf
%dir %{_localstatedir}/lib/plymouth
%ghost %{_localstatedir}/lib/plymouth/boot-duration
%{_localstatedir}/run/plymouth
%{_localstatedir}/spool/plymouth
+%{_mandir}/man1/plymouth.1*
+%{_mandir}/man8/plymouthd.8*
%{systemdunitdir}/plymouth-halt.service
%{systemdunitdir}/plymouth-kexec.service
@@ -501,6 +464,7 @@ fi
%{systemdunitdir}/halt.target.wants/plymouth-halt.service
%dir %{systemdunitdir}/initrd-switch-root.target.wants
%{systemdunitdir}/initrd-switch-root.target.wants/plymouth-switch-root.service
+%{systemdunitdir}/initrd-switch-root.target.wants/plymouth-start.service
%{systemdunitdir}/kexec.target.wants/plymouth-kexec.service
%{systemdunitdir}/multi-user.target.wants/plymouth-quit.service
%{systemdunitdir}/multi-user.target.wants/plymouth-quit-wait.service
@@ -537,20 +501,13 @@ fi
%{_pkgconfigdir}/ply-splash-core.pc
%{_pkgconfigdir}/ply-splash-graphics.pc
-%files static
-%defattr(644,root,root,755)
-%attr(755,root,root) %{_libdir}/libply.a
-%attr(755,root,root) %{_libdir}/libply-boot-client.a
-%attr(755,root,root) %{_libdir}/libply-splash-core.a
-%attr(755,root,root) %{_libdir}/libply-splash-graphics.a
-
%files scripts
%defattr(644,root,root,755)
-%attr(755,root,root) %{_sbindir}/plymouth-set-default-plugin
%attr(755,root,root) %{_sbindir}/plymouth-set-default-theme
%attr(755,root,root) %{_libdir}/plymouth/plymouth-generate-initrd
%attr(755,root,root) %{_libdir}/plymouth/plymouth-populate-initrd
%attr(755,root,root) %{_libdir}/plymouth/plymouth-update-initrd
+%{_mandir}/man1/plymouth-set-default-theme.1*
%files plugin-fade-throbber
%defattr(644,root,root,755)
@@ -579,11 +536,11 @@ fi
%files system-theme
%defattr(644,root,root,755)
-%files theme-charge
+%files theme-glow
%defattr(644,root,root,755)
-%dir %{_datadir}/plymouth/themes/charge
-%{_datadir}/plymouth/themes/charge/*.png
-%{_datadir}/plymouth/themes/charge/charge.plymouth
+%dir %{_datadir}/plymouth/themes/glow
+%{_datadir}/plymouth/themes/glow/*.png
+%{_datadir}/plymouth/themes/glow/glow.plymouth
%files theme-fade-in
%defattr(644,root,root,755)
diff --git a/charge.plymouth b/charge.plymouth
deleted file mode 100644
index f499c0f..0000000
--- a/charge.plymouth
+++ /dev/null
@@ -1,13 +0,0 @@
-[Plymouth Theme]
-Name=Charge
-Description=A theme that features the shadowy hull of a Fedora logo charge up and and finally burst into into full form.
-ModuleName=two-step
-
-[two-step]
-ImageDir=/usr/share/plymouth/themes/charge
-HorizontalAlignment=.5
-VerticalAlignment=.5
-Transition=none
-TransitionDuration=0.0
-BackgroundStartColor=0x202020
-BackgroundEndColor=0x202020
diff --git a/path-udevadm.patch b/path-udevadm.patch
deleted file mode 100644
index 42970b6..0000000
--- a/path-udevadm.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- plymouth-0.8.8/systemd-units/plymouth-start.service.in.orig 2012-10-31 20:43:34.695979769 +0100
-+++ plymouth-0.8.8/systemd-units/plymouth-start.service.in 2012-10-31 20:44:47.219310059 +0100
-@@ -8,7 +8,7 @@
-
- [Service]
- ExecStart=@PLYMOUTH_DAEMON_DIR@/plymouthd --mode=boot --pid-file=@plymouthruntimedir@/pid --attach-to-session
--ExecStartPost=-/bin/udevadm settle --timeout=30 --exit-if-exists=/sys/class/drm/card0/dev ; /bin/udevadm settle --timeout=30 --exit-if-exists=/sys/class/graphics/fb0/dev ; @PLYMOUTH_CLIENT_DIR@/plymouth show-splash
-+ExecStartPost=-/sbin/udevadm settle --timeout=30 --exit-if-exists=/sys/class/drm/card0/dev ; /sbin/udevadm settle --timeout=30 --exit-if-exists=/sys/class/graphics/fb0/dev ; @PLYMOUTH_CLIENT_DIR@/plymouth show-splash
- Type=forking
- KillMode=none
- SendSIGKILL=no
diff --git a/plymouth-git.patch b/plymouth-git.patch
new file mode 100644
index 0000000..a5c8b3c
--- /dev/null
+++ b/plymouth-git.patch
@@ -0,0 +1,11238 @@
+diff --git a/Makefile.am b/Makefile.am
+index b322463..395c91b 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1,4 +1,8 @@
+-SUBDIRS = src themes images scripts docs systemd-units
++SUBDIRS = src themes images scripts systemd-units
++
++if BUILD_DOCUMENTATION
++SUBDIRS += docs
++endif
+
+ DISTCHECK_CONFIGURE_FLAGS = --disable-tests --without-system-root-install
+
+diff --git a/configure.ac b/configure.ac
+index 2ab0893..9c8f863 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -6,7 +6,7 @@ AC_CONFIG_AUX_DIR(build-tools)
+ AC_USE_SYSTEM_EXTENSIONS
+ AC_SYS_LARGEFILE
+ AC_PROG_AWK
+-AC_PROG_CC
++AC_PROG_CC_STDC
+ AM_PROG_CC_C_O
+ AC_HEADER_STDC
+ AC_C_CONST
+@@ -16,7 +16,7 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+ AM_MAINTAINER_MODE([enable])
+
+ PKG_PROG_PKG_CONFIG
+-LT_INIT
++LT_INIT([dlopen disable-static pic-only])
+
+ ## increment if the interface has additions, changes, removals.
+ LT_CURRENT=3
+@@ -38,12 +38,19 @@ PKG_CHECK_MODULES(IMAGE, [libpng >= 1.2.16 ])
+ AC_SUBST(IMAGE_CFLAGS)
+ AC_SUBST(IMAGE_LIBS)
+
++PKG_CHECK_MODULES(UDEV, [libudev]);
++AC_SUBST(UDEV_CFLAGS)
++AC_SUBST(UDEV_LIBS)
++
+ PLYMOUTH_CFLAGS=""
+ PLYMOUTH_LIBS="-lm -lrt -ldl"
+
+ AC_SUBST(PLYMOUTH_CFLAGS)
+ AC_SUBST(PLYMOUTH_LIBS)
+
++AC_PATH_PROG([SYSTEMD_ASK_PASSWORD_AGENT], [systemd-tty-ask-password-agent])
++AC_PATH_PROG([UDEVADM], [udevadm])
++
+ AC_ARG_ENABLE(pango, AS_HELP_STRING([--enable-pango],[enable building with pango, disabled there is no encryption prompts]),enable_pango=$enableval,enable_pango=yes)
+ AM_CONDITIONAL(ENABLE_PANGO, [test "$enable_pango" = yes])
+
+@@ -62,148 +69,6 @@ if test x$enable_gtk = xyes; then
+ AC_SUBST(GTK_LIBS)
+ fi
+
+-AC_ARG_ENABLE(libdrm_intel, AS_HELP_STRING([--enable-libdrm_intel],[enable building with libdrm_intel support]),enable_libdrm_intel=$enableval,enable_libdrm_intel=no)
+-AM_CONDITIONAL(ENABLE_LIBDRM_INTEL, [test "$enable_libdrm_intel" = yes])
+-
+-if test x$enable_libdrm_intel = xyes; then
+- PKG_CHECK_MODULES(DRM_INTEL, [libdrm libdrm_intel])
+- OLD_CFLAGS="$CFLAGS"
+- CFLAGS="$CFLAGS $DRM_INTEL_CFLAGS"
+- AC_MSG_CHECKING([if i915_drm.h is in include path])
+- AC_COMPILE_IFELSE(AC_LANG_PROGRAM(
+- [[
+- #include <stdint.h>
+- #include <stdlib.h>
+- #include "i915_drm.h"
+- ]],[[]]),[found_drm_intel_kernel_headers=yes],[found_drm_intel_kernel_headers=no])
+-
+- if test "$found_drm_intel_kernel_headers" = "yes"; then
+- AC_MSG_RESULT([yes])
+- else
+- AC_MSG_RESULT([no])
+- AC_MSG_CHECKING([if we can find them anyway])
+-
+- MORE_DRM_CFLAGS="-I`$PKG_CONFIG --variable includedir libdrm`/drm"
+- CFLAGS="$CFLAGS $MORE_DRM_CFLAGS"
+- AC_COMPILE_IFELSE(AC_LANG_PROGRAM(
+- [[
+- #include <stdint.h>
+- #include <stdlib.h>
+- #include "i915_drm.h"
+- ]],[[]]),[found_drm_intel_kernel_headers=yes],[found_drm_intel_kernel_headers=no])
+-
+- if test "$found_drm_intel_kernel_headers" = "yes"; then
+- AC_MSG_RESULT([yes])
+- DRM_INTEL_CFLAGS="$DRM_INTEL_CFLAGS $MORE_DRM_CFLAGS"
+- else
+- AC_MSG_RESULT([no])
+- AC_MSG_ERROR([Could not find i915_drm.h])
+- fi
+- fi
+-
+- AC_SUBST(DRM_INTEL_CFLAGS)
+- AC_SUBST(DRM_INTEL_LIBS)
+- AC_DEFINE(PLY_ENABLE_LIBDRM_INTEL, 1, [Enable support for libdrm_intel driver])
+-fi
+-
+-AC_ARG_ENABLE(libdrm_radeon, AS_HELP_STRING([--enable-libdrm_radeon],[enable building with libdrm_radeon support]),enable_libdrm_radeon=$enableval,enable_libdrm_radeon=no)
+-AM_CONDITIONAL(ENABLE_LIBDRM_RADEON, [test "$enable_libdrm_radeon" = yes])
+-
+-if test x$enable_libdrm_radeon = xyes; then
+- PKG_CHECK_MODULES(DRM_RADEON, [libdrm libdrm_radeon])
+- OLD_CFLAGS="$CFLAGS"
+- CFLAGS="$CFLAGS $DRM_RADEON_CFLAGS"
+- AC_MSG_CHECKING([if radeon_drm.h is in include path])
+- AC_COMPILE_IFELSE(AC_LANG_PROGRAM(
+- [[
+- #include <stdint.h>
+- #include <stdlib.h>
+- #include "radeon_drm.h"
+- ]],[[]]),[found_drm_radeon_kernel_headers=yes],[found_drm_radeon_kernel_headers=no])
+-
+- if test "$found_drm_radeon_kernel_headers" = "yes"; then
+- AC_MSG_RESULT([yes])
+- else
+- AC_MSG_RESULT([no])
+- AC_MSG_CHECKING([if we can find them anyway])
+-
+- MORE_DRM_CFLAGS="-I`$PKG_CONFIG --variable includedir libdrm`/drm"
+- CFLAGS="$CFLAGS $MORE_DRM_RADEON_CFLAGS"
+- AC_COMPILE_IFELSE(AC_LANG_PROGRAM(
+- [[
+- #include <stdint.h>
+- #include <stdlib.h>
+- #include "radeon_drm.h"
+- ]],[[]]),[found_drm_radeon_kernel_headers=yes],[found_drm_radeon_kernel_headers=no])
+-
+- if test "$found_drm_radeon_kernel_headers" = "yes"; then
+- AC_MSG_RESULT([yes])
+- DRM_RADEON_CFLAGS="$DRM_RADEON_CFLAGS $MORE_DRM_CFLAGS"
+- else
+- AC_MSG_RESULT([no])
+- AC_MSG_ERROR([Could not find radeon_drm.h])
+- fi
+- fi
+-
+- AC_SUBST(DRM_RADEON_CFLAGS)
+- AC_SUBST(DRM_RADEON_LIBS)
+- AC_DEFINE(PLY_ENABLE_LIBDRM_RADEON, 1, [Enable support for libdrm_radeon driver])
+-fi
+-
+-AC_ARG_ENABLE(libdrm_nouveau, AS_HELP_STRING([--enable-libdrm_nouveau],[enable building with libdrm_nouveau support]),enable_libdrm_nouveau=$enableval,enable_libdrm_nouveau=no)
+-AM_CONDITIONAL(ENABLE_LIBDRM_NOUVEAU, [test "$enable_libdrm_nouveau" = yes])
+-
+-if test x$enable_libdrm_nouveau = xyes; then
+- PKG_CHECK_MODULES(DRM_NOUVEAU, [libdrm libdrm_nouveau])
+- OLD_CFLAGS="$CFLAGS"
+- CFLAGS="$CFLAGS $DRM_NOUVEAU_CFLAGS"
+- AC_MSG_CHECKING([if nouveau_drm.h is in include path])
+- AC_COMPILE_IFELSE(AC_LANG_PROGRAM(
+- [[
+- #include <stdint.h>
+- #include <stdlib.h>
+- #include "nouveau_drm.h"
+- ]],[[]]),[found_drm_nouveau_kernel_headers=yes],[found_drm_nouveau_kernel_headers=no])
+-
+- if test "$found_drm_nouveau_kernel_headers" = "yes"; then
+- AC_MSG_RESULT([yes])
+- else
+- AC_MSG_RESULT([no])
+- AC_MSG_CHECKING([if we can find them anyway])
+-
+- MORE_DRM_CFLAGS="-I`$PKG_CONFIG --variable includedir libdrm`/drm"
+- CFLAGS="$CFLAGS $MORE_DRM_CFLAGS"
+- AC_COMPILE_IFELSE(AC_LANG_PROGRAM(
+- [[
+- #include <stdint.h>
+- #include <stdlib.h>
+- #include "nouveau_drm.h"
+- ]],[[]]),[found_drm_nouveau_kernel_headers=yes],[found_drm_nouveau_kernel_headers=no])
+-
+- if test "$found_drm_nouveau_kernel_headers" = "yes"; then
+- AC_MSG_RESULT([yes])
+- DRM_NOUVEAU_CFLAGS="$DRM_NOUVEAU_CFLAGS $MORE_DRM_CFLAGS"
+- else
+- AC_MSG_RESULT([no])
+- AC_MSG_ERROR([Could not find nouveau_drm.h])
+- fi
+- fi
+-
+- AC_SUBST(DRM_NOUVEAU_CFLAGS)
+- AC_SUBST(DRM_NOUVEAU_LIBS)
+- AC_DEFINE(PLY_ENABLE_LIBDRM_NOUVEAU, 1, [Enable support for libdrm_nouveau driver])
+-fi
+-
+-AC_ARG_ENABLE(libkms, AS_HELP_STRING([--enable-libkms],[enable building with libkms support]),enable_libkms=$enableval,enable_libkms=no)
+-AM_CONDITIONAL(ENABLE_LIBKMS, [test "$enable_libkms" = yes])
+-
+-if test x$enable_libkms = xyes; then
+- PKG_CHECK_MODULES(LIBKMS, [libdrm libkms])
+- AC_SUBST(LIBKMS_CFLAGS)
+- AC_SUBST(LIBKMS_LIBS)
+- AC_DEFINE(PLY_ENABLE_LIBKMS, 1, [Enable support for libkms abstraction over drm drivers])
+-fi
+-
+ AC_ARG_ENABLE(drm, AS_HELP_STRING([--enable-drm-renderer],[enable building drm kms support]),enable_drm_renderer=$enableval,enable_drm_renderer=yes)
+ AM_CONDITIONAL(ENABLE_DRM_RENDERER, [test "$enable_drm_renderer" = yes])
+
+@@ -211,10 +76,17 @@ if test x$enable_drm_renderer = xyes; then
+ PKG_CHECK_MODULES(DRM, [libdrm])
+ fi
+
+-DRM_CFLAGS="$DRM_CFLAGS $DRM_INTEL_CFLAGS $DRM_RADEON_CFLAGS $DRM_NOUVEAU_CFLAGS $LIBKMS_CFLAG"
+-DRM_LIBS="$DRM_LIBS $DRM_INTEL_LIBS $DRM_RADEON_LIBS $DRM_NOUVEAU_LIBS $LIBKMS_LIBS"
+-AC_SUBST(DRM_CFLAGS)
+-AC_SUBST(DRM_LIBS)
++AC_ARG_ENABLE(documentation,
++ AS_HELP_STRING([--enable-documentation],
++ [build documentation]),,
++ enable_documentation=yes)
++if test x$enable_documentation = xyes; then
++ AC_PATH_PROG([XSLTPROC], [xsltproc])
++ if test x$XSLTPROC = x; then
++ AC_MSG_ERROR([xsltproc is required to build documentation])
++ fi
++fi
++AM_CONDITIONAL(BUILD_DOCUMENTATION, test x$enable_documentation = xyes)
+
+ AC_ARG_ENABLE(tracing, AS_HELP_STRING([--enable-tracing],[enable verbose tracing code]),enable_tracing=$enableval,enable_tracing=yes)
+
+@@ -222,10 +94,6 @@ if test x$enable_tracing = xyes; then
+ AC_DEFINE(PLY_ENABLE_TRACING, 1, [Build in verbose debug tracing spew])
+ fi
+
+-AC_ARG_ENABLE(tests, AS_HELP_STRING([--enable-tests],[build tests]),enable_tests=$enableval,enable_tests=yes)
+-
+-AM_CONDITIONAL(ENABLE_TESTS, [test "$enable_tests" = yes])
+-
+ AC_ARG_ENABLE(gdm-transition, AS_HELP_STRING([--enable-gdm-transition],[enable smooth transition to gdm]),enable_gdm_transition=$enableval,enable_gdm_transition=no)
+
+ if test x$enable_gdm_transition = xyes; then
+@@ -254,7 +122,7 @@ AM_CONDITIONAL(ENABLE_SYSTEMD_INTEGRATION, [test "$enable_systemd_integration" =
+
+ if test x$enable_systemd_integration = xyes; then
+ AC_DEFINE(PLY_ENABLE_SYSTEMD_INTEGRATION, 1, [Coordinate boot up with systemd])
+- SYSTEMD_UNIT_DIR=/lib/systemd/system
++ SYSTEMD_UNIT_DIR=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)
+ AC_SUBST(SYSTEMD_UNIT_DIR)
+ fi
+
+@@ -278,7 +146,7 @@ AS_AC_EXPAND(PLYMOUTH_CLIENT_DIR, $plymouthclientdir)
+ AS_AC_EXPAND(PLYMOUTH_DAEMON_DIR, $plymouthdaemondir)
+ AS_AC_EXPAND(PLYMOUTH_RUNTIME_DIR, $plymouthruntimedir)
+
+-AC_ARG_WITH(rhgb-compat-link, AS_HELP_STRING([--with-rhgb-compat-link],[Install /usr/bin/rhgb-client compatability symlink]),with_rhgb_compat_link=${withval},with_rhgb_compat_link=yes)
++AC_ARG_WITH(rhgb-compat-link, AS_HELP_STRING([--with-rhgb-compat-link],[Install /usr/bin/rhgb-client compatability symlink]),with_rhgb_compat_link=${withval},with_rhgb_compat_link=no)
+ AM_CONDITIONAL(WITH_RHGB_COMPAT_LINK, [test "$with_rhgb_compat_link" = yes])
+
+ AC_ARG_WITH(log-viewer, AS_HELP_STRING([--with-log-viewer],[Install plymouth log viewer]),with_log_viewer=${withval},with_log_viewer=no)
+@@ -328,7 +196,7 @@ AC_DEFUN([PLYMOUTH_CC_TRY_FLAG], [
+ plymouth_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $1"
+
+- AC_COMPILE_IFELSE([ ], [plymouth_cc_flag=yes], [plymouth_cc_flag=no])
++ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ ]], [[ ]])], [plymouth_cc_flag=yes], [plymouth_cc_flag=no])
+ CFLAGS="$plymouth_save_CFLAGS"
+
+ if test "x$plymouth_cc_flag" = "xyes"; then
+@@ -357,7 +225,7 @@ if test "$GCC" = "yes" -a "$set_more_warnings" != "no"; then
+ -Wchar-subscripts -Wmissing-declarations -Wmissing-prototypes \
+ -Wwrite-strings -Wnested-externs -Wpointer-arith \
+ -Wswitch-enum -Wstrict-aliasing=2 -Winit-self -Wunsafe-loop-optimizations \
+- -Wno-missing-field-initializers -Wno-unused-parameter \
++ -Wno-missing-field-initializers -Wno-unused-parameter -Wno-unused-result \
+ -Wcast-align -Wsign-compare -Wp,-D_FORTIFY_SOURCE=2"
+ elif test "$GCC" = "yes"; then
+ AC_MSG_RESULT(no)
+@@ -427,6 +295,7 @@ AC_CONFIG_FILES([Makefile
+ src/plugins/splash/Makefile
+ src/plugins/splash/throbgress/Makefile
+ src/plugins/splash/fade-throbber/Makefile
++ src/plugins/splash/tribar/Makefile
+ src/plugins/splash/text/Makefile
+ src/plugins/splash/details/Makefile
+ src/plugins/splash/space-flares/Makefile
+@@ -439,12 +308,10 @@ AC_CONFIG_FILES([Makefile
+ src/client/Makefile
+ src/viewer/Makefile
+ src/upstart-bridge/Makefile
+- src/tests/Makefile
+- src/libply/tests/Makefile
+- src/client/tests/Makefile
+ themes/Makefile
+ themes/spinfinity/Makefile
+ themes/fade-in/Makefile
++ themes/tribar/Makefile
+ themes/text/Makefile
+ themes/details/Makefile
+ themes/solar/Makefile
+diff --git a/docs/Makefile.am b/docs/Makefile.am
+index dedda55..1a9f7ea 100644
+--- a/docs/Makefile.am
++++ b/docs/Makefile.am
+@@ -1,4 +1,31 @@
+-dist_man_MANS = plymouth.8
++XSLTPROC_FLAGS = \
++ --nonet \
++ --stringparam man.output.quietly 1 \
++ --stringparam funcsynopsis.style ansi \
++ --stringparam man.th.extra1.suppress 1 \
++ --stringparam man.authors.section.enabled 0 \
++ --stringparam man.copyright.section.enabled 0
+
+-%.html: %.txt
+- asciidoc $(ASCIIDOC_OPTS) -a toc $*.txt
++
++plymouth.1: plymouth1.xml
++ $(AM_V_GEN) $(XSLTPROC) $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $<
++
++%.8: %.xml
++ $(AM_V_GEN) $(XSLTPROC) $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $<
++
++%.1: %.xml
++ $(AM_V_GEN) $(XSLTPROC) $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $<
++
++man_MANS = \
++ plymouth.1 \
++ plymouth.8 \
++ plymouthd.8 \
++ plymouth-set-default-theme.1
++
++EXTRA_DIST = \
++ plymouth.xml \
++ plymouth1.xml \
++ plymouth-set-default-theme.xml \
++ plymouthd.xml
++
++CLEANFILES = $(man_MANS)
+diff --git a/docs/plymouth-set-default-theme.xml b/docs/plymouth-set-default-theme.xml
+new file mode 100644
+index 0000000..efb051e
+--- /dev/null
++++ b/docs/plymouth-set-default-theme.xml
+@@ -0,0 +1,103 @@
++<?xml version='1.0'?>
++<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
++ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
++
++<refentry id="plymouth-set-default-theme">
++
++ <refentryinfo>
++ <title>plymouth-set-default-theme</title>
++ <productname>plymouth</productname>
++
++ <authorgroup>
++ <author>
++ <contrib>Developer</contrib>
++ <firstname>Kristian</firstname>
++ <surname>Høgsberg</surname>
++ </author>
++ <author>
++ <contrib>Developer</contrib>
++ <firstname>Ray</firstname>
++ <surname>Strode</surname>
++ </author>
++ </authorgroup>
++
++ </refentryinfo>
++
++ <refmeta>
++ <refentrytitle>plymouth-set-default-theme</refentrytitle>
++ <manvolnum>1</manvolnum>
++ <refmiscinfo class="manual">User Commands</refmiscinfo>
++ </refmeta>
++
++ <refnamediv>
++ <refname>plymouth-set-default-theme</refname>
++ <refpurpose>Set the plymouth theme</refpurpose>
++ </refnamediv>
++
++ <refsynopsisdiv>
++ <cmdsynopsis>
++ <command>plymouth-set-default-theme <arg choice="opt" rep="repeat">OPTION</arg> <arg choice="opt" rep="norepeat">THEME</arg></command>
++ </cmdsynopsis>
++ </refsynopsisdiv>
++
++ <refsect1>
++ <title>Description</title>
++
++<para>
++When called with a <option>THEME</option> argument,
++the <command>plymouth-set-default-theme</command> command
++changes the preferred boot theme and also performs the necessary
++regeneration of the initial ramdisk (initrd) since plymouth is loaded
++from the boot loader from the initrd prior to the mounting of the root
++filesystem.
++</para>
++
++<para>
++If <command>plymouth-set-default-theme</command> is invoked with no options
++or parameters, it shows the currently selected theme by default. This output
++is used by the helper scripts plymouth-generate-initrd and
++plymouth-update-initrd to set the proper theme in the initial ramdisk.
++</para>
++
++ </refsect1>
++
++ <refsect1>
++ <title>Options</title>
++
++ <para>The following options are understood:</para>
++
++ <variablelist>
++ <varlistentry>
++ <term><option>-h</option>, <option>--help</option></term>
++ <listitem><para>Show summary of options.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><option>-l</option>, <option>--list</option></term>
++ <listitem><para>List available themes.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><option>-r</option>, <option>--reset</option></term>
++ <listitem><para>Reset to default theme.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><option>-R</option>, <option>--rebuild-initrd</option></term>
++ <listitem><para>Rebuild initrd (necessary after changing theme).</para></listitem>
++ </varlistentry>
++ </variablelist>
++ </refsect1>
++
++ <refsect1>
++ <title>See Also</title>
++ <para>
++ <citerefentry><refentrytitle>grub</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
++ <citerefentry><refentrytitle>plymouth</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
++ <citerefentry><refentrytitle>plymouthd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
++ <citerefentry><refentrytitle>plymouth</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
++ <ulink url="http://www.freedesktop.org/wiki/Software/Plymouth">http://www.freedesktop.org/wiki/Software/Plymouth</ulink>
++ </para>
++ </refsect1>
++
++</refentry>
+diff --git a/docs/plymouth.8 b/docs/plymouth.8
+deleted file mode 100644
+index 7f4766b..0000000
+--- a/docs/plymouth.8
++++ /dev/null
+@@ -1,62 +0,0 @@
+-\" Hey, EMACS: -*- nroff -*-
+-.TH PLYMOUTH 8 "December 15, 2009"
+-.SH NAME
+-plymouth \- A graphical boot system and logger
+-.SH SYNOPSIS
+-.B plymouth-set-default-theme
+-.RI [ options ] " \<theme\>"
+-.SH DESCRIPTION
+-\fBplymouth\fP is a graphical boot system for Linux which takes advantage of the kernel-based
+-mode setting (KMS) available for modern graphic cards to provide a seamless, flickerfree
+-and attractive boot screen. It allows to choose between various, static or
+-animated graphical themes to spruce up the startup and avoid the noise
+-generated by the vast amount of kernel messages while the machine boots into X.
+-On systems where kernel-based mode setting is not available, plymouth falls
+-back to a text mode boot screen which provides a simple progress bar to provide
+-feedback during boot.
+-.PP
+-To configure plymouth, that is to choose and install the preferred boot theme, the
+-user has to invoke \fBplymouth-set-default-theme\fP. It changes the configuration
+-to the new theme and also performs the necessary regeneration of the initial ramdisk
+-(initrd) since plymouth is loaded from the boot loader from the initrd
+-prior to the mounting of the root filesystem. The options available to this
+-script are explained in the \fBOPTIONS\fP paragraph.
+-.PP
+-In order for the configured default plymouth theme to be loaded during boot,
+-the option `splash' (or `rhgb' for backward compatibility with the RHGB boot
+-splash) must be provided at the kernel command line. With this command line
+-option, plymouth will default to showing detailed boot output.
+-.SH OPTIONS
+-plymouth-set-default-theme follows the usual GNU command line syntax, with long
+-options starting with two dashes (`-') and short variants of each of them.
+-.TP
+-.B \-h, \-\-help
+-Show summary of options.
+-.TP
+-.B \-l, \-\-list
+-List available themes.
+-.TP
+-.B \-r, \-\-reset
+-Reset to default theme.
+-.TP
+-.B \-R, \-\-rebuild\-initrd
+-Rebuild initrd (necessary after changing theme).
+-.TP
+-.B \<theme-name\>
+-Name of new theme to use. If you want to see which themes are available, invoke the script with just \-\-list.
+-.PP
+-If plymouth-set-default-theme is invoked with no options or parameters, it shows the currently selected theme
+-by default. This output is used by the helper scripts `plymouth-generate-initrd' and `plymouth-update-initrd'
+-to set the proper theme in the initial ramdisk.
+-.SH SEE ALSO
+-.BR grub (8)
+-.br
+-.SH AUTHOR
+-plymouth was originally prototyped and named by Kristian Høgsberg <krh at bitplanet.net>,
+-originally written by Ray Strode <halfline at gmail.com> and has had significant contributions
+-from Charlie Brej <cbrej at cs.man.ac.uk>. It has also had contributions from
+-Peter Jones <pjones at redhat.com>, Adam Jackson <ajax at nwnk.net>,
+-Frederic Crozat <fcrozat at mandriva.com> and others.
+-It can be downloaded here: <http://www.freedesktop.org/wiki/Software/Plymouth>.
+-.PP
+-This manual page was written by Adrian Glaubitz <glaubitz at physik.fu-berlin.de>.
+diff --git a/docs/plymouth.xml b/docs/plymouth.xml
+new file mode 100644
+index 0000000..0f196c6
+--- /dev/null
++++ b/docs/plymouth.xml
+@@ -0,0 +1,86 @@
++<?xml version='1.0'?>
++<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
++ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
++
++<refentry id="plymouth">
++
++ <refentryinfo>
++ <title>plymouth</title>
++ <productname>plymouth</productname>
++
++ <authorgroup>
++ <author>
++ <contrib>Developer</contrib>
++ <firstname>Kristian</firstname>
++ <surname>Høgsberg</surname>
++ </author>
++ <author>
++ <contrib>Developer</contrib>
++ <firstname>Ray</firstname>
++ <surname>Strode</surname>
++ </author>
++ </authorgroup>
++
++ </refentryinfo>
++
++ <refmeta>
++ <refentrytitle>plymouth</refentrytitle>
++ <manvolnum>8</manvolnum>
++ <refmiscinfo class="manual">System Administration</refmiscinfo>
++ </refmeta>
++
++ <refnamediv>
++ <refname>plymouth</refname>
++ <refpurpose>A graphical boot system and logger</refpurpose>
++ </refnamediv>
++
++ <refsect1>
++ <title>Description</title>
++
++<para>
++<command>plymouth</command> is a graphical boot system for Linux which takes advantage of
++the kernel-based mode setting (KMS) available for modern graphic cards
++to provide a seamless, flickerfree and attractive boot screen. It
++allows to choose between various, static or animated graphical themes
++to spruce up the startup and avoid the noise generated by the vast
++amount of kernel messages while the machine boots into X. On systems
++where kernel-based mode setting is not available, plymouth falls back
++to a text mode boot screen which provides a simple progress bar to pro‐
++vide feedback during boot.
++</para>
++<para>
++In order for the configured default plymouth theme to be loaded during
++boot, the option `splash' (or `rhgb' for backward compatibility with
++the RHGB boot splash) must be provided at the kernel command line.
++Without this command line option, plymouth will default to showing
++detailed boot output.
++</para>
++
++<para>
++During the boot process, the user can switch between the graphical theme
++and the detailed boot output using the Escape key.
++</para>
++
++ </refsect1>
++
++ <refsect1>
++ <title>See Also</title>
++ <para>
++ <citerefentry><refentrytitle>grub</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
++ <citerefentry><refentrytitle>plymouth-set-theme</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
++ <citerefentry><refentrytitle>plymouthd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
++ <citerefentry><refentrytitle>plymouth</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
++ <ulink url="http://www.freedesktop.org/wiki/Software/Plymouth">http://www.freedesktop.org/wiki/Software/Plymouth</ulink>
++ </para>
++ </refsect1>
++
++ <refsect1>
++ <title>Authors</title>
++ <para>
++plymouth was originally prototyped and named by Kristian Høgsberg,
++originally written by Ray Strode and has had significant contributions from
++Charlie Brej. It has also had contributions from Peter Jones, Adam Jackson,
++Frederic Crozat and others.
++ </para>
++ </refsect1>
++</refentry>
+diff --git a/docs/plymouth1.xml b/docs/plymouth1.xml
+new file mode 100644
+index 0000000..b484599
+--- /dev/null
++++ b/docs/plymouth1.xml
+@@ -0,0 +1,351 @@
++<?xml version='1.0'?>
++<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
++ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
++
++<refentry id="plymouth-set-default-theme">
++
++ <refentryinfo>
++ <title>plymouth</title>
++ <productname>plymouth</productname>
++
++ <authorgroup>
++ <author>
++ <contrib>Developer</contrib>
++ <firstname>Kristian</firstname>
++ <surname>Høgsberg</surname>
++ </author>
++ <author>
++ <contrib>Developer</contrib>
++ <firstname>Ray</firstname>
++ <surname>Strode</surname>
++ </author>
++ </authorgroup>
++
++ </refentryinfo>
++
++ <refmeta>
++ <refentrytitle>plymouth</refentrytitle>
++ <manvolnum>1</manvolnum>
++ <refmiscinfo class="manual">User Commands</refmiscinfo>
++ </refmeta>
++
++ <refnamediv>
++ <refname>plymouth</refname>
++ <refpurpose>Send commands to plymouthd</refpurpose>
++ </refnamediv>
++
++ <refsynopsisdiv>
++ <cmdsynopsis>
++ <command>plymouth <arg choice="opt" rep="repeat">OPTION</arg></command>
++ </cmdsynopsis>
++ <cmdsynopsis>
++ <command>plymouth <arg choice="plain">COMMAND <arg choice="opt" rep="repeat">OPTION</arg></arg></command>
++ </cmdsynopsis>
++ </refsynopsisdiv>
++
++ <refsect1>
++ <title>Description</title>
++
++<para>
++The <command>plymouth</command> sends commands to a running
++<command>plymouthd</command>. This is used during the boot
++process to control the display of the graphical boot splash.
++</para>
++
++ </refsect1>
++
++ <refsect1>
++ <title>Options</title>
++
++ <para>
++The following options are understood. These options are supported
++for compatibility with the old <command>rhgb-client</command> interface,
++and have been replaced by the commands that are described in the
++next section.
++</para>
++
++ <variablelist>
++ <varlistentry>
++ <term><option>--help</option></term>
++ <listitem><para>Show summary of options.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><option>--debug</option></term>
++ <listitem><para>Enable verbose debug logging.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><option>--get-splash-plugin-path</option></term>
++ <listitem><para>Get directory where splash plugins are installed.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><option>--newroot=<arg>STRING</arg></option></term>
++ <listitem><para>Tell plymouthd that the new root filesystem is mounted.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><option>--quit</option></term>
++ <listitem><para>Tell plymouthd to quit.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><option>--ping</option></term>
++ <listitem><para>Check if plymouthd is running.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><option>--has-active-vt</option></term>
++ <listitem><para>Check if plymouthd has an active vt.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><option>--sysinit</option></term>
++ <listitem><para>Tell plymouthd root filesystem is mounted read-write.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><option>--show-splash</option></term>
++ <listitem><para>Show the splash screen.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><option>--hide-splash</option></term>
++ <listitem><para>Hide the splash screen.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><option>--ask-for-password</option></term>
++ <listitem><para>Ask the user for a password.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><option>--ignore-keystroke=<arg>STRING</arg></option></term>
++ <listitem><para>Remove sensitivity to a keystroke.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><option>--update=<arg>STRING</arg></option></term>
++ <listitem><para>Tell plymouthd an update about boot progress.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><option>--details</option></term>
++ <listitem><para>Tell plymouthd there were errors during boot.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><option>--wait</option></term>
++ <listitem><para>Wait for plymouthd to quit.</para></listitem>
++ </varlistentry>
++ </variablelist>
++ </refsect1>
++
++ <refsect1>
++ <title>Commands</title>
++
++<para>
++The following commands are understood:
++</para>
++ <variablelist>
++ <varlistentry>
++ <term><command>change-mode <arg choice="plain">OPTION</arg></command></term>
++ <listitem><para>Change the operation mode.</para>
++<variablelist>
++<varlistentry>
++ <term><option>--boot-up</option></term>
++ <listitem><para>Start the system up</para></listitem>
++</varlistentry>
++<varlistentry>
++ <term><option>--shutdown</option></term>
++ <listitem><para>Shutting the system up</para></listitem>
++</varlistentry>
++<varlistentry>
++ <term><option>--updates</option></term>
++ <listitem><para>Applying updates</para></listitem>
++</varlistentry>
++</variablelist>
++</listitem>
++ </varlistentry>
++ <varlistentry>
++ <term><command>system-update <arg choice="plain">OPTION</arg></command></term>
++ <listitem><para>Tell plymouthd about boot progress.</para>
++<variablelist>
++<varlistentry>
++ <term><option>--progress=INTEGER</option></term>
++ <listitem><para>The percentage progress of the updates</para></listitem>
++</varlistentry>
++</variablelist>
++</listitem>
++ </varlistentry>
++ <varlistentry>
++ <term><command>update <arg choice="plain">OPTION</arg></command></term>
++ <listitem><para>Tell plymouthd about boot status changes.</para>
++<variablelist>
++<varlistentry>
++ <term><option>--status=STRING</option></term>
++ <listitem><para>Tell plymouthd the current boot status</para></listitem>
++</varlistentry>
++</variablelist>
++</listitem>
++ </varlistentry>
++ <varlistentry>
++ <term><command>update-root-fs <arg choice="plain">OPTION</arg></command></term>
++ <listitem><para>Tell plymouthd about root filesystem changes.</para>
++<variablelist>
++<varlistentry>
++ <term><option>--new-root-dir=STRING</option></term>
++ <listitem><para>Root filesystem is about to change</para></listitem>
++</varlistentry>
++<varlistentry>
++ <term><option>--read-write</option></term>
++ <listitem><para>Root filesystem is no longer read-only</para></listitem>
++</varlistentry>
++</variablelist>
++</listitem>
++ </varlistentry>
++ <varlistentry>
++ <term><command>show-splash</command></term>
++ <listitem><para>Tell plymouthd to show splash screen.</para></listitem>
++ </varlistentry>
++ <varlistentry>
++ <term><command>hide-splash</command></term>
++ <listitem><para>Tell plymouthd to hide splash screen.</para></listitem>
++ </varlistentry>
++ <varlistentry>
++ <term><command>ask-for-password <arg choice="plain">OPTION</arg></command></term>
++ <listitem><para>Ask the user for a password.</para>
++<variablelist>
++<varlistentry>
++ <term><option>--command=STRING</option></term>
++ <listitem><para>Command to send password to via standard input</para></listitem>
++</varlistentry>
++<varlistentry>
++ <term><option>--prompt=STRING</option></term>
++ <listitem><para>Message to display when asking for password</para></listitem>
++</varlistentry>
++<varlistentry>
++ <term><option>--number-of-tries=INTEGER</option></term>
++ <listitem><para>Number of times to ask before giving up (requires <option>--command</option>)</para></listitem>
++</varlistentry>
++<varlistentry>
++ <term><option>--dont-pause-progress</option></term>
++ <listitem><para>Don't pause boot progress bar while asking</para></listitem>
++</varlistentry>
++</variablelist>
++</listitem>
++ </varlistentry>
++ <varlistentry>
++ <term><command>ask-question</command></term>
++ <listitem><para>Ask the user a question.</para>
++<variablelist>
++<varlistentry>
++ <term><option>--command=STRING</option></term>
++ <listitem><para>Command to send the answer to via standard input</para></listitem>
++</varlistentry>
++<varlistentry>
++ <term><option>--prompt=STRING</option></term>
++ <listitem><para>Message to display when asking the question</para></listitem>
++</varlistentry>
++<varlistentry>
++ <term><option>--dont-pause-progress</option></term>
++ <listitem><para>Don't pause boot progress bar while asking</para></listitem>
++</varlistentry>
++</variablelist>
++</listitem>
++ </varlistentry>
++ <varlistentry>
++ <term><command>display-message <arg choice="plain">OPTION</arg></command></term>
++ <listitem><para>Display a message.</para>
++<variablelist>
++<varlistentry>
++ <term><option>--text=STRING</option></term>
++ <listitem><para>The message text</para></listitem>
++</varlistentry>
++</variablelist>
++</listitem>
++ </varlistentry>
++ <varlistentry>
++ <term><command>hide-message <arg choice="plain">OPTION</arg></command></term>
++ <listitem><para>Hide a message.</para>
++<variablelist>
++<varlistentry>
++ <term><option>--text=STRING</option></term>
++ <listitem><para>The message text</para></listitem>
++</varlistentry>
++</variablelist>
++</listitem>
++ </varlistentry>
++ <varlistentry>
++ <term><command>watch-keystroke <arg choice="plain">OPTION</arg></command></term>
++ <listitem><para>Become sensitive to a keystroke.</para>
++<variablelist>
++<varlistentry>
++ <term><option>--command=STRING</option></term>
++ <listitem><para>Command to send keystroke to via standard input</para></listitem>
++</varlistentry>
++<varlistentry>
++ <term><option>--keys=STRING</option></term>
++ <listitem><para>Keys to become sensitive to</para></listitem>
++</varlistentry>
++</variablelist>
++</listitem>
++ </varlistentry>
++ <varlistentry>
++ <term><command>ignore-keystroke <arg choice="plain">OPTION</arg></command></term>
++ <listitem><para>Remove sensitivity to a keystroke.</para>
++<variablelist>
++<varlistentry>
++ <term><option>--keys=STRING</option></term>
++ <listitem><para>Keys to remove sensitivitiy from</para></listitem>
++</varlistentry>
++</variablelist>
++</listitem>
++ </varlistentry>
++ <varlistentry>
++ <term><command>pause-progress</command></term>
++ <listitem><para>Pause boot progress bar.</para></listitem>
++ </varlistentry>
++ <varlistentry>
++ <term><command>unpause-progress</command></term>
++ <listitem><para>Unpause boot progress bar.</para></listitem>
++ </varlistentry>
++ <varlistentry>
++ <term><command>report-error</command></term>
++ <listitem><para>Tell plymouthd there were errors during boot.</para></listitem>
++ </varlistentry>
++ <varlistentry>
++ <term><command>deactivate</command></term>
++ <listitem><para>Tell plymouthd to deactivate.</para></listitem>
++ </varlistentry>
++ <varlistentry>
++ <term><command>reactivate</command></term>
++ <listitem><para>Tell plymouthd to reactivate.</para></listitem>
++ </varlistentry>
++ <varlistentry>
++ <term><command>quit <arg choice="plain">OPTION</arg></command></term>
++ <listitem><para>Tell plymouthd to quit.</para>
++<variablelist>
++<varlistentry>
++ <term><option>--retain-splash</option></term>
++ <listitem><para>Don't explicitly hide boot splash on exit</para></listitem>
++</varlistentry>
++</variablelist>
++</listitem>
++ </varlistentry>
++ </variablelist>
++
++ </refsect1>
++
++ <refsect1>
++ <title>See Also</title>
++ <para>
++ <citerefentry><refentrytitle>grub</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
++ <citerefentry><refentrytitle>plymouth</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
++ <citerefentry><refentrytitle>plymouthd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
++ <ulink url="http://www.freedesktop.org/wiki/Software/Plymouth">http://www.freedesktop.org/wiki/Software/Plymouth</ulink>
++ </para>
++ </refsect1>
++
++</refentry>
+diff --git a/docs/plymouthd.xml b/docs/plymouthd.xml
+new file mode 100644
+index 0000000..4e7e499
+--- /dev/null
++++ b/docs/plymouthd.xml
+@@ -0,0 +1,121 @@
++<?xml version='1.0'?>
++<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
++ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
++
++<refentry id="plymouthd">
++
++ <refentryinfo>
++ <title>plymouthd</title>
++ <productname>plymouth</productname>
++
++ <authorgroup>
++ <author>
++ <contrib>Developer</contrib>
++ <firstname>Kristian</firstname>
++ <surname>Høgsberg</surname>
++ </author>
++ <author>
++ <contrib>Developer</contrib>
++ <firstname>Ray</firstname>
++ <surname>Strode</surname>
++ </author>
++ </authorgroup>
++
++ </refentryinfo>
++
++ <refmeta>
++ <refentrytitle>plymouthd</refentrytitle>
++ <manvolnum>8</manvolnum>
++ <refmiscinfo class="manual">System Administration</refmiscinfo>
++ </refmeta>
++
++ <refnamediv>
++ <refname>plymouthd</refname>
++ <refpurpose>The plymouth daemon</refpurpose>
++ </refnamediv>
++
++ <refsynopsisdiv>
++ <cmdsynopsis>
++ <command>plymouthd <arg choice="opt" rep="repeat">OPTION</arg></command>
++ </cmdsynopsis>
++ </refsynopsisdiv>
++
++ <refsect1>
++ <title>Description</title>
++
++<para>
++The <command>plymouthd</command> daemon is usually run out of
++the initrd. It does the heavy lifting of the plymouth system, logging
++the session and showing the splash screen.
++</para>
++<para>
++The <command>plymouth</command> is used to send commands to plymouthd
++that control its behaviour.
++</para>
++
++ </refsect1>
++
++ <refsect1>
++ <title>Options</title>
++
++ <para>The following options are understood:</para>
++
++ <variablelist>
++ <varlistentry>
++ <term><option>--help</option></term>
++ <listitem><para>Show summary of options.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><option>--attach-to-session</option></term>
++ <listitem><para>Redirect console messages from screen to log.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><option>--no-daemon</option></term>
++ <listitem><para>Do not daemonize.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><option>--debug</option></term>
++ <listitem><para>Output debugging information.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><option>--debug-file=STRING</option></term>
++ <listitem><para>File to write debugging information to.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><option>--mode=MODE</option></term>
++ <listitem><para>Set mode to either boot or shutdown.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><option>--pid-file=STRING</option></term>
++ <listitem><para>Write the PID of the daemon to a file.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><option>--kernel-command-line=STRING</option></term>
++ <listitem><para>Fake kernel commandline to use.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><option>--tty=STRING</option></term>
++ <listitem><para>TTY to ues instead of default.</para></listitem>
++ </varlistentry>
++ </variablelist>
++ </refsect1>
++
++ <refsect1>
++ <title>See Also</title>
++ <para>
++ <citerefentry><refentrytitle>grub</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
++ <citerefentry><refentrytitle>plymouth</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
++ <citerefentry><refentrytitle>plymouth</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
++ <ulink url="http://www.freedesktop.org/wiki/Software/Plymouth">http://www.freedesktop.org/wiki/Software/Plymouth</ulink>
++ </para>
++ </refsect1>
++
++</refentry>
+diff --git a/scripts/plymouth-generate-initrd.in b/scripts/plymouth-generate-initrd.in
+index 35509a1..c44ca4c 100755
+--- a/scripts/plymouth-generate-initrd.in
++++ b/scripts/plymouth-generate-initrd.in
+@@ -13,11 +13,12 @@ PLYMOUTH_INITRD_DIR="$(mktemp --tmpdir -d plymouth-XXXXXXX)"
+ $PLYMOUTH_POPULATE_INITRD -t "$PLYMOUTH_INITRD_DIR"
+
+ if [ $? -eq 0 ]; then
++ command -v pigz &>/dev/null && gzip=pigz || gzip=gzip
+ (cd $PLYMOUTH_INITRD_DIR;
+ # FIXME: might make sense to add a flag to plymouth-populate-initrd to
+ # skip these from the start
+ rm -f lib*/{ld*,libc*,libdl*,libm*,libz*,libpthread*}
+- find | cpio -Hnewc -o | gzip -9 > $PLYMOUTH_IMAGE_FILE
++ find | cpio -Hnewc -o | $gzip -9 > $PLYMOUTH_IMAGE_FILE
+ )
+ fi
+
+diff --git a/scripts/plymouth-populate-initrd.in b/scripts/plymouth-populate-initrd.in
+index 8d1eec0..43c7f22 100755
+--- a/scripts/plymouth-populate-initrd.in
++++ b/scripts/plymouth-populate-initrd.in
+@@ -8,6 +8,7 @@
+ [ -z "$PLYMOUTH_DATADIR" ] && PLYMOUTH_DATADIR="@PLYMOUTH_DATADIR@"
+ [ -z "$PLYMOUTH_PLUGIN_PATH" ] && PLYMOUTH_PLUGIN_PATH="$(plymouth --get-splash-plugin-path)"
+ [ -z "$PLYMOUTH_LOGO_FILE" ] && PLYMOUTH_LOGO_FILE="@PLYMOUTH_LOGO_FILE@"
++[ -n "$PLYMOUTH_THEME_NAME" ] && THEME_OVERRIDE=1
+ [ -z "$PLYMOUTH_THEME_NAME" ] && PLYMOUTH_THEME_NAME=$(plymouth-set-default-theme)
+ [ -z "$PLYMOUTH_CONFDIR" ] && PLYMOUTH_CONFDIR="@PLYMOUTH_CONF_DIR@"
+ [ -z "$PLYMOUTH_POLICYDIR" ] && PLYMOUTH_POLICYDIR="@PLYMOUTH_POLICY_DIR@"
+@@ -372,8 +373,8 @@ done
+ [ -z "$INITRDDIR" ] && usage error
+
+ mkdir -p ${INITRDDIR}${PLYMOUTH_DATADIR}/plymouth/themes
+-inst ${PLYMOUTH_DAEMON_PATH} $INITRDDIR /sbin/plymouthd
+-inst ${PLYMOUTH_CLIENT_PATH} $INITRDDIR /bin/plymouth
++inst ${PLYMOUTH_DAEMON_PATH} $INITRDDIR
++inst ${PLYMOUTH_CLIENT_PATH} $INITRDDIR
+ inst ${PLYMOUTH_DATADIR}/plymouth/themes/text/text.plymouth $INITRDDIR
+ inst ${PLYMOUTH_PLUGIN_PATH}/text.so $INITRDDIR
+ inst ${PLYMOUTH_DATADIR}/plymouth/themes/details/details.plymouth $INITRDDIR
+@@ -388,6 +389,12 @@ if [ -z "$PLYMOUTH_THEME_NAME" ]; then
+ exit 1
+ fi
+
++if [ $THEME_OVERRIDE ]; then
++ conf=$INITRDDIR/${PLYMOUTH_CONFDIR}/plymouthd.conf
++ echo "modifying plymouthd.conf: Theme=$PLYMOUTH_THEME_NAME" > /dev/stderr
++ sed -i "s/^ *Theme *=.*/# theme modified by plymouth-populate-initrd\nTheme=$PLYMOUTH_THEME_NAME/" $conf
++fi
++
+ PLYMOUTH_MODULE_NAME=$(grep "ModuleName *= *" ${PLYMOUTH_DATADIR}/plymouth/themes/${PLYMOUTH_THEME_NAME}/${PLYMOUTH_THEME_NAME}.plymouth | sed 's/ModuleName *= *//')
+
+ if [ ! -f ${PLYMOUTH_PLUGIN_PATH}/${PLYMOUTH_MODULE_NAME}.so ]; then
+@@ -425,6 +432,7 @@ if [ -n "$SYSTEMD_UNIT_DIR" -a -d "$SYSTEMD_UNIT_DIR" ]; then
+ inst $SYSTEMD_UNIT_DIR/plymouth-halt.service $INITRDDIR
+
+ inst $SYSTEMD_UNIT_DIR/initrd-switch-root.target.wants/plymouth-switch-root.service $INITRDDIR
++ inst $SYSTEMD_UNIT_DIR/initrd-switch-root.target.wants/plymouth-start.service $INITRDDIR
+ inst $SYSTEMD_UNIT_DIR/sysinit.target.wants/plymouth-start.service $INITRDDIR
+ inst $SYSTEMD_UNIT_DIR/multi-user.target.wants/plymouth-quit.service $INITRDDIR
+ inst $SYSTEMD_UNIT_DIR/multi-user.target.wants/plymouth-quit-wait.service $INITRDDIR
+diff --git a/scripts/plymouth-update-initrd b/scripts/plymouth-update-initrd
+index 1403b8b..4ed5709 100755
+--- a/scripts/plymouth-update-initrd
++++ b/scripts/plymouth-update-initrd
+@@ -1,2 +1,2 @@
+ #!/bin/bash
+-mkinitrd -f /boot/initrd-$(uname -r).img $(uname -r)
++dracut -f
+diff --git a/src/Makefile.am b/src/Makefile.am
+index a9e6eb1..fc2f5da 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -1,8 +1,8 @@
+-SUBDIRS = libply libply-splash-core libply-splash-graphics . plugins client viewer tests
++SUBDIRS = libply libply-splash-core libply-splash-graphics . plugins client viewer
+ if ENABLE_UPSTART_MONITORING
+ SUBDIRS += upstart-bridge
+ endif
+-INCLUDES = -I$(top_srcdir) \
++AM_CPPFLAGS = -I$(top_srcdir) \
+ -I$(srcdir)/libply \
+ -I$(srcdir)/libply-splash-core \
+ -I$(srcdir) \
+@@ -15,6 +15,7 @@ plymouthdbindir = $(plymouthdaemondir)
+ plymouthdbin_PROGRAMS = plymouthd
+
+ plymouthd_CFLAGS = $(PLYMOUTH_CFLAGS) \
++ -rdynamic \
+ -DPLYMOUTH_PLUGIN_PATH=\"$(PLYMOUTH_PLUGIN_PATH)\" \
+ -DPLYMOUTH_THEME_PATH=\"$(PLYMOUTH_THEME_PATH)/\" \
+ -DPLYMOUTH_POLICY_DIR=\"$(PLYMOUTH_POLICY_DIR)/\" \
+diff --git a/src/client/Makefile.am b/src/client/Makefile.am
+index 9487901..83b19cc 100644
+--- a/src/client/Makefile.am
++++ b/src/client/Makefile.am
+@@ -1,6 +1,4 @@
+-SUBDIRS = . tests
+-
+-INCLUDES = -I$(top_srcdir) \
++AM_CPPFLAGS = -I$(top_srcdir) \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/src/libply \
+ -I$(srcdir)
+diff --git a/src/client/ply-boot-client.c b/src/client/ply-boot-client.c
+index 56458ce..3480676 100644
+--- a/src/client/ply-boot-client.c
++++ b/src/client/ply-boot-client.c
+@@ -869,137 +869,4 @@ ply_boot_client_attach_to_event_loop (ply_boot_client_t *client,
+
+ }
+
+-#ifdef PLY_BOOT_CLIENT_ENABLE_TEST
+-
+-#include <stdio.h>
+-
+-#include "ply-event-loop.h"
+-#include "ply-boot-client.h"
+-
+-static void
+-on_pinged (ply_event_loop_t *loop)
+-{
+- printf ("PING!\n");
+-}
+-
+-static void
+-on_ping_failed (ply_event_loop_t *loop)
+-{
+- printf ("PING FAILED! %m\n");
+- ply_event_loop_exit (loop, 1);
+-}
+-
+-static void
+-on_update (ply_event_loop_t *loop)
+-{
+- printf ("UPDATE!\n");
+-}
+-
+-static void
+-on_update_failed (ply_event_loop_t *loop)
+-{
+- printf ("UPDATE FAILED! %m\n");
+- ply_event_loop_exit (loop, 1);
+-}
+-
+-static void
+-on_newroot (ply_event_loop_t *loop)
+-{
+- printf ("NEWROOT!\n");
+-}
+-
+-static void
+-on_system_initialized (ply_event_loop_t *loop)
+-{
+- printf ("SYSTEM INITIALIZED!\n");
+-}
+-
+-static void
+-on_system_initialized_failed (ply_event_loop_t *loop)
+-{
+- printf ("SYSTEM INITIALIZATION REQUEST FAILED!\n");
+- ply_event_loop_exit (loop, 1);
+-}
+-
+-static void
+-on_quit (ply_event_loop_t *loop)
+-{
+- printf ("QUIT!\n");
+- ply_event_loop_exit (loop, 0);
+-}
+-
+-static void
+-on_quit_failed (ply_event_loop_t *loop)
+-{
+- printf ("QUIT FAILED! %m\n");
+- ply_event_loop_exit (loop, 2);
+-}
+-
+-static void
+-on_disconnect (ply_event_loop_t *loop)
+-{
+- printf ("DISCONNECT!\n");
+- ply_event_loop_exit (loop, 1);
+-}
+-
+-int
+-main (int argc,
+- char **argv)
+-{
+- ply_event_loop_t *loop;
+- ply_boot_client_t *client;
+- int exit_code;
+-
+- exit_code = 0;
+-
+- loop = ply_event_loop_new ();
+-
+- client = ply_boot_client_new ();
+-
+- if (!ply_boot_client_connect (client,
+- (ply_boot_client_disconnect_handler_t) on_disconnect,
+- loop))
+- {
+- perror ("could not start boot client");
+- return errno;
+- }
+-
+- ply_boot_client_attach_to_event_loop (client, loop);
+- ply_boot_client_ping_daemon (client,
+- (ply_boot_client_response_handler_t) on_pinged,
+- (ply_boot_client_response_handler_t) on_ping_failed,
+- loop);
+-
+- ply_boot_client_update_daemon (client,
+- "loading",
+- (ply_boot_client_response_handler_t) on_update,
+- (ply_boot_client_response_handler_t) on_update_failed,
+- loop);
+-
+- ply_boot_client_update_daemon (client,
+- "loading more",
+- (ply_boot_client_response_handler_t) on_update,
+- (ply_boot_client_response_handler_t) on_update_failed,
+- loop);
+-
+- ply_boot_client_tell_daemon_system_is_initialized (client,
+- (ply_boot_client_response_handler_t)
+- on_system_initialized,
+- (ply_boot_client_response_handler_t)
+- on_system_initialized_failed,
+- loop);
+-
+- ply_boot_client_tell_daemon_to_quit (client,
+- (ply_boot_client_response_handler_t) on_quit,
+- (ply_boot_client_response_handler_t) on_quit_failed,
+- loop);
+-
+- exit_code = ply_event_loop_run (loop);
+-
+- ply_boot_client_free (client);
+-
+- return exit_code;
+-}
+-
+-#endif /* PLY_BOOT_CLIENT_ENABLE_TEST */
+ /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */
+diff --git a/src/client/plymouth.c b/src/client/plymouth.c
+index e00208d..b22e90c 100644
+--- a/src/client/plymouth.c
++++ b/src/client/plymouth.c
+@@ -1173,7 +1173,8 @@ main (int argc,
+
+ if (get_kernel_command_line (&state))
+ {
+- if (strstr (state.kernel_command_line, "plymouth:debug") != NULL
++ if ((strstr (state.kernel_command_line, "plymouth.debug") != NULL ||
++ strstr (state.kernel_command_line, "plymouth:debug") != NULL)
+ && !ply_is_tracing ())
+ ply_toggle_tracing ();
+ }
+diff --git a/src/client/tests/Makefile.am b/src/client/tests/Makefile.am
+deleted file mode 100644
+index c6dbfdb..0000000
+--- a/src/client/tests/Makefile.am
++++ /dev/null
+@@ -1,10 +0,0 @@
+-INCLUDES = \
+- -I$(top_srcdir) \
+- -I$(srcdir)/.. \
+- -I$(srcdir)/../.. \
+- -I$(srcdir)
+-TESTS =
+-
+-noinst_PROGRAMS = $(TESTS)
+-
+-MAINTAINERCLEANFILES = Makefile.in
+diff --git a/src/libply-splash-core/Makefile.am b/src/libply-splash-core/Makefile.am
+index b289b65..d07d7f1 100644
+--- a/src/libply-splash-core/Makefile.am
++++ b/src/libply-splash-core/Makefile.am
+@@ -1,4 +1,4 @@
+-INCLUDES = -I$(top_srcdir) \
++AM_CPPFLAGS = -I$(top_srcdir) \
+ -I$(srcdir) \
+ -I$(srcdir)/../libply \
+ -I$(srcdir)/../plugins/controls
+@@ -15,33 +15,39 @@ libply_splash_coredir = $(includedir)/plymouth-1/ply-splash-core
+ libply_splash_core_HEADERS = \
+ ply-boot-splash.h \
+ ply-boot-splash-plugin.h \
++ ply-device-manager.h \
+ ply-keyboard.h \
+ ply-pixel-buffer.h \
+ ply-pixel-display.h \
+ ply-renderer.h \
+ ply-renderer-plugin.h \
++ ply-seat.h \
+ ply-terminal.h \
+ ply-text-display.h \
+- ply-text-progress-bar.h
++ ply-text-progress-bar.h \
++ ply-text-step-bar.h
+
+-libply_splash_core_la_CFLAGS = $(PLYMOUTH_CFLAGS) \
++libply_splash_core_la_CFLAGS = $(PLYMOUTH_CFLAGS) $(UDEV_CFLAGS) \
+ -DPLYMOUTH_BACKGROUND_COLOR=$(background_color) \
+ -DPLYMOUTH_BACKGROUND_END_COLOR=$(background_end_color) \
+ -DPLYMOUTH_BACKGROUND_START_COLOR=$(background_start_color) \
+ -DPLYMOUTH_PLUGIN_PATH=\"$(PLYMOUTH_PLUGIN_PATH)\"
+-libply_splash_core_la_LIBADD = $(PLYMOUTH_LIBS) ../libply/libply.la
++libply_splash_core_la_LIBADD = $(PLYMOUTH_LIBS) $(UDEV_LIBS) ../libply/libply.la
+ libply_splash_core_la_LDFLAGS = -export-symbols-regex '^[^_].*' \
+ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
+ -no-undefined
+ libply_splash_core_la_SOURCES = \
+ $(libply_splash_core_HEADERS) \
++ ply-device-manager.c \
+ ply-keyboard.c \
+ ply-pixel-display.c \
+ ply-text-display.c \
+ ply-text-progress-bar.c \
++ ply-text-step-bar.c \
+ ply-terminal.c \
+ ply-pixel-buffer.c \
+ ply-renderer.c \
++ ply-seat.c \
+ ply-boot-splash.c
+
+ MAINTAINERCLEANFILES = Makefile.in
+diff --git a/src/libply-splash-core/ply-boot-splash.c b/src/libply-splash-core/ply-boot-splash.c
+index 93d9345..160ce45 100644
+--- a/src/libply-splash-core/ply-boot-splash.c
++++ b/src/libply-splash-core/ply-boot-splash.c
+@@ -48,10 +48,6 @@
+ #define UPDATES_PER_SECOND 30
+ #endif
+
+-#define KEY_CTRL_L ('\100' ^'L')
+-#define KEY_CTRL_T ('\100' ^'T')
+-#define KEY_CTRL_V ('\100' ^'V')
+-
+ struct _ply_boot_splash
+ {
+ ply_event_loop_t *loop;
+@@ -59,11 +55,9 @@ struct _ply_boot_splash
+ const ply_boot_splash_plugin_interface_t *plugin_interface;
+ ply_boot_splash_plugin_t *plugin;
+ ply_boot_splash_mode_t mode;
+- ply_keyboard_t *keyboard;
+ ply_buffer_t *boot_buffer;
+ ply_trigger_t *idle_trigger;
+- ply_list_t *pixel_displays;
+- ply_list_t *text_displays;
++ ply_list_t *seats;
+
+ char *theme_path;
+ char *plugin_dir;
+@@ -100,18 +94,30 @@ ply_boot_splash_new (const char *theme_path,
+ splash->mode = PLY_BOOT_SPLASH_MODE_INVALID;
+
+ splash->boot_buffer = boot_buffer;
+- splash->pixel_displays = ply_list_new ();
+- splash->text_displays = ply_list_new ();
++ splash->seats = ply_list_new ();
+
+ return splash;
+ }
+
+ static void
+-refresh_displays (ply_boot_splash_t *splash)
++detach_from_seat (ply_boot_splash_t *splash,
++ ply_seat_t *seat)
+ {
+- ply_list_node_t *node;
++ ply_keyboard_t *keyboard;
++ ply_list_t *displays;
++ ply_list_node_t *node, *next_node;
+
+- node = ply_list_get_first_node (splash->pixel_displays);
++ ply_trace ("removing keyboard");
++ if (splash->plugin_interface->unset_keyboard != NULL)
++ {
++ keyboard = ply_seat_get_keyboard (seat);
++ splash->plugin_interface->unset_keyboard (splash->plugin, keyboard);
++ }
++
++ ply_trace ("removing pixel displays");
++ displays = ply_seat_get_pixel_displays (seat);
++
++ node = ply_list_get_first_node (displays);
+ while (node != NULL)
+ {
+ ply_pixel_display_t *display;
+@@ -119,184 +125,137 @@ refresh_displays (ply_boot_splash_t *splash)
+ unsigned long width, height;
+
+ display = ply_list_node_get_data (node);
+- next_node = ply_list_get_next_node (splash->pixel_displays, node);
++ next_node = ply_list_get_next_node (displays, node);
+
+ width = ply_pixel_display_get_width (display);
+ height = ply_pixel_display_get_height (display);
+
+- ply_pixel_display_draw_area (display, 0, 0, width, height);
++ ply_trace ("Removing %lux%lu pixel display", width, height);
++
++ if (splash->plugin_interface->remove_pixel_display != NULL)
++ splash->plugin_interface->remove_pixel_display (splash->plugin, display);
++
+ node = next_node;
+ }
+
+- node = ply_list_get_first_node (splash->text_displays);
++ ply_trace ("removing text displays");
++ displays = ply_seat_get_text_displays (seat);
++
++ node = ply_list_get_first_node (displays);
+ while (node != NULL)
+ {
+ ply_text_display_t *display;
+- ply_list_node_t *next_node;
+ int number_of_columns, number_of_rows;
+
+ display = ply_list_node_get_data (node);
+- next_node = ply_list_get_next_node (splash->text_displays, node);
++ next_node = ply_list_get_next_node (displays, node);
+
+ number_of_columns = ply_text_display_get_number_of_columns (display);
+ number_of_rows = ply_text_display_get_number_of_rows (display);
+
+- ply_text_display_draw_area (display, 0, 0,
+- number_of_columns,
+- number_of_rows);
++ 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);
++
+ node = next_node;
+ }
+ }
+
+-static ply_terminal_t *
+-find_local_console_terminal (ply_boot_splash_t *splash)
++static void
++attach_to_seat (ply_boot_splash_t *splash,
++ ply_seat_t *seat)
+ {
+- ply_list_node_t *node;
+- node = ply_list_get_first_node (splash->text_displays);
++ ply_keyboard_t *keyboard;
++ ply_list_t *displays;
++ ply_list_node_t *node, *next_node;
+
+- while (node != NULL)
++ if (splash->plugin_interface->set_keyboard != NULL)
+ {
+- ply_text_display_t *display;
+- ply_terminal_t *terminal;
+- ply_list_node_t *next_node;
++ keyboard = ply_seat_get_keyboard (seat);
++ splash->plugin_interface->set_keyboard (splash->plugin, keyboard);
++ }
+
+- display = ply_list_node_get_data (node);
+- next_node = ply_list_get_next_node (splash->text_displays, node);
++ if (splash->plugin_interface->add_pixel_display != NULL)
++ {
++ displays = ply_seat_get_pixel_displays (seat);
+
+- terminal = ply_text_display_get_terminal (display);
++ 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;
+
+- if (terminal != NULL && ply_terminal_is_vt (terminal))
+- return terminal;
++ display = ply_list_node_get_data (node);
++ next_node = ply_list_get_next_node (displays, node);
+
+- node = next_node;
+- }
++ width = ply_pixel_display_get_width (display);
++ height = ply_pixel_display_get_height (display);
+
+- return NULL;
+-}
++ ply_trace ("Adding %lux%lu pixel display", width, height);
+
+-static void
+-on_keyboard_input (ply_boot_splash_t *splash,
+- const char *keyboard_input,
+- size_t character_size)
+-{
+- wchar_t key;
++ splash->plugin_interface->add_pixel_display (splash->plugin, display);
+
+- if ((ssize_t) mbrtowc (&key, keyboard_input, character_size, NULL) > 0)
+- {
+- switch (key)
+- {
+- case KEY_CTRL_L:
+- refresh_displays (splash);
+- return;
+-
+- case KEY_CTRL_T:
+- ply_trace ("toggle text mode!");
+- splash->should_force_text_mode = !splash->should_force_text_mode;
+-
+- if (ply_list_get_length (splash->pixel_displays) >= 1)
+- {
+- ply_terminal_t *terminal;
+-
+- terminal = find_local_console_terminal (splash);
+-
+- if (terminal != NULL)
+- {
+- if (splash->should_force_text_mode)
+- {
+- ply_terminal_set_mode (terminal, PLY_TERMINAL_MODE_TEXT);
+- ply_terminal_ignore_mode_changes (terminal, true);
+- }
+- else
+- ply_terminal_ignore_mode_changes (terminal, false);
+- }
+- }
+- ply_trace ("text mode toggled!");
+- return;
+-
+- case KEY_CTRL_V:
+- ply_trace ("toggle verbose mode!");
+- ply_toggle_tracing ();
+- ply_trace ("verbose mode toggled!");
+- return;
++ node = next_node;
+ }
+ }
+-}
+
+-void
+-ply_boot_splash_set_keyboard (ply_boot_splash_t *splash,
+- ply_keyboard_t *keyboard)
+-{
+- splash->keyboard = keyboard;
++ if (splash->plugin_interface->add_text_display != NULL)
++ {
++ displays = ply_seat_get_text_displays (seat);
+
+- ply_keyboard_add_input_handler (keyboard,
+- (ply_keyboard_input_handler_t)
+- on_keyboard_input, splash);
++ 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;
+
+- if (splash->plugin_interface->set_keyboard == NULL)
+- return;
++ display = ply_list_node_get_data (node);
++ next_node = ply_list_get_next_node (displays, node);
+
+- splash->plugin_interface->set_keyboard (splash->plugin, keyboard);
+-}
++ number_of_columns = ply_text_display_get_number_of_columns (display);
++ number_of_rows = ply_text_display_get_number_of_rows (display);
+
+-void
+-ply_boot_splash_unset_keyboard (ply_boot_splash_t *splash)
+-{
+- ply_keyboard_remove_input_handler (splash->keyboard,
+- (ply_keyboard_input_handler_t)
+- on_keyboard_input);
++ ply_trace ("Adding %dx%d text display", number_of_columns, number_of_rows);
+
+- if (splash->plugin_interface->set_keyboard == NULL)
+- return;
++ splash->plugin_interface->add_text_display (splash->plugin, display);
+
+- splash->plugin_interface->unset_keyboard (splash->plugin, splash->keyboard);
++ node = next_node;
++ }
++ }
+ }
+
+ void
+-ply_boot_splash_add_pixel_display (ply_boot_splash_t *splash,
+- ply_pixel_display_t *display)
++ply_boot_splash_attach_to_seat (ply_boot_splash_t *splash,
++ ply_seat_t *seat)
+ {
+- ply_list_append_data (splash->pixel_displays, display);
+-
+- if (splash->plugin_interface->add_pixel_display == NULL)
+- return;
+-
+- splash->plugin_interface->add_pixel_display (splash->plugin, display);
+-}
++ ply_list_node_t *node;
+
+-void
+-ply_boot_splash_remove_pixel_display (ply_boot_splash_t *splash,
+- ply_pixel_display_t *display)
+-{
+- ply_list_remove_data (splash->pixel_displays, display);
++ node = ply_list_find_node (splash->seats, seat);
+
+- if (splash->plugin_interface->remove_pixel_display == NULL)
++ if (node != NULL)
+ return;
+
+- splash->plugin_interface->remove_pixel_display (splash->plugin, display);
++ ply_list_append_data (splash->seats, seat);
++ attach_to_seat (splash, seat);
+ }
+
+ void
+-ply_boot_splash_add_text_display (ply_boot_splash_t *splash,
+- ply_text_display_t *display)
++ply_boot_splash_detach_from_seat (ply_boot_splash_t *splash,
++ ply_seat_t *seat)
+ {
+- ply_list_append_data (splash->text_displays, display);
++ ply_list_node_t *node;
+
+- if (splash->plugin_interface->add_text_display == NULL)
+- return;
++ node = ply_list_find_node (splash->seats, seat);
+
+- splash->plugin_interface->add_text_display (splash->plugin, display);
+-}
+-
+-void
+-ply_boot_splash_remove_text_display (ply_boot_splash_t *splash,
+- ply_text_display_t *display)
+-{
+- ply_list_remove_data (splash->text_displays, display);
+-
+- if (splash->plugin_interface->remove_pixel_display == NULL)
++ if (node == NULL)
+ return;
+
+- splash->plugin_interface->remove_text_display (splash->plugin, display);
++ ply_list_remove_data (splash->seats, seat);
++ detach_from_seat (splash, seat);
+ }
+
+ bool
+@@ -432,56 +391,24 @@ ply_boot_splash_unload (ply_boot_splash_t *splash)
+ }
+
+ static void
+-remove_displays (ply_boot_splash_t *splash)
++detach_from_seats (ply_boot_splash_t *splash)
+ {
+- ply_list_node_t *node, *next_node;
++ ply_list_node_t *node;
+
+- ply_trace ("removing pixel displays");
++ ply_trace ("detaching from seats");
+
+- node = ply_list_get_first_node (splash->pixel_displays);
++ node = ply_list_get_first_node (splash->seats);
+ while (node != NULL)
+ {
+- ply_pixel_display_t *display;
++ ply_seat_t *seat;
+ ply_list_node_t *next_node;
+- unsigned long width, height;
+
+- display = ply_list_node_get_data (node);
+- next_node = ply_list_get_next_node (splash->pixel_displays, node);
++ seat = ply_list_node_get_data (node);
++ next_node = ply_list_get_next_node (splash->seats, node);
+
+- width = ply_pixel_display_get_width (display);
+- height = ply_pixel_display_get_height (display);
++ detach_from_seat (splash, seat);
+
+- ply_trace ("Removing %lux%lu pixel display", width, height);
+-
+- if (splash->plugin_interface->remove_pixel_display != NULL)
+- splash->plugin_interface->remove_pixel_display (splash->plugin, display);
+-
+- ply_trace ("Removing node");
+- ply_list_remove_node (splash->pixel_displays, node);
+-
+- node = next_node;
+- }
+-
+- ply_trace ("removing text displays");
+- node = ply_list_get_first_node (splash->text_displays);
+- while (node != NULL)
+- {
+- ply_text_display_t *display;
+- int number_of_columns, number_of_rows;
+-
+- display = ply_list_node_get_data (node);
+- next_node = ply_list_get_next_node (splash->text_displays, node);
+-
+- number_of_columns = ply_text_display_get_number_of_columns (display);
+- number_of_rows = ply_text_display_get_number_of_rows (display);
+-
+- ply_trace ("Removing %dx%d text display", number_of_columns, number_of_rows);
+-
+- if (splash->plugin_interface->remove_text_display != NULL)
+- splash->plugin_interface->remove_text_display (splash->plugin, display);
+-
+- ply_trace ("Removing node");
+- ply_list_remove_node (splash->text_displays, node);
++ ply_list_remove_node (splash->seats, node);
+
+ node = next_node;
+ }
+@@ -508,9 +435,8 @@ ply_boot_splash_free (ply_boot_splash_t *splash)
+ splash);
+ }
+
+- remove_displays (splash);
+- ply_list_free (splash->pixel_displays);
+- ply_list_free (splash->text_displays);
++ detach_from_seats (splash);
++ ply_list_free (splash->seats);
+
+ if (splash->module_handle != NULL)
+ ply_boot_splash_unload (splash);
+@@ -676,16 +602,6 @@ ply_boot_splash_hide (ply_boot_splash_t *splash)
+ splash->plugin_interface->hide_splash_screen (splash->plugin,
+ splash->loop);
+
+- if (ply_list_get_length (splash->pixel_displays) >= 1)
+- {
+- ply_terminal_t *terminal;
+-
+- terminal = find_local_console_terminal (splash);
+-
+- if (terminal != NULL)
+- ply_terminal_set_mode (terminal, PLY_TERMINAL_MODE_TEXT);
+- }
+-
+ splash->mode = PLY_BOOT_SPLASH_MODE_INVALID;
+
+ if (splash->loop != NULL)
+@@ -820,148 +736,4 @@ ply_boot_splash_become_idle (ply_boot_splash_t *splash,
+ splash->plugin_interface->become_idle (splash->plugin, splash->idle_trigger);
+ }
+
+-#ifdef PLY_BOOT_SPLASH_ENABLE_TEST
+-
+-#include <stdio.h>
+-
+-#include "ply-event-loop.h"
+-#include "ply-boot-splash.h"
+-
+-typedef struct test_state test_state_t;
+-struct test_state {
+- ply_event_loop_t *loop;
+- ply_boot_splash_t *splash;
+- ply_buffer_t *buffer;
+-};
+-
+-static void
+-on_timeout (ply_boot_splash_t *splash)
+-{
+- ply_boot_splash_update_status (splash, "foo");
+- ply_event_loop_watch_for_timeout (splash->loop,
+- 5.0,
+- (ply_event_loop_timeout_handler_t)
+- on_timeout,
+- splash);
+-}
+-
+-static void
+-on_quit (test_state_t *state)
+-{
+- ply_boot_splash_hide (state->splash);
+- ply_event_loop_exit (state->loop, 0);
+-}
+-
+-static void
+-add_displays_to_splash_from_renderer (test_state_t *state,
+- ply_renderer_t *renderer)
+-{
+- ply_list_t *heads;
+- ply_list_node_t *node;
+-
+- heads = ply_renderer_get_heads (renderer);
+-
+- node = ply_list_get_first_node (heads);
+- while (node != NULL)
+- {
+- ply_list_node_t *next_node;
+- ply_renderer_head_t *head;
+- ply_pixel_display_t *display;
+-
+- head = ply_list_node_get_data (node);
+- next_node = ply_list_get_next_node (heads, node);
+-
+- display = ply_pixel_display_new (renderer, head);
+-
+- ply_boot_splash_add_pixel_display (state->splash, display);
+-
+- node = next_node;
+- }
+-}
+-
+-int
+-main (int argc,
+- char **argv)
+-{
+- int exit_code;
+- test_state_t state;
+- char *tty_name;
+- const char *theme_path;
+- ply_text_display_t *text_display;
+- ply_renderer_t *renderer;
+- ply_terminal_t *terminal;
+- ply_keyboard_t *keyboard;
+-
+- exit_code = 0;
+-
+- state.loop = ply_event_loop_new ();
+-
+- if (argc > 1)
+- theme_path = argv[1];
+- else
+- theme_path = PLYMOUTH_THEME_PATH "/fade-in/fade-in.plymouth";
+-
+- if (argc > 2)
+- asprintf(&tty_name, "tty%s", argv[2]);
+- else
+- tty_name = strdup("tty0");
+-
+- terminal = ply_terminal_new (tty_name);
+-
+- if (!ply_terminal_open (terminal))
+- {
+- perror ("could not open tty");
+- return errno;
+- }
+-
+- renderer = ply_renderer_new (NULL, terminal);
+- free(tty_name);
+-
+- if (!ply_renderer_open (renderer))
+- {
+- perror ("could not open renderer /dev/fb");
+- ply_renderer_free (renderer);
+- return errno;
+- }
+-
+- keyboard = ply_keyboard_new_for_renderer (renderer);
+- ply_keyboard_add_escape_handler (keyboard,
+- (ply_keyboard_escape_handler_t) on_quit, &state);
+-
+- state.buffer = ply_buffer_new ();
+- state.splash = ply_boot_splash_new (theme_path, PLYMOUTH_PLUGIN_PATH, state.buffer);
+-
+- if (!ply_boot_splash_load (state.splash))
+- {
+- perror ("could not load splash screen");
+- return errno;
+- }
+-
+- ply_boot_splash_set_keyboard (state.splash, keyboard);
+- add_displays_to_splash_from_renderer (&state, renderer);
+-
+- text_display = ply_text_display_new (terminal);
+- ply_boot_splash_add_text_display (state.splash, text_display);
+-
+- ply_boot_splash_attach_to_event_loop (state.splash, state.loop);
+-
+- if (!ply_boot_splash_show (state.splash, PLY_BOOT_SPLASH_MODE_BOOT_UP))
+- {
+- perror ("could not show splash screen");
+- return errno;
+- }
+-
+- ply_event_loop_watch_for_timeout (state.loop,
+- 1.0,
+- (ply_event_loop_timeout_handler_t)
+- on_timeout,
+- state.splash);
+- exit_code = ply_event_loop_run (state.loop);
+- ply_boot_splash_free (state.splash);
+- ply_buffer_free (state.buffer);
+-
+- return exit_code;
+-}
+-
+-#endif /* PLY_BOOT_SPLASH_ENABLE_TEST */
+ /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */
+diff --git a/src/libply-splash-core/ply-boot-splash.h b/src/libply-splash-core/ply-boot-splash.h
+index a79e939..335039b 100644
+--- a/src/libply-splash-core/ply-boot-splash.h
++++ b/src/libply-splash-core/ply-boot-splash.h
+@@ -33,10 +33,12 @@
+ #include "ply-pixel-display.h"
+ #include "ply-text-display.h"
+ #include "ply-progress.h"
++#include "ply-seat.h"
+
+ #include "ply-boot-splash-plugin.h"
+
+ typedef struct _ply_boot_splash ply_boot_splash_t;
++typedef struct _ply_seat ply_seat_t;
+
+ typedef void (* ply_boot_splash_on_idle_handler_t) (void *user_data);
+
+@@ -48,17 +50,10 @@ ply_boot_splash_t *ply_boot_splash_new (const char * theme_path,
+ bool ply_boot_splash_load (ply_boot_splash_t *splash);
+ bool ply_boot_splash_load_built_in (ply_boot_splash_t *splash);
+ void ply_boot_splash_unload (ply_boot_splash_t *splash);
+-void ply_boot_splash_set_keyboard (ply_boot_splash_t *splash,
+- ply_keyboard_t *keyboard);
+-void ply_boot_splash_unset_keyboard (ply_boot_splash_t *splash);
+-void ply_boot_splash_add_pixel_display (ply_boot_splash_t *splash,
+- ply_pixel_display_t *display);
+-void ply_boot_splash_remove_pixel_display (ply_boot_splash_t *splash,
+- ply_pixel_display_t *display);
+-void ply_boot_splash_add_text_display (ply_boot_splash_t *splash,
+- ply_text_display_t *display);
+-void ply_boot_splash_remove_text_display (ply_boot_splash_t *splash,
+- ply_text_display_t *display);
++void ply_boot_splash_attach_to_seat (ply_boot_splash_t *splash,
++ ply_seat_t *seat);
++void ply_boot_splash_detach_from_seat (ply_boot_splash_t *splash,
++ ply_seat_t *seat);
+ void ply_boot_splash_free (ply_boot_splash_t *splash);
+ bool ply_boot_splash_show (ply_boot_splash_t *splash,
+ ply_boot_splash_mode_t mode);
+diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c
+new file mode 100644
+index 0000000..dbc203d
+--- /dev/null
++++ b/src/libply-splash-core/ply-device-manager.c
+@@ -0,0 +1,935 @@
++/* ply-device-manager.c - device manager
++ *
++ * Copyright (C) 2013 Red Hat, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
++ * 02111-1307, USA.
++ */
++#include "config.h"
++#include "ply-device-manager.h"
++
++#include <assert.h>
++#include <fcntl.h>
++#include <stdbool.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++#include <sys/inotify.h>
++#include <sys/stat.h>
++#include <sys/types.h>
++
++#include <libudev.h>
++
++#include "ply-logger.h"
++#include "ply-event-loop.h"
++#include "ply-hashtable.h"
++#include "ply-list.h"
++#include "ply-utils.h"
++
++#define SUBSYSTEM_DRM "drm"
++#define SUBSYSTEM_FRAME_BUFFER "graphics"
++
++static void create_seat_for_terminal_and_renderer_type (ply_device_manager_t *manager,
++ const char *device_path,
++ ply_terminal_t *terminal,
++ ply_renderer_type_t renderer_type);
++struct _ply_device_manager
++{
++ ply_device_manager_flags_t flags;
++ ply_event_loop_t *loop;
++ ply_hashtable_t *terminals;
++ ply_terminal_t *local_console_terminal;
++ ply_seat_t *local_console_seat;
++ ply_list_t *seats;
++ struct udev *udev_context;
++ struct udev_queue *udev_queue;
++ int udev_queue_fd;
++ ply_fd_watch_t *udev_queue_fd_watch;
++ struct udev_monitor *udev_monitor;
++
++ ply_seat_added_handler_t seat_added_handler;
++ ply_seat_removed_handler_t seat_removed_handler;
++ void *seat_event_handler_data;
++};
++
++static void
++detach_from_event_loop (ply_device_manager_t *manager)
++{
++ assert (manager != NULL);
++
++ manager->loop = NULL;
++}
++
++static void
++attach_to_event_loop (ply_device_manager_t *manager,
++ ply_event_loop_t *loop)
++{
++ assert (manager != NULL);
++ assert (loop != NULL);
++ assert (manager->loop == NULL);
++
++ manager->loop = loop;
++
++ ply_event_loop_watch_for_exit (loop, (ply_event_loop_exit_handler_t)
++ detach_from_event_loop,
++ manager);
++}
++
++static bool
++device_is_for_local_console (ply_device_manager_t *manager,
++ struct udev_device *device)
++{
++ const char *device_path;
++ struct udev_device *bus_device;
++ char *bus_device_path;
++ const char *boot_vga;
++ bool for_local_console;
++
++ /* Look at the associated bus device to see if this card is the
++ * card the kernel is using for its console. */
++ device_path = udev_device_get_syspath (device);
++ asprintf (&bus_device_path, "%s/device", device_path);
++ bus_device = udev_device_new_from_syspath (manager->udev_context, bus_device_path);
++
++ boot_vga = udev_device_get_sysattr_value (bus_device, "boot_vga");
++ free (bus_device_path);
++
++ if (boot_vga != NULL && strcmp (boot_vga, "1") == 0)
++ for_local_console = true;
++ else
++ for_local_console = false;
++
++ return for_local_console;
++}
++
++static bool
++fb_device_has_drm_device (ply_device_manager_t *manager,
++ struct udev_device *fb_device)
++{
++ struct udev_enumerate *card_matches;
++ struct udev_list_entry *card_entry;
++ const char *id_path;
++ bool has_drm_device = false;
++
++ /* We want to see if the framebuffer is associated with a DRM-capable
++ * graphics card, if it is, we'll use the DRM device */
++ card_matches = udev_enumerate_new (manager->udev_context);
++ udev_enumerate_add_match_is_initialized(card_matches);
++ udev_enumerate_add_match_parent (card_matches, udev_device_get_parent (fb_device));
++ udev_enumerate_add_match_subsystem (card_matches, "drm");
++ id_path = udev_device_get_property_value (fb_device, "ID_PATH");
++ udev_enumerate_add_match_property (card_matches, "ID_PATH", id_path);
++
++ ply_trace ("trying to find associated drm node for fb device (path: %s)", id_path);
++
++ udev_enumerate_scan_devices (card_matches);
++
++ /* there should only ever be at most one match so we don't iterate through
++ * the list, but just look at the first entry */
++ card_entry = udev_enumerate_get_list_entry (card_matches);
++
++ if (card_entry != NULL)
++ {
++ struct udev_device *card_device = NULL;
++ const char *card_node;
++ const char *card_path;
++
++ card_path = udev_list_entry_get_name (card_entry);
++ card_device = udev_device_new_from_syspath (manager->udev_context, card_path);
++ card_node = udev_device_get_devnode (card_device);
++ if (card_node != NULL)
++ has_drm_device = true;
++ else
++ ply_trace ("no card node!");
++
++ udev_device_unref (card_device);
++ }
++ else
++ {
++ ply_trace ("no card entry!");
++ }
++
++ udev_enumerate_unref (card_matches);
++ return has_drm_device;
++}
++
++static void
++create_seat_for_udev_device (ply_device_manager_t *manager,
++ struct udev_device *device)
++{
++ bool for_local_console;
++ const char *device_path;
++ ply_terminal_t *terminal = NULL;
++
++ for_local_console = device_is_for_local_console (manager, device);
++
++ ply_trace ("device is for local console: %s", for_local_console? "yes" : "no");
++
++ if (for_local_console)
++ terminal = manager->local_console_terminal;
++
++ device_path = udev_device_get_devnode (device);
++
++ if (device_path != NULL)
++ {
++ const char *subsystem;
++ ply_renderer_type_t renderer_type = PLY_RENDERER_TYPE_NONE;
++
++ subsystem = udev_device_get_subsystem (device);
++ ply_trace ("device subsystem is %s", subsystem);
++
++ if (subsystem != NULL && strcmp (subsystem, SUBSYSTEM_DRM) == 0)
++ {
++ ply_trace ("found DRM device %s", device_path);
++ renderer_type = PLY_RENDERER_TYPE_DRM;
++ }
++ else if (strcmp (subsystem, SUBSYSTEM_FRAME_BUFFER) == 0)
++ {
++ ply_trace ("found frame buffer device %s", device_path);
++ if (!fb_device_has_drm_device (manager, device))
++ {
++ renderer_type = PLY_RENDERER_TYPE_FRAME_BUFFER;
++ }
++ else
++ {
++ ply_trace ("ignoring, since there's a DRM device associated with it");
++ }
++ }
++
++ if (renderer_type != PLY_RENDERER_TYPE_NONE)
++ create_seat_for_terminal_and_renderer_type (manager,
++ device_path,
++ terminal,
++ renderer_type);
++ }
++}
++
++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)
++{
++ const char *device_path;
++
++ device_path = udev_device_get_devnode (device);
++
++ if (device_path != NULL)
++ free_seat_from_device_path (manager, device_path);
++}
++
++static bool
++create_seats_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",
++ strcmp (subsystem, SUBSYSTEM_FRAME_BUFFER) == 0?
++ "frame buffer":
++ subsystem);
++
++ matches = udev_enumerate_new (manager->udev_context);
++ udev_enumerate_add_match_subsystem (matches, subsystem);
++ udev_enumerate_scan_devices (matches);
++
++ udev_list_entry_foreach (entry, udev_enumerate_get_list_entry (matches))
++ {
++ struct udev_device *device = NULL;
++ const char *path;
++
++ path = udev_list_entry_get_name (entry);
++
++ if (path == NULL)
++ {
++ ply_trace ("path was null!");
++ continue;
++ }
++
++ ply_trace ("found device %s", path);
++
++ device = udev_device_new_from_syspath (manager->udev_context, path);
++
++ /* if device isn't fully initialized, we'll get an add event later
++ */
++ if (udev_device_get_is_initialized (device))
++ {
++ ply_trace ("device is initialized");
++
++ /* We only care about devices assigned to a (any) seat. Floating
++ * devices should be ignored.
++ */
++ if (udev_device_has_tag (device, "seat"))
++ {
++ const char *node;
++ node = udev_device_get_devnode (device);
++ if (node != NULL)
++ {
++ ply_trace ("found node %s", node);
++ found_device = true;
++ create_seat_for_udev_device (manager, device);
++ }
++ }
++ else
++ {
++ ply_trace ("device doesn't have a seat tag");
++ }
++ }
++ else
++ {
++ ply_trace ("it's not initialized");
++ }
++
++ udev_device_unref (device);
++ }
++
++ udev_enumerate_unref (matches);
++
++ return found_device;
++}
++
++static void
++on_udev_event (ply_device_manager_t *manager)
++{
++ struct udev_device *device;
++ const char *action;
++
++ device = udev_monitor_receive_device (manager->udev_monitor);
++ if (device == NULL)
++ return;
++
++ action = udev_device_get_action (device);
++
++ ply_trace ("got %s event for device %s", action, udev_device_get_sysname (device));
++
++ if (action == NULL)
++ return;
++
++ if (strcmp (action, "add") == 0)
++ {
++ const char *subsystem;
++ bool coldplug_complete = manager->udev_queue_fd_watch == NULL;
++
++ subsystem = udev_device_get_subsystem (device);
++
++ if (strcmp (subsystem, SUBSYSTEM_DRM) == 0 ||
++ coldplug_complete)
++ {
++ create_seat_for_udev_device (manager, device);
++ }
++ else
++ {
++ ply_trace ("ignoring since we only handle subsystem %s devices after coldplug completes", subsystem);
++ }
++ }
++ else if (strcmp (action, "remove") == 0)
++ {
++ free_seat_for_udev_device (manager, device);
++ }
++
++ udev_device_unref (device);
++}
++
++static void
++watch_for_udev_events (ply_device_manager_t *manager)
++{
++ int fd;
++ assert (manager != NULL);
++ assert (manager->udev_monitor == NULL);
++
++ ply_trace ("watching for udev graphics device add and remove events");
++
++ manager->udev_monitor = udev_monitor_new_from_netlink (manager->udev_context, "udev");
++
++ udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, SUBSYSTEM_DRM, NULL);
++ udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, SUBSYSTEM_FRAME_BUFFER, NULL);
++ udev_monitor_filter_add_match_tag (manager->udev_monitor, "seat");
++ udev_monitor_enable_receiving (manager->udev_monitor);
++
++ fd = udev_monitor_get_fd (manager->udev_monitor);
++ ply_event_loop_watch_fd (manager->loop,
++ fd,
++ PLY_EVENT_LOOP_FD_STATUS_HAS_DATA,
++ (ply_event_handler_t)
++ on_udev_event,
++ NULL,
++ manager);
++}
++
++static void
++free_seats (ply_device_manager_t *manager)
++{
++ ply_list_node_t *node;
++
++ ply_trace ("removing seats");
++ node = ply_list_get_first_node (manager->seats);
++ while (node != NULL)
++ {
++ ply_seat_t *seat;
++ ply_list_node_t *next_node;
++
++ seat = ply_list_node_get_data (node);
++ next_node = ply_list_get_next_node (manager->seats, node);
++
++ if (manager->seat_removed_handler != NULL)
++ manager->seat_removed_handler (manager->seat_event_handler_data, seat);
++
++ ply_seat_free (seat);
++ ply_list_remove_node (manager->seats, node);
++
++ node = next_node;
++ }
++}
++
++static void
++free_terminal (char *device,
++ ply_terminal_t *terminal,
++ ply_device_manager_t *manager)
++{
++ ply_hashtable_remove (manager->terminals, device);
++
++ ply_terminal_close (terminal);
++ ply_terminal_free (terminal);
++}
++
++static void
++free_terminals (ply_device_manager_t *manager)
++{
++ ply_hashtable_foreach (manager->terminals,
++ (ply_hashtable_foreach_func_t *)
++ free_terminal,
++ manager);
++}
++
++static ply_terminal_t *
++get_terminal (ply_device_manager_t *manager,
++ const char *device_name)
++{
++ char *full_name = NULL;
++ ply_terminal_t *terminal;
++
++ if (strncmp (device_name, "/dev/", strlen ("/dev/")) == 0)
++ full_name = strdup (device_name);
++ else
++ asprintf (&full_name, "/dev/%s", device_name);
++
++ if (strcmp (full_name, "/dev/tty0") == 0 ||
++ strcmp (full_name, "/dev/tty") == 0 ||
++ strcmp (full_name, ply_terminal_get_name (manager->local_console_terminal)) == 0)
++ {
++ terminal = manager->local_console_terminal;
++ goto done;
++ }
++
++ terminal = ply_hashtable_lookup (manager->terminals, full_name);
++
++ if (terminal == NULL)
++ {
++ terminal = ply_terminal_new (full_name);
++
++ ply_hashtable_insert (manager->terminals,
++ (void *) ply_terminal_get_name (terminal),
++ terminal);
++ }
++
++done:
++ free (full_name);
++ return terminal;
++}
++
++ply_device_manager_t *
++ply_device_manager_new (const char *default_tty,
++ ply_device_manager_flags_t flags)
++{
++ ply_device_manager_t *manager;
++
++ manager = calloc (1, sizeof (ply_device_manager_t));
++ manager->loop = NULL;
++ manager->terminals = ply_hashtable_new (ply_hashtable_string_hash, ply_hashtable_string_compare);
++ manager->local_console_terminal = ply_terminal_new (default_tty);
++ ply_hashtable_insert (manager->terminals,
++ (void *) ply_terminal_get_name (manager->local_console_terminal),
++ manager->local_console_terminal);
++ manager->seats = ply_list_new ();
++ manager->flags = flags;
++
++ if (!(flags & PLY_DEVICE_MANAGER_FLAGS_IGNORE_UDEV))
++ manager->udev_context = udev_new ();
++
++ attach_to_event_loop (manager, ply_event_loop_get_default ());
++
++ return manager;
++}
++
++void
++ply_device_manager_free (ply_device_manager_t *manager)
++{
++ ply_trace ("freeing device manager");
++
++ if (manager == NULL)
++ return;
++
++ ply_event_loop_stop_watching_for_exit (manager->loop,
++ (ply_event_loop_exit_handler_t)
++ detach_from_event_loop,
++ manager);
++ free_seats (manager);
++ ply_list_free (manager->seats);
++
++ free_terminals (manager);
++ ply_hashtable_free (manager->terminals);
++
++ if (manager->udev_monitor != NULL)
++ udev_monitor_unref (manager->udev_monitor);
++
++ if (manager->udev_context != NULL)
++ udev_unref (manager->udev_context);
++
++ free (manager);
++}
++
++static bool
++add_consoles_from_file (ply_device_manager_t *manager,
++ const char *path)
++{
++ int fd;
++ char contents[512] = "";
++ ssize_t contents_length;
++ bool has_serial_consoles;
++ const char *remaining_file_contents;
++
++ ply_trace ("opening %s", path);
++ fd = open (path, O_RDONLY);
++
++ if (fd < 0)
++ {
++ ply_trace ("couldn't open it: %m");
++ return false;
++ }
++
++ ply_trace ("reading file");
++ contents_length = read (fd, contents, sizeof (contents) - 1);
++
++ if (contents_length <= 0)
++ {
++ ply_trace ("couldn't read it: %m");
++ close (fd);
++ return false;
++ }
++ close (fd);
++
++ remaining_file_contents = contents;
++ has_serial_consoles = false;
++
++ while (remaining_file_contents < contents + contents_length)
++ {
++ char *console;
++ size_t console_length;
++ const char *console_device;
++ ply_terminal_t *terminal;
++
++ /* Advance past any leading whitespace */
++ remaining_file_contents += strspn (remaining_file_contents, " \n\t\v");
++
++ if (*remaining_file_contents == '\0')
++ {
++ /* There's nothing left after the whitespace, we're done */
++ break;
++ }
++
++ /* Find trailing whitespace and NUL terminate. If strcspn
++ * doesn't find whitespace, it gives us the length of the string
++ * until the next NUL byte, which we'll just overwrite with
++ * another NUL byte anyway. */
++ console_length = strcspn (remaining_file_contents, " \n\t\v");
++ console = strndup (remaining_file_contents, console_length);
++
++ terminal = get_terminal (manager, console);
++ console_device = ply_terminal_get_name (terminal);
++
++ free (console);
++
++ ply_trace ("console %s found!", console_device);
++
++ if (terminal != manager->local_console_terminal)
++ has_serial_consoles = true;
++
++ /* Move past the parsed console string, and the whitespace we
++ * may have found above. If we found a NUL above and not whitespace,
++ * then we're going to jump past the end of the buffer and the loop
++ * will terminate
++ */
++ remaining_file_contents += console_length + 1;
++ }
++
++ return has_serial_consoles;
++}
++
++static void
++create_seat_for_terminal_and_renderer_type (ply_device_manager_t *manager,
++ const char *device_path,
++ ply_terminal_t *terminal,
++ ply_renderer_type_t renderer_type)
++{
++ ply_seat_t *seat;
++ bool is_local_terminal = false;
++
++ if (terminal != NULL && manager->local_console_terminal == terminal)
++ is_local_terminal = true;
++
++ if (is_local_terminal && manager->local_console_seat != NULL)
++ {
++ ply_trace ("trying to create seat for local console when one already exists");
++ return;
++ }
++
++ ply_trace ("creating seat for %s (renderer type: %u) (terminal: %s)",
++ device_path? : "", renderer_type, terminal? ply_terminal_get_name (terminal): "none");
++ seat = ply_seat_new (terminal);
++
++ if (!ply_seat_open (seat, renderer_type, device_path))
++ {
++ ply_trace ("could not create seat");
++ ply_seat_free (seat);
++ return;
++ }
++
++ ply_list_append_data (manager->seats, seat);
++
++ if (is_local_terminal)
++ manager->local_console_seat = seat;
++
++ if (manager->seat_added_handler != NULL)
++ manager->seat_added_handler (manager->seat_event_handler_data, seat);
++}
++
++static void
++create_seat_for_terminal (const char *device_path,
++ ply_terminal_t *terminal,
++ ply_device_manager_t *manager)
++{
++ create_seat_for_terminal_and_renderer_type (manager,
++ device_path,
++ terminal,
++ PLY_RENDERER_TYPE_NONE);
++}
++static bool
++create_seats_from_terminals (ply_device_manager_t *manager)
++{
++ bool has_serial_consoles;
++
++ ply_trace ("checking for consoles");
++
++ if (manager->flags & PLY_DEVICE_MANAGER_FLAGS_IGNORE_SERIAL_CONSOLES)
++ {
++ has_serial_consoles = false;
++ ply_trace ("ignoring all consoles but default console because explicitly told to.");
++ }
++ else
++ {
++ has_serial_consoles = add_consoles_from_file (manager, "/sys/class/tty/console/active");
++ }
++
++ if (has_serial_consoles)
++ {
++ ply_trace ("serial consoles detected, managing them with details forced");
++ ply_hashtable_foreach (manager->terminals,
++ (ply_hashtable_foreach_func_t *)
++ create_seat_for_terminal,
++ manager);
++ return true;
++ }
++
++ return false;
++}
++
++static void
++create_seats_from_udev (ply_device_manager_t *manager)
++{
++ bool found_drm_device, found_fb_device;
++
++ ply_trace ("Looking for devices from udev");
++
++ found_drm_device = create_seats_for_subsystem (manager, SUBSYSTEM_DRM);
++ found_fb_device = create_seats_for_subsystem (manager, SUBSYSTEM_FRAME_BUFFER);
++
++ if (found_drm_device || found_fb_device)
++ return;
++
++ ply_trace ("Creating non-graphical seat, since there's no suitable graphics hardware");
++ create_seat_for_terminal_and_renderer_type (manager,
++ ply_terminal_get_name (manager->local_console_terminal),
++ manager->local_console_terminal,
++ PLY_RENDERER_TYPE_NONE);
++}
++
++static void
++create_fallback_seat (ply_device_manager_t *manager)
++{
++ create_seat_for_terminal_and_renderer_type (manager,
++ ply_terminal_get_name (manager->local_console_terminal),
++ manager->local_console_terminal,
++ PLY_RENDERER_TYPE_AUTO);
++}
++
++static void
++on_udev_queue_changed (ply_device_manager_t *manager)
++{
++
++ if (!udev_queue_get_queue_is_empty (manager->udev_queue))
++ return;
++
++ ply_trace ("udev coldplug complete");
++ ply_event_loop_stop_watching_fd (manager->loop, manager->udev_queue_fd_watch);
++ manager->udev_queue_fd_watch = NULL;
++ udev_queue_unref (manager->udev_queue);
++
++ close (manager->udev_queue_fd);
++ manager->udev_queue_fd = -1;
++
++ manager->udev_queue = NULL;
++
++ create_seats_from_udev (manager);
++}
++
++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);
++
++ if (result < 0)
++ {
++ ply_trace ("could not watch for udev to show up: %m");
++ close (fd);
++
++ create_fallback_seat (manager);
++ return;
++ }
++
++ manager->udev_queue_fd = fd;
++
++ manager->udev_queue_fd_watch = ply_event_loop_watch_fd (manager->loop,
++ fd,
++ PLY_EVENT_LOOP_FD_STATUS_HAS_DATA,
++ (ply_event_handler_t)
++ on_udev_queue_changed,
++ NULL,
++ manager);
++
++}
++
++void
++ply_device_manager_watch_seats (ply_device_manager_t *manager,
++ ply_seat_added_handler_t seat_added_handler,
++ ply_seat_removed_handler_t seat_removed_handler,
++ void *data)
++{
++ bool done_with_initial_seat_setup;
++
++ 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
++ */
++ done_with_initial_seat_setup = create_seats_from_terminals (manager);
++
++ if (done_with_initial_seat_setup)
++ return;
++
++ if ((manager->flags & PLY_DEVICE_MANAGER_FLAGS_IGNORE_UDEV))
++ {
++ ply_trace ("udev support disabled, creating fallback seat");
++ create_fallback_seat (manager);
++ return;
++ }
++
++ watch_for_udev_events (manager);
++ watch_for_coldplug_completion (manager);
++}
++
++bool
++ply_device_manager_has_open_seats (ply_device_manager_t *manager)
++{
++ ply_list_node_t *node;
++
++ node = ply_list_get_first_node (manager->seats);
++ while (node != NULL)
++ {
++ ply_seat_t *seat;
++ ply_list_node_t *next_node;
++
++ seat = ply_list_node_get_data (node);
++ next_node = ply_list_get_next_node (manager->seats, node);
++
++ if (ply_seat_is_open (seat))
++ return true;
++
++ node = next_node;
++ }
++
++ return false;
++}
++
++ply_list_t *
++ply_device_manager_get_seats (ply_device_manager_t *manager)
++{
++ return manager->seats;
++}
++
++ply_terminal_t *
++ply_device_manager_get_default_terminal (ply_device_manager_t *manager)
++{
++ return manager->local_console_terminal;
++}
++
++void
++ply_device_manager_activate_renderers (ply_device_manager_t *manager)
++{
++ ply_list_node_t *node;
++
++ ply_trace ("activating renderers");
++ node = ply_list_get_first_node (manager->seats);
++ while (node != NULL)
++ {
++ ply_seat_t *seat;
++ ply_list_node_t *next_node;
++
++ seat = ply_list_node_get_data (node);
++ next_node = ply_list_get_next_node (manager->seats, node);
++
++ ply_seat_activate_renderer (seat);
++
++ node = next_node;
++ }
++}
++
++void
++ply_device_manager_deactivate_renderers (ply_device_manager_t *manager)
++{
++ ply_list_node_t *node;
++
++ ply_trace ("deactivating renderers");
++ node = ply_list_get_first_node (manager->seats);
++ while (node != NULL)
++ {
++ ply_seat_t *seat;
++ ply_list_node_t *next_node;
++
++ seat = ply_list_node_get_data (node);
++ next_node = ply_list_get_next_node (manager->seats, node);
++
++ ply_seat_deactivate_renderer (seat);
++
++ node = next_node;
++ }
++}
++
++void
++ply_device_manager_activate_keyboards (ply_device_manager_t *manager)
++{
++ ply_list_node_t *node;
++
++ ply_trace ("activating keyboards");
++ node = ply_list_get_first_node (manager->seats);
++ while (node != NULL)
++ {
++ ply_seat_t *seat;
++ ply_list_node_t *next_node;
++
++ seat = ply_list_node_get_data (node);
++ next_node = ply_list_get_next_node (manager->seats, node);
++
++ ply_seat_activate_keyboard (seat);
++
++ node = next_node;
++ }
++}
++
++void
++ply_device_manager_deactivate_keyboards (ply_device_manager_t *manager)
++{
++ ply_list_node_t *node;
++
++ ply_trace ("deactivating keyboards");
++ node = ply_list_get_first_node (manager->seats);
++ while (node != NULL)
++ {
++ ply_seat_t *seat;
++ ply_list_node_t *next_node;
++
++ seat = ply_list_node_get_data (node);
++ next_node = ply_list_get_next_node (manager->seats, node);
++
++ ply_seat_deactivate_keyboard (seat);
++
++ node = next_node;
++ }
++}
+diff --git a/src/libply-splash-core/ply-device-manager.h b/src/libply-splash-core/ply-device-manager.h
+new file mode 100644
+index 0000000..d9c58e8
+--- /dev/null
++++ b/src/libply-splash-core/ply-device-manager.h
+@@ -0,0 +1,56 @@
++/* ply-device-manager.h - udev monitor
++ *
++ * Copyright (C) 2013 Red Hat, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
++ * 02111-1307, USA.
++ */
++#ifndef PLY_DEVICE_MANAGER_H
++#define PLY_DEVICE_MANAGER_H
++
++#include <stdbool.h>
++#include "ply-seat.h"
++
++typedef enum
++{
++ PLY_DEVICE_MANAGER_FLAGS_NONE = 0,
++ PLY_DEVICE_MANAGER_FLAGS_IGNORE_SERIAL_CONSOLES = 1 << 0,
++ PLY_DEVICE_MANAGER_FLAGS_IGNORE_UDEV = 1 << 1
++} ply_device_manager_flags_t;
++
++typedef struct _ply_device_manager ply_device_manager_t;
++typedef void (* ply_seat_added_handler_t) (void *, ply_seat_t *);
++typedef void (* ply_seat_removed_handler_t) (void *, ply_seat_t *);
++
++#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
++ply_device_manager_t *ply_device_manager_new (const char *default_tty,
++ ply_device_manager_flags_t flags);
++void ply_device_manager_watch_seats (ply_device_manager_t *manager,
++ ply_seat_added_handler_t seat_added_handler,
++ ply_seat_removed_handler_t seat_removed_handler,
++ void *data);
++bool ply_device_manager_has_open_seats (ply_device_manager_t *manager);
++ply_list_t *ply_device_manager_get_seats (ply_device_manager_t *manager);
++void ply_device_manager_free (ply_device_manager_t *manager);
++void ply_device_manager_activate_keyboards (ply_device_manager_t *manager);
++void ply_device_manager_deactivate_keyboards (ply_device_manager_t *manager);
++void ply_device_manager_activate_renderers (ply_device_manager_t *manager);
++void ply_device_manager_deactivate_renderers (ply_device_manager_t *manager);
++ply_terminal_t *ply_device_manager_get_default_terminal (ply_device_manager_t *manager);
++
++#endif
++
++#endif
++/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */
+diff --git a/src/libply-splash-core/ply-pixel-buffer.c b/src/libply-splash-core/ply-pixel-buffer.c
+index a612990..a860b7f 100644
+--- a/src/libply-splash-core/ply-pixel-buffer.c
++++ b/src/libply-splash-core/ply-pixel-buffer.c
+@@ -848,5 +848,35 @@ ply_pixel_buffer_rotate (ply_pixel_buffer_t *old_buffer,
+ return buffer;
+ }
+
++ply_pixel_buffer_t *
++ply_pixel_buffer_tile (ply_pixel_buffer_t *old_buffer,
++ long width,
++ long height)
++{
++ long x, y;
++ long old_x, old_y;
++ long old_width, old_height;
++ uint32_t *bytes, *old_bytes;
++ ply_pixel_buffer_t *buffer;
++
++ buffer = ply_pixel_buffer_new (width, height);
++
++ old_bytes = ply_pixel_buffer_get_argb32_data (old_buffer);
++ bytes = ply_pixel_buffer_get_argb32_data (buffer);
++
++ old_width = old_buffer->area.width;
++ old_height = old_buffer->area.height;
++
++ for (y = 0; y < height; y++)
++ {
++ old_y = y % old_height;
++ for (x = 0; x < width; x++)
++ {
++ old_x = x % old_width;
++ bytes[x + y * width] = old_bytes[old_x + old_y * old_width];
++ }
++ }
++ return buffer;
++}
+
+ /* 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 47cdd52..e0dffda 100644
+--- a/src/libply-splash-core/ply-pixel-buffer.h
++++ b/src/libply-splash-core/ply-pixel-buffer.h
+@@ -124,6 +124,10 @@ ply_pixel_buffer_t *ply_pixel_buffer_rotate (ply_pixel_buffer_t *old_buffer,
+ long center_y,
+ double theta_offset);
+
++ply_pixel_buffer_t *ply_pixel_buffer_tile (ply_pixel_buffer_t *old_buffer,
++ long width,
++ long height);
++
+ #endif
+
+ #endif /* PLY_PIXEL_BUFFER_H */
+diff --git a/src/libply-splash-core/ply-renderer.c b/src/libply-splash-core/ply-renderer.c
+index 3559e01..04a99ce 100644
+--- a/src/libply-splash-core/ply-renderer.c
++++ b/src/libply-splash-core/ply-renderer.c
+@@ -49,7 +49,7 @@ struct _ply_renderer
+ const ply_renderer_plugin_interface_t *plugin_interface;
+ ply_renderer_backend_t *backend;
+
+- char *plugin_path;
++ ply_renderer_type_t type;
+ char *device_name;
+ ply_terminal_t *terminal;
+
+@@ -63,16 +63,15 @@ typedef const ply_renderer_plugin_interface_t *
+ static void ply_renderer_unload_plugin (ply_renderer_t *renderer);
+
+ ply_renderer_t *
+-ply_renderer_new (const char *plugin_path,
+- const char *device_name,
+- ply_terminal_t *terminal)
++ply_renderer_new (ply_renderer_type_t renderer_type,
++ const char *device_name,
++ ply_terminal_t *terminal)
+ {
+ ply_renderer_t *renderer;
+
+ renderer = calloc (1, sizeof (struct _ply_renderer));
+
+- if (plugin_path != NULL)
+- renderer->plugin_path = strdup (plugin_path);
++ renderer->type = renderer_type;
+
+ if (device_name != NULL)
+ renderer->device_name = strdup (device_name);
+@@ -95,10 +94,15 @@ ply_renderer_free (ply_renderer_t *renderer)
+ }
+
+ free (renderer->device_name);
+- free (renderer->plugin_path);
+ free (renderer);
+ }
+
++const char *
++ply_renderer_get_device_name (ply_renderer_t *renderer)
++{
++ return renderer->device_name;
++}
++
+ static bool
+ ply_renderer_load_plugin (ply_renderer_t *renderer,
+ const char *module_path)
+@@ -258,29 +262,28 @@ ply_renderer_open (ply_renderer_t *renderer)
+ {
+ int i;
+
+- /* FIXME: at some point we may want to make this
+- * part more dynamic (so you don't have to edit this
+- * list to add a new renderer)
+- */
+- const char *known_plugins[] =
++ struct
+ {
+- PLYMOUTH_PLUGIN_PATH "renderers/x11.so",
+- PLYMOUTH_PLUGIN_PATH "renderers/drm.so",
+- PLYMOUTH_PLUGIN_PATH "renderers/frame-buffer.so",
+- NULL
++ ply_renderer_type_t type;
++ const char *path;
++ } known_plugins[] =
++ {
++ { PLY_RENDERER_TYPE_X11, PLYMOUTH_PLUGIN_PATH "renderers/x11.so" },
++ { PLY_RENDERER_TYPE_DRM, PLYMOUTH_PLUGIN_PATH "renderers/drm.so" },
++ { PLY_RENDERER_TYPE_FRAME_BUFFER, PLYMOUTH_PLUGIN_PATH "renderers/frame-buffer.so" },
++ { PLY_RENDERER_TYPE_NONE, NULL }
+ };
+
+- if (renderer->plugin_path != NULL)
++ for (i = 0; known_plugins[i].type != PLY_RENDERER_TYPE_NONE; i++)
+ {
+- return ply_renderer_open_plugin (renderer, renderer->plugin_path);
++ if (renderer->type == known_plugins[i].type ||
++ renderer->type == PLY_RENDERER_TYPE_AUTO)
++ {
++ if (ply_renderer_open_plugin (renderer, known_plugins[i].path))
++ return true;
++ }
+ }
+
+- for (i = 0; known_plugins[i] != NULL; i++)
+- {
+- if (ply_renderer_open_plugin (renderer, known_plugins[i]))
+- return true;
+- }
+-
+ ply_trace ("could not find suitable rendering plugin");
+ return false;
+ }
+diff --git a/src/libply-splash-core/ply-renderer.h b/src/libply-splash-core/ply-renderer.h
+index 4b3bd1a..3d48341 100644
+--- a/src/libply-splash-core/ply-renderer.h
++++ b/src/libply-splash-core/ply-renderer.h
+@@ -35,12 +35,21 @@ typedef struct _ply_renderer ply_renderer_t;
+ typedef struct _ply_renderer_head ply_renderer_head_t;
+ typedef struct _ply_renderer_input_source ply_renderer_input_source_t;
+
++typedef enum
++{
++ PLY_RENDERER_TYPE_NONE = -1,
++ PLY_RENDERER_TYPE_AUTO,
++ PLY_RENDERER_TYPE_DRM,
++ PLY_RENDERER_TYPE_FRAME_BUFFER,
++ PLY_RENDERER_TYPE_X11
++} ply_renderer_type_t;
++
+ typedef void (* ply_renderer_input_source_handler_t) (void *user_data,
+ ply_buffer_t *key_buffer,
+ ply_renderer_input_source_t *input_source);
+
+ #ifndef PLY_HIDE_FUNCTION_DECLARATIONS
+-ply_renderer_t *ply_renderer_new (const char *plugin_path,
++ply_renderer_t *ply_renderer_new (ply_renderer_type_t renderer_type,
+ const char *device_name,
+ ply_terminal_t *terminal);
+ void ply_renderer_free (ply_renderer_t *renderer);
+@@ -48,6 +57,7 @@ bool ply_renderer_open (ply_renderer_t *renderer);
+ void ply_renderer_close (ply_renderer_t *renderer);
+ void ply_renderer_activate (ply_renderer_t *renderer);
+ void ply_renderer_deactivate (ply_renderer_t *renderer);
++const char *ply_renderer_get_device_name (ply_renderer_t *renderer);
+ ply_list_t *ply_renderer_get_heads (ply_renderer_t *renderer);
+ ply_pixel_buffer_t *ply_renderer_get_buffer_for_head (ply_renderer_t *renderer,
+ ply_renderer_head_t *head);
+diff --git a/src/libply-splash-core/ply-seat.c b/src/libply-splash-core/ply-seat.c
+new file mode 100644
+index 0000000..2ac8bf7
+--- /dev/null
++++ b/src/libply-splash-core/ply-seat.c
+@@ -0,0 +1,387 @@
++/* 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 at 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
++ {
++ seat->keyboard = ply_keyboard_new_for_terminal (seat->terminal);
++ }
++ add_text_displays (seat);
++
++ ply_keyboard_watch_for_input (seat->keyboard);
++ seat->keyboard_active = true;
++
++ return true;
++}
++
++bool
++ply_seat_is_open (ply_seat_t *seat)
++{
++ return ply_list_get_length (seat->pixel_displays) > 0 ||
++ ply_list_get_length (seat->text_displays) > 0;
++}
++
++void
++ply_seat_deactivate_keyboard (ply_seat_t *seat)
++{
++ if (!seat->keyboard_active)
++ return;
++
++ seat->keyboard_active = false;
++
++ if (seat->keyboard == NULL)
++ return;
++
++ ply_trace ("deactivating keybord");
++ ply_keyboard_stop_watching_for_input (seat->keyboard);
++}
++
++void
++ply_seat_deactivate_renderer (ply_seat_t *seat)
++{
++ if (!seat->renderer_active)
++ return;
++
++ seat->renderer_active = false;
++
++ if (seat->renderer == NULL)
++ return;
++
++ ply_trace ("deactivating renderer");
++ ply_renderer_deactivate (seat->renderer);
++}
++
++void
++ply_seat_activate_keyboard (ply_seat_t *seat)
++{
++ if (seat->keyboard_active)
++ return;
++
++ if (seat->keyboard == NULL)
++ return;
++
++ ply_trace ("activating keyboard");
++ ply_keyboard_watch_for_input (seat->keyboard);
++
++ seat->keyboard_active = true;
++}
++
++void
++ply_seat_activate_renderer (ply_seat_t *seat)
++{
++ if (seat->renderer_active)
++ return;
++
++ if (seat->renderer == NULL)
++ return;
++
++ ply_trace ("activating renderer");
++ ply_renderer_activate (seat->renderer);
++
++ seat->renderer_active = true;
++}
++
++void
++ply_seat_refresh_displays (ply_seat_t *seat)
++{
++ ply_list_node_t *node;
++
++ node = ply_list_get_first_node (seat->pixel_displays);
++ while (node != NULL)
++ {
++ ply_pixel_display_t *display;
++ ply_list_node_t *next_node;
++ unsigned long width, height;
++
++ display = ply_list_node_get_data (node);
++ next_node = ply_list_get_next_node (seat->pixel_displays, node);
++
++ width = ply_pixel_display_get_width (display);
++ height = ply_pixel_display_get_height (display);
++
++ ply_pixel_display_draw_area (display, 0, 0, width, height);
++ node = next_node;
++ }
++
++ node = ply_list_get_first_node (seat->text_displays);
++ while (node != NULL)
++ {
++ ply_text_display_t *display;
++ ply_list_node_t *next_node;
++ int number_of_columns, number_of_rows;
++
++ display = ply_list_node_get_data (node);
++ next_node = ply_list_get_next_node (seat->text_displays, node);
++
++ number_of_columns = ply_text_display_get_number_of_columns (display);
++ number_of_rows = ply_text_display_get_number_of_rows (display);
++
++ ply_text_display_draw_area (display, 0, 0,
++ number_of_columns,
++ number_of_rows);
++ node = next_node;
++ }
++}
++
++void
++ply_seat_close (ply_seat_t *seat)
++{
++ if (seat->renderer == NULL)
++ return;
++
++ ply_trace ("destroying renderer");
++ ply_renderer_close (seat->renderer);
++ ply_renderer_free (seat->renderer);
++ seat->renderer = NULL;
++}
++
++void
++ply_seat_set_splash (ply_seat_t *seat,
++ ply_boot_splash_t *splash)
++{
++ if (seat->splash == splash)
++ return;
++
++ if (seat->splash != NULL)
++ ply_boot_splash_detach_from_seat (splash, seat);
++
++ if (splash != NULL)
++ ply_boot_splash_attach_to_seat (splash, seat);
++
++ seat->splash = splash;
++}
++
++static void
++free_pixel_displays (ply_seat_t *seat)
++{
++ ply_list_node_t *node;
++
++ ply_trace ("freeing %d pixel displays", ply_list_get_length (seat->pixel_displays));
++ node = ply_list_get_first_node (seat->pixel_displays);
++ while (node != NULL)
++ {
++ ply_list_node_t *next_node;
++ ply_pixel_display_t *display;
++
++ next_node = ply_list_get_next_node (seat->pixel_displays, node);
++ display = ply_list_node_get_data (node);
++ ply_pixel_display_free (display);
++
++ ply_list_remove_node (seat->pixel_displays, node);
++
++ node = next_node;
++ }
++}
++
++static void
++free_text_displays (ply_seat_t *seat)
++{
++ ply_list_node_t *node;
++
++ ply_trace ("freeing %d text displays", ply_list_get_length (seat->text_displays));
++ node = ply_list_get_first_node (seat->text_displays);
++ while (node != NULL)
++ {
++ ply_list_node_t *next_node;
++ ply_text_display_t *display;
++
++ next_node = ply_list_get_next_node (seat->text_displays, node);
++ display = ply_list_node_get_data (node);
++ ply_text_display_free (display);
++
++ ply_list_remove_node (seat->text_displays, node);
++
++ node = next_node;
++ }
++}
++
++void
++ply_seat_free (ply_seat_t *seat)
++{
++ if (seat == NULL)
++ return;
++
++ free_pixel_displays (seat);
++ free_text_displays (seat);
++ ply_keyboard_free (seat->keyboard);
++
++ free (seat);
++}
++
++ply_list_t *
++ply_seat_get_pixel_displays (ply_seat_t *seat)
++{
++ return seat->pixel_displays;
++}
++
++ply_list_t *
++ply_seat_get_text_displays (ply_seat_t *seat)
++{
++ return seat->text_displays;
++}
++
++ply_keyboard_t *
++ply_seat_get_keyboard (ply_seat_t *seat)
++{
++ return seat->keyboard;
++}
++
++ply_renderer_t *
++ply_seat_get_renderer (ply_seat_t *seat)
++{
++ return seat->renderer;
++}
++
++/* vim: set ts=4 sw=4 et ai ci cino={.5s,^-2,+.5s,t0,g0,e-2,n-2,p2s,(0,=.5s,:.5s */
+diff --git a/src/libply-splash-core/ply-seat.h b/src/libply-splash-core/ply-seat.h
+new file mode 100644
+index 0000000..d5d3397
+--- /dev/null
++++ b/src/libply-splash-core/ply-seat.h
+@@ -0,0 +1,66 @@
++/* ply-seat.h - APIs for encapsulating a keyboard and one or more displays
++ *
++ * Copyright (C) 2013 Red Hat, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
++ * 02111-1307, USA.
++ *
++ * Written By: Ray Strode <rstrode at 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);
<Skipped 7660 lines>
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/plymouth.git/commitdiff/0e83ad6d3eeacede31400633920f5f0d7bea4c53
More information about the pld-cvs-commit
mailing list