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 - #include - #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 - #include - #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 - #include - #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 - #include - #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 - #include - #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 - #include - #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 @@ + + + + + + + plymouth-set-default-theme + plymouth + + + + Developer + Kristian + Høgsberg + + + Developer + Ray + Strode + + + + + + + plymouth-set-default-theme + 1 + User Commands + + + + plymouth-set-default-theme + Set the plymouth theme + + + + + plymouth-set-default-theme OPTION THEME + + + + + Description + + +When called with a argument, +the plymouth-set-default-theme 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. + + + +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. + + + + + + Options + + The following options are understood: + + + + , + Show summary of options. + + + + , + List available themes. + + + + , + Reset to default theme. + + + + , + Rebuild initrd (necessary after changing theme). + + + + + + See Also + + grub8, + plymouth8, + plymouthd8, + plymouth1, + http://www.freedesktop.org/wiki/Software/Plymouth + + + + 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 ] " \" -.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 \ -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 , -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. -It can be downloaded here: . -.PP -This manual page was written by Adrian Glaubitz . 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 @@ + + + + + + + plymouth + plymouth + + + + Developer + Kristian + Høgsberg + + + Developer + Ray + Strode + + + + + + + plymouth + 8 + System Administration + + + + plymouth + A graphical boot system and logger + + + + Description + + +plymouth 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. + + +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. + + + +During the boot process, the user can switch between the graphical theme +and the detailed boot output using the Escape key. + + + + + + See Also + + grub8, + plymouth-set-theme1, + plymouthd8, + plymouth1, + http://www.freedesktop.org/wiki/Software/Plymouth + + + + + Authors + +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. + + + 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 @@ + + + + + + + plymouth + plymouth + + + + Developer + Kristian + Høgsberg + + + Developer + Ray + Strode + + + + + + + plymouth + 1 + User Commands + + + + plymouth + Send commands to plymouthd + + + + + plymouth OPTION + + + plymouth COMMAND OPTION + + + + + Description + + +The plymouth sends commands to a running +plymouthd. This is used during the boot +process to control the display of the graphical boot splash. + + + + + + Options + + +The following options are understood. These options are supported +for compatibility with the old rhgb-client interface, +and have been replaced by the commands that are described in the +next section. + + + + + + Show summary of options. + + + + + Enable verbose debug logging. + + + + + Get directory where splash plugins are installed. + + + + + Tell plymouthd that the new root filesystem is mounted. + + + + + Tell plymouthd to quit. + + + + + Check if plymouthd is running. + + + + + Check if plymouthd has an active vt. + + + + + Tell plymouthd root filesystem is mounted read-write. + + + + + Show the splash screen. + + + + + Hide the splash screen. + + + + + Ask the user for a password. + + + + + Remove sensitivity to a keystroke. + + + + + Tell plymouthd an update about boot progress. + + + + + Tell plymouthd there were errors during boot. + + + + + Wait for plymouthd to quit. + + + + + + Commands + + +The following commands are understood: + + + + change-mode OPTION + Change the operation mode. + + + + Start the system up + + + + Shutting the system up + + + + Applying updates + + + + + + system-update OPTION + Tell plymouthd about boot progress. + + + + The percentage progress of the updates + + + + + + update OPTION + Tell plymouthd about boot status changes. + + + + Tell plymouthd the current boot status + + + + + + update-root-fs OPTION + Tell plymouthd about root filesystem changes. + + + + Root filesystem is about to change + + + + Root filesystem is no longer read-only + + + + + + show-splash + Tell plymouthd to show splash screen. + + + hide-splash + Tell plymouthd to hide splash screen. + + + ask-for-password OPTION + Ask the user for a password. + + + + Command to send password to via standard input + + + + Message to display when asking for password + + + + Number of times to ask before giving up (requires ) + + + + Don't pause boot progress bar while asking + + + + + + ask-question + Ask the user a question. + + + + Command to send the answer to via standard input + + + + Message to display when asking the question + + + + Don't pause boot progress bar while asking + + + + + + display-message OPTION + Display a message. + + + + The message text + + + + + + hide-message OPTION + Hide a message. + + + + The message text + + + + + + watch-keystroke OPTION + Become sensitive to a keystroke. + + + + Command to send keystroke to via standard input + + + + Keys to become sensitive to + + + + + + ignore-keystroke OPTION + Remove sensitivity to a keystroke. + + + + Keys to remove sensitivitiy from + + + + + + pause-progress + Pause boot progress bar. + + + unpause-progress + Unpause boot progress bar. + + + report-error + Tell plymouthd there were errors during boot. + + + deactivate + Tell plymouthd to deactivate. + + + reactivate + Tell plymouthd to reactivate. + + + quit OPTION + Tell plymouthd to quit. + + + + Don't explicitly hide boot splash on exit + + + + + + + + + + See Also + + grub8, + plymouth8, + plymouthd8, + http://www.freedesktop.org/wiki/Software/Plymouth + + + + 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 @@ + + + + + + + plymouthd + plymouth + + + + Developer + Kristian + Høgsberg + + + Developer + Ray + Strode + + + + + + + plymouthd + 8 + System Administration + + + + plymouthd + The plymouth daemon + + + + + plymouthd OPTION + + + + + Description + + +The plymouthd 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. + + +The plymouth is used to send commands to plymouthd +that control its behaviour. + + + + + + Options + + The following options are understood: + + + + + Show summary of options. + + + + + Redirect console messages from screen to log. + + + + + Do not daemonize. + + + + + Output debugging information. + + + + + File to write debugging information to. + + + + + Set mode to either boot or shutdown. + + + + + Write the PID of the daemon to a file. + + + + + Fake kernel commandline to use. + + + + + TTY to ues instead of default. + + + + + + See Also + + grub8, + plymouth8, + plymouth1, + http://www.freedesktop.org/wiki/Software/Plymouth + + + + 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 - -#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 - -#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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "ply-logger.h" +#include "ply-event-loop.h" +#include "ply-hashtable.h" +#include "ply-list.h" +#include "ply-utils.h" + +#define SUBSYSTEM_DRM "drm" +#define SUBSYSTEM_FRAME_BUFFER "graphics" + +static void create_seat_for_terminal_and_renderer_type (ply_device_manager_t *manager, + const char *device_path, + ply_terminal_t *terminal, + ply_renderer_type_t renderer_type); +struct _ply_device_manager +{ + ply_device_manager_flags_t flags; + ply_event_loop_t *loop; + ply_hashtable_t *terminals; + ply_terminal_t *local_console_terminal; + ply_seat_t *local_console_seat; + ply_list_t *seats; + struct udev *udev_context; + struct udev_queue *udev_queue; + int udev_queue_fd; + ply_fd_watch_t *udev_queue_fd_watch; + struct udev_monitor *udev_monitor; + + ply_seat_added_handler_t seat_added_handler; + ply_seat_removed_handler_t seat_removed_handler; + void *seat_event_handler_data; +}; + +static void +detach_from_event_loop (ply_device_manager_t *manager) +{ + assert (manager != NULL); + + manager->loop = NULL; +} + +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 +#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 + */ +#include "config.h" +#include "ply-seat.h" + +#include +#include +#include +#include +#include +#include + +#include "ply-boot-splash.h" +#include "ply-event-loop.h" +#include "ply-keyboard.h" +#include "ply-pixel-display.h" +#include "ply-text-display.h" +#include "ply-list.h" +#include "ply-logger.h" +#include "ply-utils.h" + +struct _ply_seat +{ + ply_event_loop_t *loop; + + ply_boot_splash_t *splash; + ply_terminal_t *terminal; + ply_renderer_t *renderer; + ply_keyboard_t *keyboard; + ply_list_t *text_displays; + ply_list_t *pixel_displays; + + uint32_t renderer_active : 1; + uint32_t keyboard_active : 1; +}; + +ply_seat_t * +ply_seat_new (ply_terminal_t *terminal) +{ + ply_seat_t *seat; + + seat = calloc (1, sizeof (ply_seat_t)); + + seat->loop = ply_event_loop_get_default (); + seat->terminal = terminal; + seat->text_displays = ply_list_new (); + seat->pixel_displays = ply_list_new (); + + return seat; +} + +static void +add_pixel_displays (ply_seat_t *seat) +{ + ply_list_t *heads; + ply_list_node_t *node; + + heads = ply_renderer_get_heads (seat->renderer); + + ply_trace ("Adding displays for %d heads", + ply_list_get_length (heads)); + + node = ply_list_get_first_node (heads); + 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 + */ +#ifndef PLY_SEAT_H +#define PLY_SEAT_H + +#include +#include +#include +#include + +#include "ply-boot-splash.h" +#include "ply-buffer.h" +#include "ply-event-loop.h" +#include "ply-keyboard.h" +#include "ply-list.h" +#include "ply-pixel-display.h" +#include "ply-terminal.h" +#include "ply-text-display.h" + +typedef struct _ply_boot_splash ply_boot_splash_t; +typedef struct _ply_seat ply_seat_t; + +#ifndef PLY_HIDE_FUNCTION_DECLARATIONS +ply_seat_t *ply_seat_new (ply_terminal_t *terminal); + +void ply_seat_free (ply_seat_t *seat); +bool ply_seat_open (ply_seat_t *seat, + ply_renderer_type_t renderer_type, + const char *device); +bool ply_seat_is_open (ply_seat_t *seat); +void ply_seat_deactivate_keyboard (ply_seat_t *seat); +void ply_seat_activate_keyboard (ply_seat_t *seat); +void ply_seat_deactivate_renderer (ply_seat_t *seat); +void ply_seat_activate_renderer (ply_seat_t *seat); +void ply_seat_refresh_displays (ply_seat_t *seat); +void ply_seat_close (ply_seat_t *seat); +void ply_seat_set_splash (ply_seat_t *seat, + ply_boot_splash_t *splash); + +ply_list_t *ply_seat_get_pixel_displays (ply_seat_t *seat); +ply_list_t *ply_seat_get_text_displays (ply_seat_t *seat); +ply_keyboard_t *ply_seat_get_keyboard (ply_seat_t *seat); +ply_renderer_t *ply_seat_get_renderer (ply_seat_t *seat); +#endif + +#endif /* PLY_SEAT_H */ +/* vim: set ts=4 sw=4 et ai ci cino={.5s,^-2,+.5s,t0,g0,e-2,n-2,p2s,(0,=.5s,:.5s */ diff --git a/src/libply-splash-core/ply-terminal.c b/src/libply-splash-core/ply-terminal.c index 2e95dc8..992dd3f 100644 --- a/src/libply-splash-core/ply-terminal.c +++ b/src/libply-splash-core/ply-terminal.c @@ -876,6 +876,12 @@ ply_terminal_free (ply_terminal_t *terminal) free (terminal); } +const char * +ply_terminal_get_name (ply_terminal_t *terminal) +{ + return terminal->name; +} + int ply_terminal_get_vt_number (ply_terminal_t *terminal) { diff --git a/src/libply-splash-core/ply-terminal.h b/src/libply-splash-core/ply-terminal.h index 8b4b017..48b4f77 100644 --- a/src/libply-splash-core/ply-terminal.h +++ b/src/libply-splash-core/ply-terminal.h @@ -91,6 +91,7 @@ void ply_terminal_set_mode (ply_terminal_t *terminal, void ply_terminal_ignore_mode_changes (ply_terminal_t *terminal, bool should_ignore); +const char *ply_terminal_get_name (ply_terminal_t *terminal); int ply_terminal_get_vt_number (ply_terminal_t *terminal); bool ply_terminal_activate_vt (ply_terminal_t *terminal); bool ply_terminal_deactivate_vt (ply_terminal_t *terminal); diff --git a/src/libply-splash-core/ply-text-progress-bar.c b/src/libply-splash-core/ply-text-progress-bar.c index bf4b378..8c4e759 100644 --- a/src/libply-splash-core/ply-text-progress-bar.c +++ b/src/libply-splash-core/ply-text-progress-bar.c @@ -104,7 +104,7 @@ get_os_string (void) buf = NULL; - fd = open (RELEASE_FILE, O_RDONLY); + fd = open (RELEASE_FILE, O_RDONLY|O_CLOEXEC); if (fd == -1) goto out; @@ -136,6 +136,8 @@ get_os_string (void) if (pos2 != NULL) *pos2 = '\0'; + else + pos2 = pos + strlen(pos) - 1; if ((*pos == '\"' && pos2[-1] == '\"') || (*pos == '\'' && pos2[-1] == '\'')) diff --git a/src/libply-splash-core/ply-text-step-bar.c b/src/libply-splash-core/ply-text-step-bar.c new file mode 100644 index 0000000..552a39f --- /dev/null +++ b/src/libply-splash-core/ply-text-step-bar.c @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2008-2012 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ +#include "config.h" + +#include +#include +#include +#include +#include + +#include "ply-text-display.h" +#include "ply-text-step-bar.h" + +struct _ply_text_step_bar +{ + ply_text_display_t *display; + + int column; + int row; + int number_of_rows; + int number_of_columns; + + double percent_done; + uint32_t is_hidden : 1; +}; + +ply_text_step_bar_t * +ply_text_step_bar_new (void) +{ + ply_text_step_bar_t *step_bar; + + step_bar = calloc (1, sizeof (ply_text_step_bar_t)); + + step_bar->row = 0; + step_bar->column = 0; + step_bar->number_of_columns = 0; + step_bar->number_of_rows = 0; + + return step_bar; +} + +void +ply_text_step_bar_free (ply_text_step_bar_t *step_bar) +{ + if (step_bar == NULL) + return; + + free (step_bar); +} + +void +ply_text_step_bar_draw (ply_text_step_bar_t *step_bar) +{ + int i; + int cur; + + if (step_bar->is_hidden) + return; + + ply_text_display_set_background_color (step_bar->display, + PLY_TERMINAL_COLOR_BLACK); + + ply_text_display_set_cursor_position (step_bar->display, + step_bar->column, + step_bar->row); + + cur = step_bar->percent_done * step_bar->number_of_columns; + for (i = 0; i < step_bar->number_of_columns; i++) + { + if (i == cur) + { + ply_text_display_set_foreground_color (step_bar->display, + PLY_TERMINAL_COLOR_WHITE); + } + else + { + ply_text_display_set_foreground_color (step_bar->display, + PLY_TERMINAL_COLOR_BROWN); + } + + ply_text_display_write (step_bar->display, "%c", '■'); + ply_text_display_write (step_bar->display, "%c", ' '); + } + + ply_text_display_set_foreground_color (step_bar->display, + PLY_TERMINAL_COLOR_DEFAULT); +} + +void +ply_text_step_bar_show (ply_text_step_bar_t *step_bar, + ply_text_display_t *display) +{ + int screen_rows; + int screen_cols; + + assert (step_bar != NULL); + + step_bar->display = display; + + + screen_rows = ply_text_display_get_number_of_rows (display); + screen_cols = ply_text_display_get_number_of_columns (display); + + step_bar->number_of_rows = 1; + step_bar->row = screen_rows * .66; + step_bar->number_of_columns = 3; + step_bar->column = screen_cols / 2.0 - step_bar->number_of_columns / 2.0; + + step_bar->is_hidden = false; + + ply_text_step_bar_draw (step_bar); +} + +void +ply_text_step_bar_hide (ply_text_step_bar_t *step_bar) +{ + step_bar->display = NULL; + step_bar->is_hidden = true; +} + +void +ply_text_step_bar_set_percent_done (ply_text_step_bar_t *step_bar, + double percent_done) +{ + step_bar->percent_done = percent_done; +} + +double +ply_text_step_bar_get_percent_done (ply_text_step_bar_t *step_bar) +{ + return step_bar->percent_done; +} + +int +ply_text_step_bar_get_number_of_columns (ply_text_step_bar_t *step_bar) +{ + return step_bar->number_of_columns; +} + +int +ply_text_step_bar_get_number_of_rows (ply_text_step_bar_t *step_bar) +{ + return step_bar->number_of_rows; +} + +/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ diff --git a/src/libply-splash-core/ply-text-step-bar.h b/src/libply-splash-core/ply-text-step-bar.h new file mode 100644 index 0000000..0a4733f --- /dev/null +++ b/src/libply-splash-core/ply-text-step-bar.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2008-2012 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ +#ifndef PLY_TEXT_STEP_BAR_H +#define PLY_TEXT_STEP_BAR_H + +#include + +#include "ply-event-loop.h" +#include "ply-text-display.h" + +typedef struct _ply_text_step_bar ply_text_step_bar_t; + +#ifndef PLY_HIDE_FUNCTION_DECLARATIONS +ply_text_step_bar_t *ply_text_step_bar_new (void); +void ply_text_step_bar_free (ply_text_step_bar_t *step_bar); + +void ply_text_step_bar_draw (ply_text_step_bar_t *step_bar); +void ply_text_step_bar_show (ply_text_step_bar_t *step_bar, + ply_text_display_t *display); +void ply_text_step_bar_hide (ply_text_step_bar_t *step_bar); + +void ply_text_step_bar_set_percent_done (ply_text_step_bar_t *step_bar, + double percent_done); + +double ply_text_step_bar_get_percent_done (ply_text_step_bar_t *step_bar); + +int ply_text_step_bar_get_number_of_rows (ply_text_step_bar_t *step_bar); +int ply_text_step_bar_get_number_of_columns (ply_text_step_bar_t *step_bar); +#endif + +#endif /* PLY_TEXT_PULSER_H */ +/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ diff --git a/src/libply-splash-graphics/Makefile.am b/src/libply-splash-graphics/Makefile.am index f70d1ed..9013e56 100644 --- a/src/libply-splash-graphics/Makefile.am +++ b/src/libply-splash-graphics/Makefile.am @@ -1,4 +1,4 @@ -INCLUDES = -I$(top_srcdir) \ +AM_CPPFLAGS = -I$(top_srcdir) \ -I$(srcdir) \ -I$(srcdir)/../libply \ -I$(srcdir)/../libply-splash-core \ diff --git a/src/libply-splash-graphics/ply-animation.c b/src/libply-splash-graphics/ply-animation.c index ed558cf..bba8490 100644 --- a/src/libply-splash-graphics/ply-animation.c +++ b/src/libply-splash-graphics/ply-animation.c @@ -182,14 +182,8 @@ on_timeout (ply_animation_t *animation) animation->previous_time = animation->now; animation->now = ply_get_timestamp (); -#ifdef REAL_TIME_ANIMATION should_continue = animate_at_time (animation, animation->now - animation->start_time); -#else - static double time = 0.0; - time += 1.0 / FRAMES_PER_SECOND; - should_continue = animate_at_time (animation, time); -#endif sleep_time = 1.0 / FRAMES_PER_SECOND; sleep_time = MAX (sleep_time - (ply_get_timestamp () - animation->now), diff --git a/src/libply-splash-graphics/ply-image.c b/src/libply-splash-graphics/ply-image.c index 3e09f68..7d21946 100644 --- a/src/libply-splash-graphics/ply-image.c +++ b/src/libply-splash-graphics/ply-image.c @@ -123,7 +123,7 @@ ply_image_load (ply_image_t *image) assert (image != NULL); - fp = fopen (image->filename, "r"); + fp = fopen (image->filename, "re"); if (fp == NULL) return false; @@ -254,6 +254,21 @@ ply_image_rotate (ply_image_t *image, return new_image; } +ply_image_t * +ply_image_tile (ply_image_t *image, + long width, + long height) +{ + ply_image_t *new_image; + + new_image = ply_image_new (image->filename); + + new_image->buffer = ply_pixel_buffer_tile (image->buffer, + width, + height); + return new_image; +} + ply_pixel_buffer_t * ply_image_get_buffer (ply_image_t *image) { diff --git a/src/libply-splash-graphics/ply-image.h b/src/libply-splash-graphics/ply-image.h index 66fa520..5bda567 100644 --- a/src/libply-splash-graphics/ply-image.h +++ b/src/libply-splash-graphics/ply-image.h @@ -39,6 +39,7 @@ long ply_image_get_width (ply_image_t *image); long ply_image_get_height (ply_image_t *image); ply_image_t *ply_image_resize (ply_image_t *image, long width, long height); ply_image_t *ply_image_rotate (ply_image_t *oldimage, long center_x, long center_y, double theta_offset); +ply_image_t *ply_image_tile (ply_image_t *image, long width, long height); ply_pixel_buffer_t *ply_image_get_buffer (ply_image_t *image); ply_pixel_buffer_t *ply_image_convert_to_pixel_buffer (ply_image_t *image); diff --git a/src/libply-splash-graphics/ply-throbber.c b/src/libply-splash-graphics/ply-throbber.c index 59cf10c..42044ba 100644 --- a/src/libply-splash-graphics/ply-throbber.c +++ b/src/libply-splash-graphics/ply-throbber.c @@ -178,14 +178,8 @@ on_timeout (ply_throbber_t *throbber) bool should_continue; throbber->now = ply_get_timestamp (); -#ifdef REAL_TIME_ANIMATION should_continue = animate_at_time (throbber, - throbber->now - throbber->start_time); -#else - static double time = 0.0; - time += 1.0 / FRAMES_PER_SECOND; - should_continue = animate_at_time (throbber, time); -#endif + throbber->now - throbber->start_time); sleep_time = 1.0 / FRAMES_PER_SECOND; sleep_time = MAX (sleep_time - (ply_get_timestamp () - throbber->now), diff --git a/src/libply/Makefile.am b/src/libply/Makefile.am index 302e47d..de15808 100644 --- a/src/libply/Makefile.am +++ b/src/libply/Makefile.am @@ -1,5 +1,4 @@ -SUBDIRS = tests -INCLUDES = -I$(top_srcdir) \ +AM_CPPFLAGS = -I$(top_srcdir) \ -I$(srcdir) \ -DPLYMOUTH_TIME_DIRECTORY=\"$(localstatedir)/lib/plymouth/\" diff --git a/src/libply/ply-array.c b/src/libply/ply-array.c index 41134b8..999c86e 100644 --- a/src/libply/ply-array.c +++ b/src/libply/ply-array.c @@ -171,34 +171,4 @@ ply_array_steal_uint32_elements (ply_array_t *array) return data; } -#ifdef PLY_ARRAY_ENABLE_TEST -#include - -int -main (int argc, - char **argv) -{ - ply_array_t *array; - int i; - char **data; - - array = ply_array_new (PLY_ARRAY_ELEMENT_TYPE_POINTER); - - ply_array_add_pointer_element (array, "foo"); - ply_array_add_pointer_element (array, "bar"); - ply_array_add_pointer_element (array, "baz"); - ply_array_add_pointer_element (array, "qux"); - - data = (char **) ply_array_get_pointer_elements (array); - for (i = 0; data[i] != NULL; i++) - { - printf ("element '%d' has data '%s'\n", i, data[i]); - i++; - } - - ply_array_free (array); - return 0; -} - -#endif /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ diff --git a/src/libply/ply-bitarray.c b/src/libply/ply-bitarray.c index 89e2216..3d0cdd0 100644 --- a/src/libply/ply-bitarray.c +++ b/src/libply/ply-bitarray.c @@ -42,64 +42,4 @@ ply_bitarray_count (ply_bitarray_t *bitarray, return count; } - - - -#ifdef PLY_BITARRAY_ENABLE_TEST -#include - -int -main (int argc, - char **argv) -{ - ply_bitarray_t *bitarray; - int i, i2; - printf ("bitarray test start\n"); - bitarray = ply_bitarray_new (134); - - for (i=0; i<64; i++) - { - if (ply_bitarray_lookup (bitarray, i)) - printf ("1"); - else - printf ("0"); - } - printf ("\n"); - - for (i=0; i<64; i++) - if ((6654654654654654654ll >> i) & 1) - ply_bitarray_set (bitarray, i); - - for (i=0; i<64; i++) - { - if (ply_bitarray_lookup (bitarray, i)) - printf ("1"); - else - printf ("0"); - } - printf ("\n"); - - for (i = 63; i > 0; i--) - { - if ((6654654654654654654ll >> i) & 1) - { - ply_bitarray_clear (bitarray, i); - for (i2 = 0; i2 < 64; i2++) - { - if (ply_bitarray_lookup (bitarray, i2)) - printf ("1"); - else - printf ("0"); - } - printf ("\n"); - } - } - - ply_bitarray_free (bitarray); - - printf ("bitarray test end\n"); - return 0; -} - -#endif /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ diff --git a/src/libply/ply-buffer.c b/src/libply/ply-buffer.c index c65634f..0d0406f 100644 --- a/src/libply/ply-buffer.c +++ b/src/libply/ply-buffer.c @@ -263,22 +263,4 @@ ply_buffer_clear (ply_buffer_t *buffer) buffer->size = 0; } -#ifdef PLY_BUFFER_ENABLE_TEST -int -main (int argc, - char **argv) -{ - int exit_code; - ply_buffer_t *buffer; - - exit_code = 0; - buffer = ply_buffer_new (); - - ply_buffer_append (buffer, "yo yo yo\n"); - ply_buffer_free (buffer); - - return exit_code; -} - -#endif /* PLY_BUFFER_ENABLE_TEST */ /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ diff --git a/src/libply/ply-command-parser.c b/src/libply/ply-command-parser.c index 6ab323b..2768668 100644 --- a/src/libply/ply-command-parser.c +++ b/src/libply/ply-command-parser.c @@ -968,100 +968,4 @@ ply_command_parser_parse_arguments (ply_command_parser_t *parser, return parsed_arguments; } -#ifdef PLY_COMMAND_PARSER_ENABLE_TEST - -#include - -#include "ply-command-parser.h" -#include "ply-event-loop.h" -#include "ply-logger.h" - -static void -on_ask_for_password (ply_command_parser_t *parser, - const char *command) -{ - char *prompt; - char *program; - - prompt = NULL; - program = NULL; - ply_command_parser_get_command_options (parser, command, "prompt", &prompt, "command", &program, NULL); - - printf ("ask for password with prompt '%s' feed result to '%s'\n", prompt, program); - free (prompt); - free (program); -} - -static void -on_show_splash (ply_command_parser_t *parser, - const char *command) -{ - char *plugin_name; - - plugin_name = NULL; - ply_command_parser_get_command_options (parser, command, "plugin-name", &plugin_name, NULL); - - printf ("show splash plugin '%s'\n", plugin_name); - free (plugin_name); -} - -int -main (int argc, - char **argv) -{ - ply_event_loop_t *loop; - ply_command_parser_t *parser; - bool should_help; - - loop = ply_event_loop_new (); - parser = ply_command_parser_new (argv[0], "Test Program"); - - ply_command_parser_add_options (parser, - "help", "This help message", PLY_COMMAND_OPTION_TYPE_FLAG, - NULL); - - ply_command_parser_add_command (parser, - "ask-for-password", - "Ask user for password", - (ply_command_handler_t) - on_ask_for_password, parser, - "command", "command to pipe result to", PLY_COMMAND_OPTION_TYPE_STRING, - "prompt", "string to present to user", PLY_COMMAND_OPTION_TYPE_STRING, - "output-result", "print result", PLY_COMMAND_OPTION_TYPE_BOOLEAN, - NULL); - - ply_command_parser_add_command (parser, - "show-splash", - "Show splash to user", - (ply_command_handler_t) - on_show_splash, parser, - "plugin-name", "name of the plugin to run", PLY_COMMAND_OPTION_TYPE_STRING, - NULL); - - if (!ply_command_parser_parse_arguments (parser, loop, argv, argc)) - { - ply_error ("couldn't parse arguments"); - return 1; - } - - - ply_command_parser_get_options (parser, "help", &should_help, NULL); - - if (should_help) - { - char *usage; - usage = ply_command_parser_get_help_string (parser); - printf ("%s\n", usage); - free (usage); - return 0; - } - - ply_event_loop_run (loop); - - ply_command_parser_free (parser); - - return 0; -} - -#endif /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ diff --git a/src/libply/ply-event-loop.c b/src/libply/ply-event-loop.c index 3cfad76..0c85cb9 100644 --- a/src/libply/ply-event-loop.c +++ b/src/libply/ply-event-loop.c @@ -491,7 +491,7 @@ ply_event_loop_new (void) loop = calloc (1, sizeof (ply_event_loop_t)); - loop->epoll_fd = epoll_create (PLY_EVENT_LOOP_NUM_EVENT_HANDLERS); + loop->epoll_fd = epoll_create1(EPOLL_CLOEXEC); loop->wakeup_time = PLY_EVENT_LOOP_NO_TIMED_WAKEUP; assert (loop->epoll_fd >= 0); @@ -1376,88 +1376,4 @@ ply_event_loop_run (ply_event_loop_t *loop) return loop->exit_code; } -#ifdef PLY_EVENT_LOOP_ENABLE_TEST - -static ply_event_loop_t *loop; - -static void -alrm_signal_handler (void) -{ - write (1, "times up!\n", sizeof ("times up!\n") - 1); - ply_event_loop_exit (loop, 0); -} - -static void -usr1_signal_handler (void) -{ - write (1, "got sigusr1\n", sizeof ("got sigusr1\n") - 1); -} - -static void -hangup_signal_handler (void) -{ - write (1, "got hangup\n", sizeof ("got hangup\n") - 1); -} - -static void -terminate_signal_handler (void) -{ - write (1, "got terminate\n", sizeof ("got terminate\n") - 1); - ply_event_loop_exit (loop, 0); -} - -static void -line_received_handler (void) -{ - char line[512] = { 0 }; - printf ("Received line: "); - fflush (stdout); - - fgets (line, sizeof (line), stdin); - printf ("%s", line); -} - -static void -on_timeout (ply_event_loop_t *loop) -{ - printf ("timeout elapsed\n"); -} - -int -main (int argc, - char **argv) -{ - int exit_code; - - loop = ply_event_loop_new (); - - ply_event_loop_watch_signal (loop, SIGHUP, - (ply_event_handler_t) hangup_signal_handler, - NULL); - ply_event_loop_watch_signal (loop, SIGTERM, - (ply_event_handler_t) - terminate_signal_handler, NULL); - ply_event_loop_watch_signal (loop, SIGUSR1, - (ply_event_handler_t) - usr1_signal_handler, NULL); - ply_event_loop_watch_signal (loop, SIGALRM, - (ply_event_handler_t) - alrm_signal_handler, NULL); - - ply_event_loop_watch_for_timeout (loop, 2.0, - (ply_event_loop_timeout_handler_t) - on_timeout, loop); - ply_event_loop_watch_fd (loop, 0, PLY_EVENT_LOOP_FD_STATUS_HAS_DATA, - (ply_event_handler_t) line_received_handler, - (ply_event_handler_t) line_received_handler, - NULL); - - alarm (5); - exit_code = ply_event_loop_run (loop); - - ply_event_loop_free (loop); - - return exit_code; -} -#endif /* PLY_EVENT_LOOP_ENABLE_TEST */ /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ diff --git a/src/libply/ply-hashtable.c b/src/libply/ply-hashtable.c index 7d8d648..7b03d87 100644 --- a/src/libply/ply-hashtable.c +++ b/src/libply/ply-hashtable.c @@ -130,14 +130,6 @@ ply_hashtable_insert_internal (ply_hashtable_t *hashtable, { unsigned int hash_index; int step = 0; - -#ifdef PLY_HASHTABLE_ENABLE_TEST - /* Make sure the counts are synchronised with bitmap */ - assert (ply_bitarray_count (hashtable->dirty_node_bitmap, hashtable->total_node_count) == - (int) hashtable->dirty_node_count); - assert (ply_bitarray_count (hashtable->live_node_bitmap, hashtable->total_node_count) == - (int) hashtable->live_node_count); -#endif /* PLY_HASHTABLE_ENABLE_TEST */ hash_index = hashtable->hash_func (key); hash_index &= hashtable->total_node_count - 1; @@ -281,56 +273,10 @@ ply_hashtable_foreach (ply_hashtable_t *hashtable, } } - -#ifdef PLY_HASHTABLE_ENABLE_TEST -#include - -static void -foreach_func (void *key, - void *data, - void *user_data) -{ - printf ("foreach key:%s data:%s\n", (char*) key, (char*) data); -} - - int -main (int argc, - char **argv) +ply_hashtable_get_size (ply_hashtable_t *hashtable) { - ply_hashtable_t *hashtable; - int i; - const char* key[10] = {"k1", "k2", "k3", "k4", "k5", "k6", "k7", "k8", "k9", "k10"}; - const char* data[10] = {"d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10"}; - char* reply_key = NULL; - char* reply_data = NULL; - - printf ("hashtable test start\n"); - hashtable = ply_hashtable_new (ply_hashtable_string_hash, ply_hashtable_string_compare); - for (i=0; i<10; i++) - { - ply_hashtable_insert (hashtable, (void *) key[i], (void *) data[9-i]); - } - for (i=0; i<10; i++) - { - reply_data = ply_hashtable_lookup (hashtable, (void *) key[i]); - printf ("got:%s\n", reply_data); - } - for (i=0; i<10; i++) - { - ply_hashtable_remove (hashtable, (void *) key[i]); - ply_hashtable_insert (hashtable, (void *) key[i], (void *) data[i]); - } - for (i=0; i<10; i++) - { - if (ply_hashtable_lookup_full (hashtable, (void *) key[i], (void**) &reply_key, (void**) &reply_data)) - printf ("got key:%s data:%s\n", reply_key, reply_data); - } - ply_hashtable_foreach (hashtable, foreach_func, NULL); - ply_hashtable_free(hashtable); - printf ("hashtable test end\n"); - return 0; + return hashtable->live_node_count; } -#endif /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ diff --git a/src/libply/ply-hashtable.h b/src/libply/ply-hashtable.h index 016c781..e7e1a6e 100644 --- a/src/libply/ply-hashtable.h +++ b/src/libply/ply-hashtable.h @@ -57,6 +57,8 @@ int ply_hashtable_lookup_full (ply_hashtable_t *hashtable, void ply_hashtable_foreach (ply_hashtable_t *hashtable, ply_hashtable_foreach_func_t func, void *user_data); + +int ply_hashtable_get_size (ply_hashtable_t *hashtable); #endif #endif /* PLY_HASHTABLE_H */ diff --git a/src/libply/ply-key-file.c b/src/libply/ply-key-file.c index a3d5a11..c62551e 100644 --- a/src/libply/ply-key-file.c +++ b/src/libply/ply-key-file.c @@ -25,6 +25,7 @@ #include "ply-key-file.h" #include +#include #include #include #include @@ -75,7 +76,7 @@ ply_key_file_open_file (ply_key_file_t *key_file) { assert (key_file != NULL); - key_file->fp = fopen (key_file->filename, "r"); + key_file->fp = fopen (key_file->filename, "re"); if (key_file->fp == NULL) { @@ -173,13 +174,18 @@ ply_key_file_load_group (ply_key_file_t *key_file, ply_key_file_entry_t *entry; char *key; char *value; - long offset; + off_t offset; int first_byte; key = NULL; value = NULL; - first_byte = fgetc (key_file->fp); + do + { + first_byte = fgetc (key_file->fp); + } + while (isspace (first_byte)); + if (first_byte == '#') { char *line_to_toss; @@ -196,13 +202,13 @@ ply_key_file_load_group (ply_key_file_t *key_file, } ungetc (first_byte, key_file->fp); - offset = ftell (key_file->fp); - items_matched = fscanf (key_file->fp, " %a[^= \t\n] = %a[^\n] ", &key, &value); + offset = ftello (key_file->fp); + items_matched = fscanf (key_file->fp, " %m[^= \t\n] = %m[^\n] ", &key, &value); if (items_matched != 2) { if (items_matched == 1) - fseek (key_file->fp, offset, SEEK_SET); + fseeko (key_file->fp, offset, SEEK_SET); free (key); free (value); @@ -254,7 +260,7 @@ ply_key_file_load_groups (ply_key_file_t *key_file) ungetc (first_byte, key_file->fp); group_name = NULL; - items_matched = fscanf (key_file->fp, " [ %a[^]] ] ", &group_name); + items_matched = fscanf (key_file->fp, " [ %m[^]] ] ", &group_name); if (items_matched <= 0) { diff --git a/src/libply/ply-list.c b/src/libply/ply-list.c index 85262ab..8c589c2 100644 --- a/src/libply/ply-list.c +++ b/src/libply/ply-list.c @@ -375,85 +375,4 @@ ply_list_node_get_data (ply_list_node_t *node) return node->data; } -#ifdef PLY_LIST_ENABLE_TEST -#include - -static int -compare_int_ptr (void *element_a, - void *element_b) -{ - int *int_a = element_a; - int *int_b = element_b; - return *int_a - *int_b; - -} - -int -main (int argc, - char **argv) -{ - ply_list_t *list; - ply_list_node_t *node; - int i, lastval; - int *value; - int errors; - - errors = 0; - - list = ply_list_new (); - - ply_list_append_data (list, (void *) "foo"); - ply_list_append_data (list, (void *) "bar"); - ply_list_append_data (list, (void *) "baz"); - ply_list_prepend_data (list, (void *) "qux"); - ply_list_prepend_data (list, (void *) "quux"); - ply_list_remove_data (list, (void *) "baz"); - ply_list_remove_data (list, (void *) "foo"); - - node = ply_list_get_first_node (list); - i = 0; - while (node != NULL) - { - printf ("node '%d' has data '%s'\n", i, - (char *) ply_list_node_get_data (node)); - node = ply_list_get_next_node (list, node); - i++; - } - - printf ("\n"); - ply_list_remove_all_nodes (list); - srandom(1); - - for (i = 0; i<100; i++) - { - value = malloc (sizeof (int)); - *value = random() % 100; - ply_list_append_data (list, (void *) value); - } - - ply_list_sort (list, compare_int_ptr); - - node = ply_list_get_first_node (list); - i = 0; - lastval = 0; - - while (node != NULL) - { - value = (int *) ply_list_node_get_data (node); - if (*value < lastval) - { - printf ("ERROR: incorrect order\n"); - errors = 1; - } - lastval = *value; - printf ("node '%d' has data '%d'\n", i, *value); - node = ply_list_get_next_node (list, node); - i++; - } - - ply_list_free (list); - return errors; -} - -#endif /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ diff --git a/src/libply/ply-logger.c b/src/libply/ply-logger.c index f51bb84..740c30e 100644 --- a/src/libply/ply-logger.c +++ b/src/libply/ply-logger.c @@ -40,7 +40,7 @@ #include "ply-list.h" #ifndef PLY_LOGGER_OPEN_FLAGS -#define PLY_LOGGER_OPEN_FLAGS (O_WRONLY | O_TRUNC | O_CREAT | O_NOFOLLOW) +#define PLY_LOGGER_OPEN_FLAGS (O_WRONLY | O_TRUNC | O_CREAT | O_NOFOLLOW | O_CLOEXEC) #endif #ifndef PLY_LOGGER_MAX_INJECTION_SIZE @@ -357,6 +357,9 @@ ply_logger_close_file (ply_logger_t *logger) { assert (logger != NULL); + if (logger->output_fd < 0) + return; + close (logger->output_fd); ply_logger_set_output_fd (logger, -1); } @@ -595,26 +598,4 @@ ply_logger_is_tracing_enabled (ply_logger_t *logger) } #endif /* PLY_ENABLE_TRACING */ -#ifdef PLY_LOGGER_ENABLE_TEST - -int -main (int argc, - char **argv) -{ - int exit_code; - ply_logger_t *logger; - - exit_code = 0; - logger = ply_logger_new (); - - ply_logger_inject (logger, "yo yo yo\n"); - ply_logger_set_output_fd (logger, 1); - ply_logger_inject (logger, "yo yo yo yo\n"); - ply_logger_flush (logger); - ply_logger_free (logger); - - return exit_code; -} - -#endif /* PLY_LOGGER_ENABLE_TEST */ /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ diff --git a/src/libply/ply-logger.h b/src/libply/ply-logger.h index 36fe7d1..596bed5 100644 --- a/src/libply/ply-logger.h +++ b/src/libply/ply-logger.h @@ -91,8 +91,8 @@ do \ ply_logger_flush (logger); \ errno = _old_errno; \ ply_logger_inject (logger, \ - "[%s] %45.45s:" format "\r\n", \ - __FILE__, __func__, ##args); \ + "[%s:%d] %45.45s:" format "\r\n", \ + __FILE__, __LINE__, __func__, ##args); \ ply_logger_flush (logger); \ errno = _old_errno; \ } \ diff --git a/src/libply/ply-progress.c b/src/libply/ply-progress.c index 2091a27..4a16556 100644 --- a/src/libply/ply-progress.c +++ b/src/libply/ply-progress.c @@ -22,6 +22,10 @@ * Charlie Brej */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include @@ -212,9 +216,14 @@ ply_progress_save_cache (ply_progress_t* progress, ply_list_node_t *node; double cur_time = ply_progress_get_time(progress); + ply_trace ("saving progress cache to %s", filename); + fp = fopen (filename,"w"); if (fp == NULL) - return; + { + ply_trace ("failed to save cache: %m"); + return; + } node = ply_list_get_first_node (progress->current_message_list); @@ -326,75 +335,5 @@ ply_progress_status_update (ply_progress_t* progress, } } -#ifdef PLY_PROGRESS_ENABLE_TEST - -#include - -int -main (int argc, - char **argv) -{ - double percent; - int slowness; - double time; - int i; - const char* strings[10]={"foobar", "barfoo", "barbar", "foo", "foo", "bar", "foo", "more", "even more", "even even more"}; - ply_progress_t* progress = ply_progress_new (); - - progress->scalar = 1.0/5; /* Original time estimate is 5 sec*/ - - percent = ply_progress_get_percentage (progress); - time = ply_progress_get_time (progress); - printf("Time:%f \t Percentage: %f%%\n", time, percent*100); - srand ((int) ply_get_timestamp ()); - - slowness = rand () % 500000 + 50000; - - for (i=0; i<2; i++) - { - usleep ((rand () % slowness+slowness)); - percent = ply_progress_get_percentage (progress); - time = ply_progress_get_time (progress); - printf("Time:%f \t Percentage: %f%%\n", time, percent*100); - } - printf("Load cache\n"); - ply_progress_load_cache (progress, PLYMOUTH_TIME_DIRECTORY "/boot-duration"); - - for (i=0; i<10; i++) - { - ply_progress_status_update (progress, strings[i]); - usleep ((rand () % slowness+slowness)); - percent = ply_progress_get_percentage (progress); - time = ply_progress_get_time (progress); - printf("Time:%f \t Percentage: %f%% \tScalar:%f\n", time, percent*100, progress->scalar); - } - printf("Save and free cache\n"); - ply_progress_save_cache (progress, PLYMOUTH_TIME_DIRECTORY "/boot-duration"); - ply_progress_free(progress); - - printf("\nManual set percentage run\n\n"); - - progress = ply_progress_new (); - progress->scalar = 1.0/5; /* Original time estimate is 5 sec*/ - - percent = ply_progress_get_percentage (progress); - time = ply_progress_get_time (progress); - printf("Time:%f \t Percentage: %f%%\n", time, percent*100); - srand ((int) ply_get_timestamp ()); - - for (i=0; i<12; i++) - { - ply_progress_set_percentage (progress, (double)i/12); - usleep ((rand () % slowness+slowness)); - percent = ply_progress_get_percentage (progress); - time = ply_progress_get_time (progress); - printf("Time:%f \t Percentage: %f%% (%f%%)\tScalar:%f\n", time, percent*100, (double)i/12*100, progress->scalar); - } - ply_progress_free(progress); - - return 0; -} - -#endif /* PLY_PROGRESS_ENABLE_TEST */ /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ diff --git a/src/libply/ply-region.c b/src/libply/ply-region.c index cbaca40..92d3574 100644 --- a/src/libply/ply-region.c +++ b/src/libply/ply-region.c @@ -467,141 +467,4 @@ ply_region_get_sorted_rectangle_list (ply_region_t *region) return region->rectangle_list; } -#ifdef PLY_REGION_ENABLE_TEST -#include - -#define COVER_SIZE 100 -#define RECTANGLE_COUNT 1000 - -static void -cover_with_rect(char cover[COVER_SIZE][COVER_SIZE], - ply_rectangle_t *rectangle, - char value) -{ /* is value is not zero, the entry will be set to the value, - otherwise entry is incremented*/ - unsigned long x, y; - for (y=0; yheight; y++) - { - for (x=0; xwidth; x++) - { - if (rectangle->x + x < COVER_SIZE && - rectangle->y + y < COVER_SIZE) - { - if (value) - cover[rectangle->y + y][rectangle->x + x] = value; - else - cover[rectangle->y + y][rectangle->x + x]++; - } - } - } -} - -static int -do_test (void) -{ - ply_rectangle_t rectangle; - char cover[COVER_SIZE][COVER_SIZE]; - int i; - unsigned long x, y; - ply_region_t *region; - ply_list_node_t *node; - - region = ply_region_new (); - - for (y = 0; y < COVER_SIZE; y++) - { - for (x = 0; x < COVER_SIZE; x++) - { - cover[y][x] = 0; - } - } - - for (i = 0; i < RECTANGLE_COUNT; i++) - { - rectangle.x = random() % COVER_SIZE-5; - rectangle.y = random() % COVER_SIZE-5; - rectangle.width = 1 + random() % 20; - rectangle.height = 1 + random() % 20; - printf("Adding X=%ld Y=%ld W=%ld H=%ld\n", - rectangle.x, - rectangle.y, - rectangle.width, - rectangle.height); - cover_with_rect(cover, &rectangle, 100); /* 100 means covered by origial squares */ - ply_region_add_rectangle (region, &rectangle); - } - - printf("Converted to:\n"); - int count = 0; - - ply_list_t *rectangle_list = ply_region_get_rectangle_list (region); - for (node = ply_list_get_first_node (rectangle_list); - node; - node = ply_list_get_next_node (rectangle_list, node)) - { - ply_rectangle_t *small_rectangle = ply_list_node_get_data (node); - printf("Processed X=%ld Y=%ld W=%ld H=%ld\n", - small_rectangle->x, - small_rectangle->y, - small_rectangle->width, - small_rectangle->height); - cover_with_rect(cover, small_rectangle, 0); - count++; - } - printf("Rectangles in:%d out:%d\n", RECTANGLE_COUNT, count); - - count=0; - - for (y = 0; y < COVER_SIZE; y++) - { - printf("%03ld ", y); - for (x = 0; x < COVER_SIZE; x++) - { - if (cover[y][x] >= 100) - { - if (cover[y][x] == 100) - { - printf("-"); /* "-" means should have been covered but wasn't */ - count++; - } - else - { - if (cover[y][x] == 101) - printf("O"); /* "O" means correctly covered */ - else - { - printf("%d", cover[y][x] - 101); - count++; /* 1+ means covered multiple times*/ - } - } - } - else - { - if (cover[y][x] == 0) - printf("o"); /* "o" means not involved*/ - else - { - printf("%c", 'A' - 1 + cover[y][x]); - count++; /* A+ means covered despite being not involved*/ - } - } - } - printf("\n"); - } - printf("errors:%d\n", count); - return count; -} -int -main (int argc, - char **argv) -{ - int i; - srandom(312); - for (i=0; i<100; i++) - { - if (do_test ()) return 1; - } - return 0; -} -#endif /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ diff --git a/src/libply/ply-terminal-session.c b/src/libply/ply-terminal-session.c index 3d43709..379035c 100644 --- a/src/libply/ply-terminal-session.c +++ b/src/libply/ply-terminal-session.c @@ -148,7 +148,8 @@ ply_terminal_session_free (ply_terminal_session_t *session) ply_free_string_array (session->argv); - close (session->pseudoterminal_master_fd); + if (session->pseudoterminal_master_fd >= 0) + close (session->pseudoterminal_master_fd); free (session); } @@ -213,8 +214,12 @@ ply_terminal_session_unredirect_console (ply_terminal_session_t *session) assert (session->console_is_redirected); fd = open ("/dev/console", O_RDWR | O_NOCTTY); - if (fd >= 0) + if (fd >= 0) { ioctl (fd, TIOCCONS); + close (fd); + } else { + ply_trace ("couldn't open /dev/console to stop redirecting it: %m"); + } session->console_is_redirected = false; } @@ -582,57 +587,4 @@ ply_terminal_session_close_log (ply_terminal_session_t *session) return ply_logger_close_file (session->logger); } -#ifdef PLY_TERMINAL_SESSION_ENABLE_TEST - -#include - -#include "ply-event-loop.h" -#include "ply-terminal-session.h" - -static void -on_finished (ply_event_loop_t *loop) -{ - ply_event_loop_exit (loop, 0); -} - -int -main (int argc, - char **argv) -{ - ply_event_loop_t *loop; - ply_terminal_session_t *session; - int exit_code; - ply_terminal_session_flags_t flags; - - exit_code = 0; - - loop = ply_event_loop_new (); - - session = ply_terminal_session_new ((const char * const *) (argv + 1)); - - flags = PLY_TERMINAL_SESSION_FLAGS_RUN_IN_PARENT; - flags |= PLY_TERMINAL_SESSION_FLAGS_LOOK_IN_PATH; - - ply_terminal_session_attach_to_event_loop (session, loop); - - if (!ply_terminal_session_run (session, flags, - (ply_terminal_session_begin_handler_t) NULL, - (ply_terminal_session_output_handler_t) NULL, - (ply_terminal_session_hangup_handler_t) - on_finished, loop)) - { - perror ("could not start terminal session"); - return errno; - } - - ply_terminal_session_open_log (session, "foo.log"); - - exit_code = ply_event_loop_run (loop); - - ply_terminal_session_free (session); - - return exit_code; -} - -#endif /* PLY_TERMINAL_SESSION_ENABLE_TEST */ /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ diff --git a/src/libply/ply-utils.c b/src/libply/ply-utils.c index 60d59d1..8333485 100644 --- a/src/libply/ply-utils.c +++ b/src/libply/ply-utils.c @@ -87,27 +87,9 @@ ply_open_unidirectional_pipe (int *sender_fd, assert (sender_fd != NULL); assert (receiver_fd != NULL); - if (pipe (pipe_fds) < 0) + if (pipe2 (pipe_fds, O_CLOEXEC) < 0) return false; - if (fcntl (pipe_fds[0], F_SETFD, O_NONBLOCK | FD_CLOEXEC) < 0) - { - ply_save_errno (); - close (pipe_fds[0]); - close (pipe_fds[1]); - ply_restore_errno (); - return false; - } - - if (fcntl (pipe_fds[1], F_SETFD, O_NONBLOCK | FD_CLOEXEC) < 0) - { - ply_save_errno (); - close (pipe_fds[0]); - close (pipe_fds[1]); - ply_restore_errno (); - return false; - } - *sender_fd = pipe_fds[1]; *receiver_fd = pipe_fds[0]; @@ -120,20 +102,11 @@ ply_open_unix_socket (void) int fd; const int should_pass_credentials = true; - fd = socket (PF_UNIX, SOCK_STREAM, 0); + fd = socket (PF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); if (fd < 0) return -1; - if (fcntl (fd, F_SETFD, O_NONBLOCK | FD_CLOEXEC) < 0) - { - ply_save_errno (); - close (fd); - ply_restore_errno (); - - return -1; - } - if (setsockopt (fd, SOL_SOCKET, SO_PASSCRED, &should_pass_credentials, sizeof (should_pass_credentials)) < 0) { @@ -822,11 +795,12 @@ ply_create_daemon (void) if (!ply_read (receiver_fd, &byte, sizeof (uint8_t))) { + int read_error = errno; int status; if (waitpid (pid, &status, WNOHANG) <= 0) { - ply_error ("failed to read status from child immediately after starting to daemonize"); + ply_error ("failed to read status from child immediately after starting to daemonize: %s", strerror (read_error)); } else if (WIFEXITED (status)) { @@ -971,7 +945,7 @@ ply_get_process_parent_pid (pid_t pid) asprintf (&path, "/proc/%ld/stat", (long) pid); ppid = 0; - fp = fopen (path, "r"); + fp = fopen (path, "re"); if (fp == NULL) { diff --git a/src/libply/tests/Makefile.am b/src/libply/tests/Makefile.am deleted file mode 100644 index bc4da58..0000000 --- a/src/libply/tests/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -INCLUDES = \ - -I$(top_srcdir) \ - -I$(srcdir)/.. \ - -I$(srcdir) -TESTS = - -if ENABLE_TESTS -include $(srcdir)/ply-terminal-session-test.am -include $(srcdir)/ply-logger-test.am -include $(srcdir)/ply-array-test.am -include $(srcdir)/ply-bitarray-test.am -include $(srcdir)/ply-list-test.am -include $(srcdir)/ply-hashtable-test.am -include $(srcdir)/ply-event-loop-test.am -include $(srcdir)/ply-command-parser-test.am -include $(srcdir)/ply-progress-test.am -include $(srcdir)/ply-region.am -endif - -noinst_PROGRAMS = $(TESTS) - -# Our tests aren't unit tests so clear for now -TESTS = - -MAINTAINERCLEANFILES = Makefile.in diff --git a/src/libply/tests/ply-array-test.am b/src/libply/tests/ply-array-test.am deleted file mode 100644 index 4f8ecc4..0000000 --- a/src/libply/tests/ply-array-test.am +++ /dev/null @@ -1,16 +0,0 @@ -TESTS += ply-array-test - -ply_array_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_ARRAY_ENABLE_TEST -ply_array_test_LDADD = $(PLYMOUTH_LIBS) - -ply_array_test_SOURCES = \ - $(srcdir)/../ply-buffer.h \ - $(srcdir)/../ply-buffer.c \ - $(srcdir)/../ply-list.h \ - $(srcdir)/../ply-list.c \ - $(srcdir)/../ply-logger.h \ - $(srcdir)/../ply-logger.c \ - $(srcdir)/../ply-utils.h \ - $(srcdir)/../ply-utils.c \ - $(srcdir)/../ply-array.h \ - $(srcdir)/../ply-array.c diff --git a/src/libply/tests/ply-bitarray-test.am b/src/libply/tests/ply-bitarray-test.am deleted file mode 100644 index 85c3608..0000000 --- a/src/libply/tests/ply-bitarray-test.am +++ /dev/null @@ -1,8 +0,0 @@ -TESTS += ply-bitarray-test - -ply_bitarray_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_BITARRAY_ENABLE_TEST -ply_bitarray_test_LDADD = $(PLYMOUTH_LIBS) - -ply_bitarray_test_SOURCES = \ - $(srcdir)/../ply-bitarray.h \ - $(srcdir)/../ply-bitarray.c diff --git a/src/libply/tests/ply-command-parser-test.am b/src/libply/tests/ply-command-parser-test.am deleted file mode 100644 index 91649d5..0000000 --- a/src/libply/tests/ply-command-parser-test.am +++ /dev/null @@ -1,18 +0,0 @@ -TESTS += ply-command-parser-test - -ply_command_parser_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_COMMAND_PARSER_ENABLE_TEST -ply_command_parser_test_LDADD = $(PLYMOUTH_LIBS) - -ply_command_parser_test_SOURCES = \ - $(srcdir)/../ply-buffer.h \ - $(srcdir)/../ply-buffer.c \ - $(srcdir)/../ply-event-loop.h \ - $(srcdir)/../ply-event-loop.c \ - $(srcdir)/../ply-list.h \ - $(srcdir)/../ply-list.c \ - $(srcdir)/../ply-logger.h \ - $(srcdir)/../ply-logger.c \ - $(srcdir)/../ply-utils.h \ - $(srcdir)/../ply-utils.c \ - $(srcdir)/../ply-command-parser.h \ - $(srcdir)/../ply-command-parser.c diff --git a/src/libply/tests/ply-event-loop-test.am b/src/libply/tests/ply-event-loop-test.am deleted file mode 100644 index c666ea6..0000000 --- a/src/libply/tests/ply-event-loop-test.am +++ /dev/null @@ -1,14 +0,0 @@ -TESTS += ply-event-loop-test - -ply_event_loop_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_EVENT_LOOP_ENABLE_TEST -ply_event_loop_test_LDADD = $(PLYMOUTH_LIBS) - -ply_event_loop_test_SOURCES = \ - $(srcdir)/../ply-utils.h \ - $(srcdir)/../ply-utils.c \ - $(srcdir)/../ply-list.h \ - $(srcdir)/../ply-list.c \ - $(srcdir)/../ply-logger.h \ - $(srcdir)/../ply-logger.c \ - $(srcdir)/../ply-event-loop.h \ - $(srcdir)/../ply-event-loop.c diff --git a/src/libply/tests/ply-hashtable-test.am b/src/libply/tests/ply-hashtable-test.am deleted file mode 100644 index d3410fc..0000000 --- a/src/libply/tests/ply-hashtable-test.am +++ /dev/null @@ -1,10 +0,0 @@ -TESTS += ply-hashtable-test - -ply_hashtable_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_HASHTABLE_ENABLE_TEST -ply_hashtable_test_LDADD = $(PLYMOUTH_LIBS) - -ply_hashtable_test_SOURCES = \ - $(srcdir)/../ply-hashtable.h \ - $(srcdir)/../ply-hashtable.c \ - $(srcdir)/../ply-bitarray.h \ - $(srcdir)/../ply-bitarray.c diff --git a/src/libply/tests/ply-list-test.am b/src/libply/tests/ply-list-test.am deleted file mode 100644 index 8beb578..0000000 --- a/src/libply/tests/ply-list-test.am +++ /dev/null @@ -1,8 +0,0 @@ -TESTS += ply-list-test - -ply_list_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_LIST_ENABLE_TEST -ply_list_test_LDADD = $(PLYMOUTH_LIBS) - -ply_list_test_SOURCES = \ - $(srcdir)/../ply-list.h \ - $(srcdir)/../ply-list.c diff --git a/src/libply/tests/ply-logger-test.am b/src/libply/tests/ply-logger-test.am deleted file mode 100644 index a589fb9..0000000 --- a/src/libply/tests/ply-logger-test.am +++ /dev/null @@ -1,12 +0,0 @@ -TESTS += ply-logger-test - -ply_logger_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_LOGGER_ENABLE_TEST -ply_logger_test_LDADD = $(PLYMOUTH_LIBS) - -ply_logger_test_SOURCES = \ - $(srcdir)/../ply-list.h \ - $(srcdir)/../ply-list.c \ - $(srcdir)/../ply-utils.h \ - $(srcdir)/../ply-utils.c \ - $(srcdir)/../ply-logger.h \ - $(srcdir)/../ply-logger.c diff --git a/src/libply/tests/ply-progress-test.am b/src/libply/tests/ply-progress-test.am deleted file mode 100644 index 6279fac..0000000 --- a/src/libply/tests/ply-progress-test.am +++ /dev/null @@ -1,15 +0,0 @@ -TESTS += ply-progress-test - -ply_progress_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_PROGRESS_ENABLE_TEST \ - -DPLYMOUTH_TIME_DIRECTORY=\"$(localstatedir)/lib/plymouth/\" -ply_progress_test_LDADD = $(PLYMOUTH_LIBS) - -ply_progress_test_SOURCES = \ - $(srcdir)/../ply-progress.h \ - $(srcdir)/../ply-progress.c \ - $(srcdir)/../ply-list.h \ - $(srcdir)/../ply-list.c \ - $(srcdir)/../ply-logger.h \ - $(srcdir)/../ply-logger.c \ - $(srcdir)/../ply-utils.h \ - $(srcdir)/../ply-utils.c diff --git a/src/libply/tests/ply-region.am b/src/libply/tests/ply-region.am deleted file mode 100644 index 1883833..0000000 --- a/src/libply/tests/ply-region.am +++ /dev/null @@ -1,12 +0,0 @@ -TESTS += ply-region-test - -ply_region_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_REGION_ENABLE_TEST -ply_region_test_LDADD = $(PLYMOUTH_LIBS) - -ply_region_test_SOURCES = \ - $(srcdir)/../ply-region.h \ - $(srcdir)/../ply-region.c \ - $(srcdir)/../ply-rectangle.h \ - $(srcdir)/../ply-rectangle.c \ - $(srcdir)/../ply-list.h \ - $(srcdir)/../ply-list.c diff --git a/src/libply/tests/ply-terminal-session-test.am b/src/libply/tests/ply-terminal-session-test.am deleted file mode 100644 index decb531..0000000 --- a/src/libply/tests/ply-terminal-session-test.am +++ /dev/null @@ -1,18 +0,0 @@ -TESTS += ply-terminal-session-test - -ply_terminal_session_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_TERMINAL_SESSION_ENABLE_TEST -ply_terminal_session_test_LDADD = $(PLYMOUTH_LIBS) - -ply_terminal_session_test_SOURCES = \ - $(srcdir)/../ply-utils.h \ - $(srcdir)/../ply-utils.c \ - $(srcdir)/../ply-buffer.h \ - $(srcdir)/../ply-buffer.c \ - $(srcdir)/../ply-logger.h \ - $(srcdir)/../ply-logger.c \ - $(srcdir)/../ply-list.h \ - $(srcdir)/../ply-list.c \ - $(srcdir)/../ply-event-loop.h \ - $(srcdir)/../ply-event-loop.c \ - $(srcdir)/../ply-terminal-session.h \ - $(srcdir)/../ply-terminal-session.c diff --git a/src/main.c b/src/main.c index 88e5002..c3daac0 100644 --- a/src/main.c +++ b/src/main.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -35,6 +36,7 @@ #include #include #include +#include #include #include @@ -43,10 +45,12 @@ #include "ply-command-parser.h" #include "ply-boot-server.h" #include "ply-boot-splash.h" +#include "ply-device-manager.h" #include "ply-event-loop.h" #include "ply-hashtable.h" #include "ply-list.h" #include "ply-logger.h" +#include "ply-renderer.h" #include "ply-terminal-session.h" #include "ply-trigger.h" #include "ply-utils.h" @@ -84,9 +88,6 @@ typedef struct { ply_event_loop_t *loop; ply_boot_server_t *boot_server; - ply_list_t *pixel_displays; - ply_list_t *text_displays; - ply_keyboard_t *keyboard; ply_boot_splash_t *boot_splash; ply_terminal_session_t *session; ply_buffer_t *boot_buffer; @@ -97,12 +98,15 @@ typedef struct ply_list_t *messages; ply_command_parser_t *command_parser; ply_mode_t mode; - ply_renderer_t *renderer; ply_terminal_t *local_console_terminal; + ply_device_manager_t *device_manager; ply_trigger_t *deactivate_trigger; ply_trigger_t *quit_trigger; + double start_time; + double splash_delay; + char kernel_command_line[PLY_MAX_COMMAND_LINE_SIZE]; uint32_t kernel_command_line_is_set : 1; uint32_t no_boot_log : 1; @@ -113,9 +117,9 @@ typedef struct uint32_t should_be_attached : 1; uint32_t should_retain_splash : 1; uint32_t is_inactive : 1; + uint32_t is_shown : 1; uint32_t should_force_details : 1; - char *kernel_console_tty; char *override_splash_path; char *system_default_splash_path; char *distribution_default_splash_path; @@ -124,15 +128,15 @@ typedef struct int number_of_errors; } state_t; -static ply_boot_splash_t *start_boot_splash (state_t *state, - const char *theme_path, - bool fall_back_if_neccessary); - -static void add_display_and_keyboard_for_terminal (state_t *state, - ply_terminal_t *terminal); - -static void add_default_displays_and_keyboard (state_t *state); +static void show_splash (state_t *state); +static ply_boot_splash_t *load_built_in_theme (state_t *state); +static ply_boot_splash_t *load_theme (state_t *state, + const char *theme_path); +static ply_boot_splash_t *show_theme (state_t *state, + const char *theme_path); +static void attach_splash_to_seats (state_t *state, + ply_boot_splash_t *splash); static bool attach_to_running_session (state_t *state); static void detach_from_running_session (state_t *state); static void on_escape_pressed (state_t *state); @@ -145,12 +149,19 @@ static void on_error_message (ply_buffer_t *debug_buffer, static ply_buffer_t *debug_buffer; static char *debug_buffer_path = NULL; static char *pid_file = NULL; -static void check_for_consoles (state_t *state, - const char *default_tty, - bool should_add_displays); static void toggle_between_splash_and_details (state_t *state); +#ifdef PLY_ENABLE_SYSTEMD_INTEGRATION static void tell_systemd_to_print_details (state_t *state); static void tell_systemd_to_stop_printing_details (state_t *state); +#endif +static const char * get_cache_file_for_mode (ply_mode_t mode); +static void on_escape_pressed (state_t *state); +static void on_enter (state_t *state, + const char *line); +static void on_keyboard_input (state_t *state, + const char *keyboard_input, + size_t character_size); +static void on_backspace (state_t *state); static void on_session_output (state_t *state, @@ -249,21 +260,68 @@ show_messages (state_t *state) } } +static bool +load_settings (state_t *state, + const char *path, + char **theme_path) +{ + ply_key_file_t *key_file = NULL; + const char *delay_string; + bool settings_loaded = false; + const char *splash_string; + + ply_trace ("Trying to load %s", path); + key_file = ply_key_file_new (path); + + if (!ply_key_file_load (key_file)) + goto out; + + splash_string = ply_key_file_get_value (key_file, "Daemon", "Theme"); + + if (splash_string == NULL) + goto out; + + asprintf (theme_path, + PLYMOUTH_THEME_PATH "%s/%s.plymouth", + splash_string, splash_string); + + if (isnan (state->splash_delay)) + { + delay_string = ply_key_file_get_value (key_file, "Daemon", "ShowDelay"); + + if (delay_string != NULL) + { + state->splash_delay = atof (delay_string); + ply_trace ("Splash delay is set to %lf", state->splash_delay); + } + } + + settings_loaded = true; +out: + ply_key_file_free (key_file); + + return settings_loaded; +} + static void show_detailed_splash (state_t *state) { + ply_boot_splash_t *splash; + if (state->boot_splash != NULL) return; ply_trace ("Showing detailed splash screen"); - state->boot_splash = start_boot_splash (state, - PLYMOUTH_THEME_PATH "details/details.plymouth", - true); + splash = show_theme (state, NULL); - if (state->boot_splash == NULL) + if (splash == NULL) { ply_trace ("Could not start detailed splash screen, this could be a problem."); + return; } + + state->boot_splash = splash; + update_display (state); } static const char * @@ -326,64 +384,46 @@ find_override_splash (state_t *state) PLYMOUTH_THEME_PATH "%*.*s/%*.*s.plymouth", length, length, splash_string, length, length, splash_string); } + + if (isnan (state->splash_delay)) + { + const char *delay_string; + + delay_string = command_line_get_string_after_prefix (state->kernel_command_line, "plymouth.splash-delay="); + + if (delay_string != NULL) + state->splash_delay = atof (delay_string); + } } static void find_system_default_splash (state_t *state) { - ply_key_file_t *key_file; - char *splash_string; - if (state->system_default_splash_path != NULL) return; - ply_trace ("Trying to load " PLYMOUTH_CONF_DIR "plymouthd.conf"); - key_file = ply_key_file_new (PLYMOUTH_CONF_DIR "plymouthd.conf"); - - if (!ply_key_file_load (key_file)) + if (!load_settings (state, PLYMOUTH_CONF_DIR "plymouthd.conf", &state->system_default_splash_path)) { ply_trace ("failed to load " PLYMOUTH_CONF_DIR "plymouthd.conf"); - ply_key_file_free (key_file); return; } - splash_string = ply_key_file_get_value (key_file, "Daemon", "Theme"); - - ply_trace ("System default splash is configured to be '%s'", splash_string); - - asprintf (&state->system_default_splash_path, - PLYMOUTH_THEME_PATH "%s/%s.plymouth", - splash_string, splash_string); - free (splash_string); + ply_trace ("System configured theme file is '%s'", state->system_default_splash_path); } static void find_distribution_default_splash (state_t *state) { - ply_key_file_t *key_file; - char *splash_string; - if (state->distribution_default_splash_path != NULL) return; - ply_trace ("Trying to load " PLYMOUTH_POLICY_DIR "plymouthd.defaults"); - key_file = ply_key_file_new (PLYMOUTH_POLICY_DIR "plymouthd.defaults"); - - if (!ply_key_file_load (key_file)) + if (!load_settings (state, PLYMOUTH_POLICY_DIR "plymouthd.defaults", &state->distribution_default_splash_path)) { ply_trace ("failed to load " PLYMOUTH_POLICY_DIR "plymouthd.defaults"); - ply_key_file_free (key_file); return; } - splash_string = ply_key_file_get_value (key_file, "Daemon", "Theme"); - - ply_trace ("Distribution default splash is configured to be '%s'", splash_string); - - asprintf (&state->distribution_default_splash_path, - PLYMOUTH_THEME_PATH "%s/%s.plymouth", - splash_string, splash_string); - free (splash_string); + ply_trace ("Distribution default theme file is '%s'", state->distribution_default_splash_path); } static void @@ -393,63 +433,66 @@ show_default_splash (state_t *state) return; ply_trace ("Showing splash screen"); - find_override_splash (state); if (state->override_splash_path != NULL) { ply_trace ("Trying override splash at '%s'", state->override_splash_path); - state->boot_splash = start_boot_splash (state, - state->override_splash_path, - false); + state->boot_splash = show_theme (state, state->override_splash_path); } - find_system_default_splash (state); if (state->boot_splash == NULL && state->system_default_splash_path != NULL) { ply_trace ("Trying system default splash"); - state->boot_splash = start_boot_splash (state, - state->system_default_splash_path, - false); + state->boot_splash = show_theme (state, state->system_default_splash_path); } - find_distribution_default_splash (state); if (state->boot_splash == NULL && state->distribution_default_splash_path != NULL) { ply_trace ("Trying distribution default splash"); - state->boot_splash = start_boot_splash (state, - state->distribution_default_splash_path, - false); + state->boot_splash = show_theme (state, state->distribution_default_splash_path); } if (state->boot_splash == NULL) { ply_trace ("Trying old scheme for default splash"); - state->boot_splash = start_boot_splash (state, - PLYMOUTH_THEME_PATH "default.plymouth", - false); + state->boot_splash = show_theme (state, PLYMOUTH_THEME_PATH "default.plymouth"); } if (state->boot_splash == NULL) { ply_trace ("Could not start default splash screen," "showing text splash screen"); - state->boot_splash = start_boot_splash (state, - PLYMOUTH_THEME_PATH "text/text.plymouth", - false); + state->boot_splash = show_theme (state, PLYMOUTH_THEME_PATH "text/text.plymouth"); } if (state->boot_splash == NULL) { ply_trace ("Could not start text splash screen," - "showing built-in fallback"); - state->boot_splash = start_boot_splash (state, - PLYMOUTH_THEME_PATH "text/text.plymouth", - true); + "showing built-in splash screen"); + state->boot_splash = show_theme (state, NULL); } if (state->boot_splash == NULL) - ply_error ("plymouthd: could not start boot splash: %m"); + { + ply_error ("plymouthd: could not start boot splash: %m"); + return; + } + + update_display (state); +} + +static void +cancel_pending_delayed_show (state_t *state) +{ + if (isnan (state->splash_delay)) + return; + + ply_event_loop_stop_watching_for_timeout (state->loop, + (ply_event_loop_timeout_handler_t) + show_splash, + state); + state->splash_delay = NAN; } static void @@ -459,13 +502,36 @@ on_ask_for_password (state_t *state, { ply_entry_trigger_t *entry_trigger; - /* No splash, client will have to get password - */ if (state->boot_splash == NULL) { - ply_trace ("no splash loaded, replying immediately with no password"); - ply_trigger_pull (answer, NULL); - return; + /* Waiting to be shown, boot splash will + * arrive shortly so just sit tight + */ + if (state->is_shown) + { + bool has_open_seats; + + cancel_pending_delayed_show (state); + + has_open_seats = ply_device_manager_has_open_seats (state->device_manager); + + if (has_open_seats) + { + ply_trace ("seats open now, showing splash immediately"); + show_splash (state); + } + else + { + ply_trace ("splash still coming up, waiting a bit"); + } + } + else + { + /* No splash, client will have to get password */ + ply_trace ("no splash loaded, replying immediately with no password"); + ply_trigger_pull (answer, NULL); + return; + } } entry_trigger = calloc (1, sizeof (ply_entry_trigger_t)); @@ -587,17 +653,11 @@ static void on_newroot (state_t *state, const char *root_dir) { - if (state->mode != PLY_MODE_BOOT) - { - ply_trace ("new root is only supported in boot mode "); - return; - } - ply_trace ("new root mounted at \"%s\", switching to it", root_dir); chdir(root_dir); chroot("."); chdir("/"); - ply_progress_load_cache (state->progress, BOOT_DURATION_FILE); + ply_progress_load_cache (state->progress, get_cache_file_for_mode (state->mode)); if (state->boot_splash != NULL) ply_boot_splash_root_mounted (state->boot_splash); } @@ -619,7 +679,7 @@ get_cache_file_for_mode (ply_mode_t mode) filename = NULL; break; default: - fprintf (stderr, "Unhandled case in %s line %d\n", __FILE__, __LINE__); + ply_error ("Unhandled case in %s line %d\n", __FILE__, __LINE__); abort (); break; } @@ -629,21 +689,24 @@ get_cache_file_for_mode (ply_mode_t mode) } static const char * -get_log_file_for_mode (ply_mode_t mode) +get_log_file_for_state (state_t *state) { const char *filename; - switch ((int)mode) + switch ((int)state->mode) { case PLY_MODE_BOOT: - filename = PLYMOUTH_LOG_DIRECTORY "/boot.log"; + if (state->no_boot_log) + filename = NULL; + else + filename = PLYMOUTH_LOG_DIRECTORY "/boot.log"; break; case PLY_MODE_SHUTDOWN: case PLY_MODE_UPDATES: filename = _PATH_DEVNULL; break; default: - fprintf (stderr, "Unhandled case in %s line %d\n", __FILE__, __LINE__); + ply_error ("Unhandled case in %s line %d\n", __FILE__, __LINE__); abort (); break; } @@ -667,7 +730,7 @@ get_log_spool_file_for_mode (ply_mode_t mode) filename = NULL; break; default: - fprintf (stderr, "Unhandled case in %s line %d\n", __FILE__, __LINE__); + ply_error ("Unhandled case in %s line %d\n", __FILE__, __LINE__); abort (); break; } @@ -684,7 +747,7 @@ spool_error (state_t *state) ply_trace ("spooling error for viewer"); - logfile = get_log_file_for_mode (state->mode); + logfile = get_log_file_for_state (state); logspool = get_log_spool_file_for_mode (state->mode); if (logfile != NULL && logspool != NULL) @@ -712,11 +775,16 @@ prepare_logging (state_t *state) return; } - logfile = get_log_file_for_mode (state->mode); + logfile = get_log_file_for_state (state); if (logfile != NULL) { + bool log_opened; ply_trace ("opening log '%s'", logfile); - ply_terminal_session_open_log (state->session, logfile); + + log_opened = ply_terminal_session_open_log (state->session, logfile); + + if (!log_opened) + ply_trace ("failed to open log: %m"); if (state->number_of_errors > 0) spool_error (state); @@ -821,55 +889,15 @@ plymouth_should_show_default_splash (state_t *state) } static void -remove_displays_and_keyboard (state_t *state) +on_show_splash (state_t *state) { - ply_list_node_t *node; - ply_trace ("removing displays and keyboard"); - - node = ply_list_get_first_node (state->pixel_displays); - while (node != NULL) - { - ply_list_node_t *next_node; - ply_pixel_display_t *display; - - ply_trace ("removing pixel display"); - next_node = ply_list_get_next_node (state->pixel_displays, node); - display = ply_list_node_get_data (node); - ply_pixel_display_free (display); - - ply_list_remove_node (state->pixel_displays, node); - - node = next_node; - } - - node = ply_list_get_first_node (state->text_displays); - while (node != NULL) - { - ply_list_node_t *next_node; - ply_text_display_t *display; + bool has_open_seats; - ply_trace ("removing text display"); - next_node = ply_list_get_next_node (state->text_displays, node); - display = ply_list_node_get_data (node); - ply_text_display_free (display); - - ply_list_remove_node (state->text_displays, node); - - node = next_node; - } - - if (state->keyboard != NULL) + if (state->is_shown) { - ply_trace ("removing keyboard"); - ply_keyboard_free (state->keyboard); - state->keyboard = NULL; + ply_trace ("show splash called while already shown"); + return; } -} - -static void -on_show_splash (state_t *state) -{ - bool has_display; if (state->is_inactive) { @@ -884,18 +912,81 @@ on_show_splash (state_t *state) return; } - check_for_consoles (state, state->default_tty, true); - - has_display = ply_list_get_length (state->pixel_displays) > 0 || - ply_list_get_length (state->text_displays) > 0; + state->is_shown = true; + has_open_seats = ply_device_manager_has_open_seats (state->device_manager); - if (!state->is_attached && state->should_be_attached && has_display) + if (!state->is_attached && state->should_be_attached && has_open_seats) attach_to_running_session (state); - if (!has_display) + if (has_open_seats) + { + ply_trace ("at least one seat already open, so loading splash"); + show_splash (state); + } + else { - ply_trace ("no open seats"); - detach_from_running_session (state); + ply_trace ("no seats available to show splash on, waiting..."); + } +} + +static void +on_seat_removed (state_t *state, + ply_seat_t *seat) +{ + ply_keyboard_t *keyboard; + + keyboard = ply_seat_get_keyboard (seat); + + ply_trace ("no longer listening for keystrokes"); + ply_keyboard_remove_input_handler (keyboard, + (ply_keyboard_input_handler_t) + on_keyboard_input); + ply_trace ("no longer listening for escape"); + ply_keyboard_remove_escape_handler (keyboard, + (ply_keyboard_escape_handler_t) + on_escape_pressed); + ply_trace ("no longer listening for backspace"); + ply_keyboard_remove_backspace_handler (keyboard, + (ply_keyboard_backspace_handler_t) + on_backspace); + ply_trace ("no longer listening for enter"); + ply_keyboard_remove_enter_handler (keyboard, + (ply_keyboard_enter_handler_t) + on_enter); + + if (state->boot_splash != NULL) + ply_boot_splash_detach_from_seat (state->boot_splash, seat); +} + +static void +show_splash (state_t *state) +{ + if (state->boot_splash != NULL) + return; + + if (!isnan (state->splash_delay)) + { + double now, running_time; + + now = ply_get_timestamp (); + running_time = now - state->start_time; + if (state->splash_delay > running_time) + { + double time_left = state->splash_delay - running_time; + + ply_trace ("delaying show splash for %lf seconds", + time_left); + ply_event_loop_stop_watching_for_timeout (state->loop, + (ply_event_loop_timeout_handler_t) + show_splash, + state); + ply_event_loop_watch_for_timeout (state->loop, + time_left, + (ply_event_loop_timeout_handler_t) + show_splash, + state); + return; + } } if (plymouth_should_show_default_splash (state)) @@ -908,65 +999,67 @@ on_show_splash (state_t *state) show_detailed_splash (state); state->showing_details = true; } - show_messages (state); } -static ply_list_t * -get_tracked_terminals (state_t *state) +static void +on_seat_added (state_t *state, + ply_seat_t *seat) { - ply_list_t *terminals; - ply_list_node_t *node; - - terminals = ply_list_new (); + ply_keyboard_t *keyboard; - node = ply_list_get_first_node (state->text_displays); - while (node != NULL) + if (state->is_shown) { - ply_list_node_t *next_node; - ply_text_display_t *display; - ply_terminal_t *terminal; - - next_node = ply_list_get_next_node (state->text_displays, node); - display = ply_list_node_get_data (node); - terminal = ply_text_display_get_terminal (display); + if (state->boot_splash == NULL) + { + ply_trace ("seat added before splash loaded, so loading splash now"); + show_splash (state); + } + else + { + ply_trace ("seat added after splash loaded, so attaching to splash"); + ply_boot_splash_attach_to_seat (state->boot_splash, seat); + } + } - ply_list_append_data (terminals, terminal); + keyboard = ply_seat_get_keyboard (seat); - node = next_node; - } + ply_trace ("listening for keystrokes"); + ply_keyboard_add_input_handler (keyboard, + (ply_keyboard_input_handler_t) + on_keyboard_input, state); + ply_trace ("listening for escape"); + ply_keyboard_add_escape_handler (keyboard, + (ply_keyboard_escape_handler_t) + on_escape_pressed, state); + ply_trace ("listening for backspace"); + ply_keyboard_add_backspace_handler (keyboard, + (ply_keyboard_backspace_handler_t) + on_backspace, state); + ply_trace ("listening for enter"); + ply_keyboard_add_enter_handler (keyboard, + (ply_keyboard_enter_handler_t) + on_enter, state); - return terminals; } static void -free_terminals (state_t *state, - ply_list_t *terminals) +load_devices (state_t *state, + ply_device_manager_flags_t flags) { - ply_list_node_t *node; - node = ply_list_get_first_node (terminals); - while (node != NULL) - { - ply_list_node_t *next_node; - ply_terminal_t *terminal; + state->device_manager = ply_device_manager_new (state->default_tty, flags); + state->local_console_terminal = ply_device_manager_get_default_terminal (state->device_manager); - next_node = ply_list_get_next_node (state->text_displays, node); - terminal = ply_list_node_get_data (node); - - ply_terminal_close (terminal); - ply_terminal_free (terminal); - ply_list_remove_node (terminals, node); - - node = next_node; - } - - ply_list_free (terminals); + ply_device_manager_watch_seats (state->device_manager, + (ply_seat_added_handler_t) + on_seat_added, + (ply_seat_removed_handler_t) + on_seat_removed, + state); } static void quit_splash (state_t *state) { - ply_list_t *terminals; - ply_trace ("quiting splash"); if (state->boot_splash != NULL) { @@ -975,17 +1068,7 @@ quit_splash (state_t *state) state->boot_splash = NULL; } - terminals = get_tracked_terminals (state); - - ply_trace ("removing displays and keyboard"); - remove_displays_and_keyboard (state); - - if (state->renderer != NULL) - { - ply_renderer_close (state->renderer); - ply_renderer_free (state->renderer); - state->renderer = NULL; - } + ply_device_manager_deactivate_keyboards (state->device_manager); if (state->local_console_terminal != NULL) { @@ -993,25 +1076,37 @@ quit_splash (state_t *state) { ply_trace ("Not retaining splash, so deallocating VT"); ply_terminal_deactivate_vt (state->local_console_terminal); + ply_terminal_close (state->local_console_terminal); } - state->local_console_terminal = NULL; } - free_terminals (state, terminals); detach_from_running_session (state); } static void +hide_splash (state_t *state) +{ + state->is_shown = false; + + cancel_pending_delayed_show (state); + + if (state->boot_splash == NULL) + return; + + ply_boot_splash_hide (state->boot_splash); + + if (state->local_console_terminal != NULL) + ply_terminal_set_mode (state->local_console_terminal, PLY_TERMINAL_MODE_TEXT); +} + +static void dump_details_and_quit_splash (state_t *state) { state->showing_details = false; toggle_between_splash_and_details (state); - if (state->renderer != NULL) - ply_renderer_deactivate (state->renderer); - if (state->boot_splash != NULL) - ply_boot_splash_hide (state->boot_splash); - + ply_device_manager_deactivate_renderers (state->device_manager); + hide_splash (state); quit_splash (state); } @@ -1042,6 +1137,9 @@ tell_gdm_to_transition (void) static void quit_program (state_t *state) { + ply_trace ("cleaning up devices"); + ply_device_manager_free (state->device_manager); + ply_trace ("exiting event loop"); ply_event_loop_exit (state->loop, 0); @@ -1077,11 +1175,7 @@ deactivate_splash (state_t *state) { assert (!state->is_inactive); - if (state->renderer != NULL) - { - ply_trace ("deactivating renderer"); - ply_renderer_deactivate (state->renderer); - } + ply_device_manager_deactivate_renderers (state->device_manager); detach_from_running_session (state); @@ -1090,7 +1184,13 @@ deactivate_splash (state_t *state) ply_trace ("deactivating terminal"); ply_terminal_stop_watching_for_vt_changes (state->local_console_terminal); ply_terminal_set_buffered_input (state->local_console_terminal); - ply_terminal_ignore_mode_changes (state->local_console_terminal, true); + ply_terminal_close (state->local_console_terminal); + } + + /* do not let any tty opened where we could write after deactivate */ + if (command_line_has_argument (state->kernel_command_line, "plymouth.debug")) + { + ply_logger_close_file (ply_logger_get_error_default ()); } state->is_inactive = true; @@ -1112,10 +1212,8 @@ on_boot_splash_idle (state_t *state) if (!state->should_retain_splash) { ply_trace ("hiding splash"); - if (state->renderer != NULL) - ply_renderer_deactivate (state->renderer); - if (state->boot_splash != NULL) - ply_boot_splash_hide (state->boot_splash); + ply_device_manager_deactivate_renderers (state->device_manager); + hide_splash (state); } ply_trace ("quitting splash"); @@ -1130,12 +1228,17 @@ on_boot_splash_idle (state_t *state) } } - static void on_deactivate (state_t *state, ply_trigger_t *deactivate_trigger) { - if ((state->deactivate_trigger != NULL) || state->is_inactive) + if (state->is_inactive) + { + ply_trigger_pull (deactivate_trigger, NULL); + return; + } + + if (state->deactivate_trigger != NULL) { ply_trigger_add_handler (state->deactivate_trigger, (ply_trigger_handler_t) @@ -1147,12 +1250,9 @@ on_deactivate (state_t *state, state->deactivate_trigger = deactivate_trigger; ply_trace ("deactivating"); + cancel_pending_delayed_show (state); - if (state->keyboard != NULL) - { - ply_trace ("deactivating keyboard"); - ply_keyboard_stop_watching_for_input (state->keyboard); - } + ply_device_manager_deactivate_keyboards (state->device_manager); if (state->boot_splash != NULL) { @@ -1176,6 +1276,7 @@ on_reactivate (state_t *state) if (state->local_console_terminal != NULL) { + ply_terminal_open (state->local_console_terminal); ply_terminal_watch_for_vt_changes (state->local_console_terminal); ply_terminal_set_unbuffered_input (state->local_console_terminal); ply_terminal_ignore_mode_changes (state->local_console_terminal, false); @@ -1187,17 +1288,8 @@ on_reactivate (state_t *state) attach_to_running_session (state); } - if (state->keyboard != NULL) - { - ply_trace ("activating keyboard"); - ply_keyboard_watch_for_input (state->keyboard); - } - - if (state->renderer != NULL) - { - ply_trace ("activating renderer"); - ply_renderer_activate (state->renderer); - } + ply_device_manager_activate_keyboards (state->device_manager); + ply_device_manager_activate_renderers (state->device_manager); state->is_inactive = false; @@ -1209,8 +1301,11 @@ on_quit (state_t *state, bool retain_splash, ply_trigger_t *quit_trigger) { + ply_trace ("quitting (retain splash: %s)", retain_splash? "true" : "false"); + if (state->quit_trigger != NULL) { + ply_trace ("quit trigger already pending, so chaining to it"); ply_trigger_add_handler (state->quit_trigger, (ply_trigger_handler_t) ply_trigger_pull, @@ -1219,9 +1314,16 @@ on_quit (state_t *state, } if (state->system_initialized) - ply_progress_save_cache (state->progress, - get_cache_file_for_mode (state->mode)); - + { + ply_trace ("system initialized so saving boot-duration file"); + ply_create_directory (PLYMOUTH_TIME_DIRECTORY); + ply_progress_save_cache (state->progress, + get_cache_file_for_mode (state->mode)); + } + else + { + ply_trace ("system not initialized so skipping saving boot-duration file"); + } state->quit_trigger = quit_trigger; state->should_retain_splash = retain_splash; @@ -1229,15 +1331,11 @@ on_quit (state_t *state, tell_systemd_to_stop_printing_details (state); #endif - ply_trace ("time to quit, closing log"); + ply_trace ("closing log"); if (state->session != NULL) ply_terminal_session_close_log (state->session); - if (state->keyboard != NULL) - { - ply_trace ("deactivating keyboard"); - ply_keyboard_stop_watching_for_input (state->keyboard); - } + ply_device_manager_deactivate_keyboards (state->device_manager); ply_trace ("unloading splash"); if (state->is_inactive && !retain_splash) @@ -1351,7 +1449,7 @@ toggle_between_splash_and_details (state_t *state) if (state->boot_splash != NULL) { ply_trace ("hiding and freeing current splash"); - ply_boot_splash_hide (state->boot_splash); + hide_splash (state); ply_boot_splash_free (state->boot_splash); state->boot_splash = NULL; } @@ -1366,8 +1464,6 @@ toggle_between_splash_and_details (state_t *state) show_default_splash (state); state->showing_details = false; } - update_display (state); - show_messages (state); } static void @@ -1479,140 +1575,24 @@ on_enter (state_t *state, } static void -set_keyboard (state_t *state, - ply_keyboard_t *keyboard) -{ - state->keyboard = keyboard; - - ply_keyboard_add_escape_handler (keyboard, (ply_keyboard_escape_handler_t) - on_escape_pressed, state); - ply_trace ("listening for keystrokes"); - ply_keyboard_add_input_handler (keyboard, - (ply_keyboard_input_handler_t) - on_keyboard_input, state); - ply_trace ("listening for backspace"); - ply_keyboard_add_backspace_handler (keyboard, - (ply_keyboard_backspace_handler_t) - on_backspace, state); - ply_trace ("listening for enter"); - ply_keyboard_add_enter_handler (keyboard, - (ply_keyboard_enter_handler_t) - on_enter, state); -} -static void -add_display_and_keyboard_for_terminal (state_t *state, - ply_terminal_t *terminal) -{ - ply_text_display_t *display; - ply_keyboard_t *keyboard; - - keyboard = ply_keyboard_new_for_terminal (terminal); - display = ply_text_display_new (terminal); - - ply_list_append_data (state->text_displays, display); - set_keyboard (state, keyboard); -} - -static void -add_pixel_displays_from_renderer (state_t *state, - ply_renderer_t *renderer) -{ - ply_list_t *heads; - ply_list_node_t *node; - - heads = ply_renderer_get_heads (renderer); - - ply_trace ("Adding displays for %d heads", - ply_list_get_length (heads)); - - node = ply_list_get_first_node (heads); - while (node != NULL) - { - ply_list_node_t *next_node; - ply_renderer_head_t *head; - ply_pixel_display_t *display; - - head = ply_list_node_get_data (node); - next_node = ply_list_get_next_node (heads, node); - - display = ply_pixel_display_new (renderer, head); - - ply_list_append_data (state->pixel_displays, display); - - node = next_node; - } - -} - -static void -add_default_displays_and_keyboard (state_t *state) +attach_splash_to_seats (state_t *state, + ply_boot_splash_t *splash) { - ply_renderer_t *renderer; - ply_keyboard_t *keyboard; - ply_text_display_t *text_display; - - ply_trace ("adding default displays and keyboard"); - state->local_console_terminal = ply_terminal_new (state->default_tty); - - renderer = ply_renderer_new (NULL, NULL, state->local_console_terminal); - - if (!ply_renderer_open (renderer)) - { - ply_trace ("could not open renderer /dev/fb"); - ply_renderer_free (renderer); - - ply_trace ("adding text display and keyboard for %s", state->default_tty); - add_display_and_keyboard_for_terminal (state, state->local_console_terminal); - return; - } - - keyboard = ply_keyboard_new_for_renderer (renderer); - set_keyboard (state, keyboard); - - add_pixel_displays_from_renderer (state, renderer); - - text_display = ply_text_display_new (state->local_console_terminal); - ply_list_append_data (state->text_displays, text_display); - - state->renderer = renderer; -} - -static void -add_displays_and_keyboard_to_boot_splash (state_t *state, - ply_boot_splash_t *splash) -{ + ply_list_t *seats; ply_list_node_t *node; - ply_trace ("setting keyboard on boot splash"); - if (state->keyboard != NULL) - ply_boot_splash_set_keyboard (splash, state->keyboard); - - node = ply_list_get_first_node (state->pixel_displays); + seats = ply_device_manager_get_seats (state->device_manager); + node = ply_list_get_first_node (seats); while (node != NULL) { - ply_pixel_display_t *display; + ply_seat_t *seat; ply_list_node_t *next_node; - display = ply_list_node_get_data (node); - next_node = ply_list_get_next_node (state->pixel_displays, node); - ply_trace ("adding pixel display on boot splash"); - ply_boot_splash_add_pixel_display (splash, display); + seat = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (seats, node); - node = next_node; - } - - node = ply_list_get_first_node (state->text_displays); - while (node != NULL) - { - ply_text_display_t *display; - ply_list_node_t *next_node; - - display = ply_list_node_get_data (node); - next_node = ply_list_get_next_node (state->text_displays, node); - - ply_trace ("adding text display on boot splash"); - ply_boot_splash_add_text_display (splash, display); + ply_boot_splash_attach_to_seat (splash, seat); node = next_node; } @@ -1637,12 +1617,41 @@ tell_systemd_to_stop_printing_details (state_t *state) #endif static ply_boot_splash_t * -start_boot_splash (state_t *state, - const char *theme_path, - bool fall_back_if_neccessary) +load_built_in_theme (state_t *state) +{ + ply_boot_splash_t *splash; + bool is_loaded; + + ply_trace ("Loading built-in theme"); + + splash = ply_boot_splash_new ("", + PLYMOUTH_PLUGIN_PATH, + state->boot_buffer); + + is_loaded = ply_boot_splash_load_built_in (splash); + + if (!is_loaded) + { + ply_save_errno (); + ply_boot_splash_free (splash); + ply_restore_errno (); + return NULL; + } + + ply_trace ("attaching plugin to event loop"); + ply_boot_splash_attach_to_event_loop (splash, state->loop); + + ply_trace ("attaching progress to plugin"); + ply_boot_splash_attach_progress (splash, state->progress); + + return splash; +} + +static ply_boot_splash_t * +load_theme (state_t *state, + const char *theme_path) { ply_boot_splash_t *splash; - ply_boot_splash_mode_t splash_mode; bool is_loaded; ply_trace ("Loading boot splash theme '%s'", @@ -1653,13 +1662,6 @@ start_boot_splash (state_t *state, state->boot_buffer); is_loaded = ply_boot_splash_load (splash); - if (!is_loaded && fall_back_if_neccessary) - { - ply_trace ("Splash couldn't be loaded: %m"); - - ply_trace ("Loading built in splash"); - is_loaded = ply_boot_splash_load_built_in (splash); - } if (!is_loaded) { @@ -1675,9 +1677,27 @@ start_boot_splash (state_t *state, ply_trace ("attaching progress to plugin"); ply_boot_splash_attach_progress (splash, state->progress); - add_displays_and_keyboard_to_boot_splash (state, splash); + return splash; +} + +static ply_boot_splash_t * +show_theme (state_t *state, + const char *theme_path) +{ + ply_boot_splash_mode_t splash_mode; + ply_boot_splash_t *splash; + + if (theme_path != NULL) + splash = load_theme (state, theme_path); + else + splash = load_built_in_theme (state); + + if (splash == NULL) + return NULL; + + attach_splash_to_seats (state, splash); + ply_device_manager_activate_renderers (state->device_manager); - ply_trace ("showing plugin"); if (state->mode == PLY_MODE_SHUTDOWN) splash_mode = PLY_BOOT_SPLASH_MODE_SHUTDOWN; else @@ -1686,7 +1706,6 @@ start_boot_splash (state_t *state, if (!ply_boot_splash_show (splash, splash_mode)) { ply_save_errno (); - ply_boot_splash_unset_keyboard (splash); ply_boot_splash_free (splash); ply_restore_errno (); return NULL; @@ -1697,10 +1716,9 @@ start_boot_splash (state_t *state, tell_systemd_to_print_details (state); #endif - if (state->keyboard != NULL) - ply_keyboard_watch_for_input (state->keyboard); + ply_device_manager_activate_keyboards (state->device_manager); + show_messages (state); - update_display (state); return splash; } @@ -1875,6 +1893,30 @@ check_verbosity (state_t *state) ply_logger_set_output_fd (ply_logger_get_error_default (), fd); } free (stream_copy); + } else { + const char* device; + char *file; + + device = state->default_tty; + + ply_trace ("redirecting debug output to %s", device); + + if (strncmp (device, "/dev/", strlen ("/dev/")) == 0) + file = strdup (device); + else + asprintf (&file, "/dev/%s", device); + + fd = open (file, O_RDWR | O_APPEND); + + if (fd < 0) + { + ply_trace ("could not redirected debug output to %s: %m", device); + } + else { + ply_logger_set_output_fd (ply_logger_get_error_default (), fd); + } + + free (file); } } else @@ -1896,267 +1938,26 @@ check_verbosity (state_t *state) static void check_logging (state_t *state) { - ply_trace ("checking if console messages should be redirected and logged"); - - if (command_line_has_argument (state->kernel_command_line, "plymouth.nolog")) - { - ply_trace ("logging won't be enabled!"); - state->no_boot_log = true; - } - else - { - ply_trace ("logging will be enabled!"); - state->no_boot_log = false; - } -} - -static void -add_display_and_keyboard_for_console (const char *console, - const char *null, - state_t *state) -{ - ply_terminal_t *terminal; - - terminal = ply_terminal_new (console); - - if (strcmp (console, state->default_tty) == 0) - state->local_console_terminal = terminal; + bool kernel_no_log; - ply_trace ("adding display and keyboard for console %s", console); - add_display_and_keyboard_for_terminal (state, terminal); -} - -static int -add_consoles_from_file (state_t *state, - ply_hashtable_t *consoles, - const char *path) -{ - int fd; - char contents[512] = ""; - ssize_t contents_length; - int num_consoles; - const char *remaining_file_contents; - - ply_trace ("opening %s", path); - fd = open (path, O_RDONLY); - - if (fd < 0) - { - ply_trace ("couldn't open it: %m"); - return 0; - } - - ply_trace ("reading file"); - contents_length = read (fd, contents, sizeof (contents)); - - if (contents_length <= 0) - { - ply_trace ("couldn't read it: %m"); - close (fd); - return 0; - } - close (fd); - - remaining_file_contents = contents; - num_consoles = 0; - - while (remaining_file_contents < contents + contents_length) - { - char *console; - size_t console_length; - char *console_device; - - /* 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); - - /* If this console is anything besides tty0, then the user is sort - * of a weird case (uses a serial console or whatever) and they - * most likely don't want a graphical splash, so force details. - */ - if (strcmp (console, "tty0") != 0) - state->should_force_details = true; - - asprintf (&console_device, "/dev/%s", console); - - free (console); - - ply_trace ("console %s found!", console_device); - ply_hashtable_insert (consoles, console_device, console_device); - num_consoles++; - - /* Move past the parsed console string, and the whitespace we - * may have found above. If we found a NUL above and not whitespace, - * then we're going to jump past the end of the buffer and the loop - * will terminate - */ - remaining_file_contents += console_length + 1; - } - - return num_consoles; -} - -static int -add_consoles_from_kernel_command_line (state_t *state, - ply_hashtable_t *consoles) -{ - const char *console_string; - const char *remaining_command_line; - char *console; - int num_consoles; - - remaining_command_line = state->kernel_command_line; - - num_consoles = 0; - console = NULL; - while ((console_string = command_line_get_string_after_prefix (remaining_command_line, - "console=")) != NULL) - { - char *end; - size_t console_length; - char *console_device; - - remaining_command_line = console_string; - - state->should_force_details = true; - - console = strdup (console_string); - - end = strpbrk (console, " \n\t\v,"); - - if (end != NULL) - *end = '\0'; - - console_length = strlen (console); - - if (strncmp (console, "/dev/", strlen ("/dev/")) == 0) - { - console_device = console; - console = NULL; - } - else - { - asprintf (&console_device, "/dev/%s", console); - free (console); - console = NULL; - } - - ply_trace ("console %s found!", console_device); - ply_hashtable_insert (consoles, console_device, console_device); - num_consoles++; - remaining_command_line += console_length; - } - - return num_consoles; -} - -static void -check_for_consoles (state_t *state, - const char *default_tty, - bool should_add_displays) -{ - char *console; - ply_hashtable_t *consoles; - int num_consoles; - bool ignore_serial_consoles; - - ply_trace ("checking for consoles%s", - should_add_displays? " and adding displays": ""); - - consoles = ply_hashtable_new (ply_hashtable_string_hash, - ply_hashtable_string_compare); - ignore_serial_consoles = command_line_has_argument (state->kernel_command_line, "plymouth.ignore-serial-consoles"); - - num_consoles = 0; + ply_trace ("checking if console messages should be redirected and logged"); - if (!ignore_serial_consoles) - { - num_consoles = add_consoles_from_file (state, consoles, "/sys/class/tty/console/active"); + kernel_no_log = command_line_has_argument (state->kernel_command_line, "plymouth.nolog"); + if (kernel_no_log) + state->no_boot_log = true; - if (num_consoles == 0) - { - ply_trace ("falling back to kernel command line"); - num_consoles = add_consoles_from_kernel_command_line (state, consoles); - } - } + if (state->no_boot_log) + ply_trace ("logging won't be enabled!"); else - { - ply_trace ("ignoring all consoles but default console because of plymouth.ignore-serial-consoles"); - } - - console = ply_hashtable_remove (consoles, (void *) "/dev/tty0"); - if (console != NULL) - { - free (console); - console = strdup (default_tty); - ply_hashtable_insert (consoles, console, console); - } - - console = ply_hashtable_remove (consoles, (void *) "/dev/tty"); - if (console != NULL) - { - free (console); - console = strdup (default_tty); - ply_hashtable_insert (consoles, console, console); - } - - free (state->kernel_console_tty); - state->kernel_console_tty = NULL; - - if (console != NULL) - state->kernel_console_tty = strdup (console); - - if (should_add_displays) - { - /* Do a full graphical splash if there's no weird serial console - * stuff going on, otherwise just prepare text splashes - */ - if ((num_consoles == 0) || - ((num_consoles == 1) && - (ply_hashtable_lookup (consoles, (void *) default_tty) != NULL))) - add_default_displays_and_keyboard (state); - else - ply_hashtable_foreach (consoles, - (ply_hashtable_foreach_func_t *) - add_display_and_keyboard_for_console, - state); - } - - ply_hashtable_foreach (consoles, (ply_hashtable_foreach_func_t *) free, NULL); - ply_hashtable_free (consoles); - - ply_trace ("After processing serial consoles there are now %d text displays", - ply_list_get_length (state->text_displays)); + ply_trace ("logging will be enabled!"); } static bool -redirect_standard_io_to_device (const char *device) +redirect_standard_io_to_dev_null (void) { int fd; - char *file; - - ply_trace ("redirecting stdio to %s", device); - - if (strncmp (device, "/dev/", strlen ("/dev/")) == 0) - file = strdup (device); - else - asprintf (&file, "/dev/%s", device); - fd = open (file, O_RDWR | O_APPEND); - - free (file); + fd = open ("/dev/null", O_RDWR | O_APPEND); if (fd < 0) return false; @@ -2199,19 +2000,11 @@ initialize_environment (state_t *state) if (!get_kernel_command_line (state)) return false; - check_verbosity (state); - check_logging (state); - - ply_trace ("source built on %s", __DATE__); - - state->keystroke_triggers = ply_list_new (); - state->entry_triggers = ply_list_new (); - state->entry_buffer = ply_buffer_new(); - state->pixel_displays = ply_list_new (); - state->text_displays = ply_list_new (); - state->messages = ply_list_new (); - state->keyboard = NULL; - + if (!state->default_tty) + { + if (getenv ("DISPLAY") != NULL && access (PLYMOUTH_PLUGIN_PATH "renderers/x11.so", F_OK) == 0) + state->default_tty = "/dev/tty"; + } if (!state->default_tty) { if (state->mode == PLY_MODE_SHUTDOWN) @@ -2232,12 +2025,17 @@ initialize_environment (state_t *state) } } - check_for_consoles (state, state->default_tty, false); + check_verbosity (state); + check_logging (state); - if (state->kernel_console_tty != NULL) - redirect_standard_io_to_device (state->kernel_console_tty); - else - redirect_standard_io_to_device (state->default_tty); + ply_trace ("source built on %s", __DATE__); + + state->keystroke_triggers = ply_list_new (); + state->entry_triggers = ply_list_new (); + state->entry_buffer = ply_buffer_new(); + state->messages = ply_list_new (); + + redirect_standard_io_to_dev_null (); ply_trace ("Making sure " PLYMOUTH_RUNTIME_DIR " exists"); if (!ply_create_directory (PLYMOUTH_RUNTIME_DIR)) @@ -2338,6 +2136,7 @@ main (int argc, state_t state = { 0 }; int exit_code; bool should_help = false; + bool no_boot_log = false; bool no_daemon = false; bool debug = false; bool attach_to_session; @@ -2345,7 +2144,9 @@ main (int argc, char *mode_string = NULL; char *kernel_command_line = NULL; char *tty = NULL; + ply_device_manager_flags_t device_manager_flags = PLY_DEVICE_MANAGER_FLAGS_NONE; + state.start_time = ply_get_timestamp (); state.command_parser = ply_command_parser_new ("plymouthd", "Splash server"); state.loop = ply_event_loop_get_default (); @@ -2360,6 +2161,7 @@ main (int argc, "pid-file", "Write the pid of the daemon to a file", PLY_COMMAND_OPTION_TYPE_STRING, "kernel-command-line", "Fake kernel command line to use", PLY_COMMAND_OPTION_TYPE_STRING, "tty", "TTY to use instead of default", PLY_COMMAND_OPTION_TYPE_STRING, + "no-boot-log", "Do not write boot log file", PLY_COMMAND_OPTION_TYPE_FLAG, NULL); if (!ply_command_parser_parse_arguments (state.command_parser, state.loop, argv, argc)) @@ -2378,6 +2180,7 @@ main (int argc, "help", &should_help, "attach-to-session", &attach_to_session, "mode", &mode_string, + "no-boot-log", &no_boot_log, "no-daemon", &no_daemon, "debug", &debug, "debug-file", &debug_buffer_path, @@ -2434,6 +2237,8 @@ main (int argc, return EX_OSERR; } + state.no_boot_log = no_boot_log; + chdir ("/"); signal (SIGPIPE, SIG_IGN); @@ -2505,6 +2310,7 @@ main (int argc, } state.progress = ply_progress_new (); + state.splash_delay = NAN; ply_progress_load_cache (state.progress, get_cache_file_for_mode (state.mode)); @@ -2519,6 +2325,28 @@ main (int argc, return EX_UNAVAILABLE; } + find_override_splash (&state); + find_system_default_splash (&state); + find_distribution_default_splash (&state); + + if (command_line_has_argument (state.kernel_command_line, "plymouth.ignore-serial-consoles")) + device_manager_flags |= PLY_DEVICE_MANAGER_FLAGS_IGNORE_SERIAL_CONSOLES; + + if (command_line_has_argument (state.kernel_command_line, "plymouth.ignore-udev") || + (getenv ("DISPLAY") != NULL)) + device_manager_flags |= PLY_DEVICE_MANAGER_FLAGS_IGNORE_UDEV; + + if (!plymouth_should_show_default_splash (&state)) + { + /* don't bother listening for udev events if we're forcing details */ + device_manager_flags |= PLY_DEVICE_MANAGER_FLAGS_IGNORE_UDEV; + + /* don't ever delay showing the detailed splash */ + state.splash_delay = NAN; + } + + load_devices (&state, device_manager_flags); + ply_trace ("entering event loop"); exit_code = ply_event_loop_run (state.loop); ply_trace ("exited event loop"); diff --git a/src/plugins/controls/label/Makefile.am b/src/plugins/controls/label/Makefile.am index 296203b..219930a 100644 --- a/src/plugins/controls/label/Makefile.am +++ b/src/plugins/controls/label/Makefile.am @@ -1,4 +1,4 @@ -INCLUDES = -I$(top_srcdir) \ +AM_CPPFLAGS = -I$(top_srcdir) \ -I$(srcdir)/../../../libply \ -I$(srcdir)/../../../libply-splash-core \ -I$(srcdir)/../../../libply-splash-graphics \ diff --git a/src/plugins/renderers/drm/Makefile.am b/src/plugins/renderers/drm/Makefile.am index 2209b30..747f202 100644 --- a/src/plugins/renderers/drm/Makefile.am +++ b/src/plugins/renderers/drm/Makefile.am @@ -1,5 +1,5 @@ if ENABLE_DRM_RENDERER -INCLUDES = -I$(top_srcdir) \ +AM_CPPFLAGS = -I$(top_srcdir) \ -I$(srcdir)/../../../libply \ -I$(srcdir)/../../../libply-splash-core \ -I$(srcdir)/../../.. \ @@ -21,27 +21,7 @@ drm_la_SOURCES = $(srcdir)/plugin.c \ drm_la_SOURCES += $(srcdir)/ply-renderer-generic-driver.h \ $(srcdir)/ply-renderer-generic-driver.c -if ENABLE_LIBDRM_INTEL -drm_la_SOURCES += $(srcdir)/ply-renderer-i915-driver.h \ - $(srcdir)/ply-renderer-i915-driver.c -endif - -if ENABLE_LIBDRM_RADEON -drm_la_SOURCES += $(srcdir)/ply-renderer-radeon-driver.h \ - $(srcdir)/ply-renderer-radeon-driver.c -endif -if ENABLE_LIBDRM_NOUVEAU -drm_la_SOURCES += $(srcdir)/ply-renderer-nouveau-driver.h \ - $(srcdir)/ply-renderer-nouveau-driver.c -endif - -if ENABLE_LIBKMS -drm_la_LIBADD += $(LIBKMS_LIBS) -drm_la_CFLAGS += $(LIBKMS_CFLAGS) -drm_la_SOURCES += $(srcdir)/ply-renderer-libkms-driver.h \ - $(srcdir)/ply-renderer-libkms-driver.c -endif endif diff --git a/src/plugins/renderers/drm/plugin.c b/src/plugins/renderers/drm/plugin.c index db953e6..6677279 100644 --- a/src/plugins/renderers/drm/plugin.c +++ b/src/plugins/renderers/drm/plugin.c @@ -60,19 +60,6 @@ #include "ply-renderer-plugin.h" #include "ply-renderer-driver.h" #include "ply-renderer-generic-driver.h" -#ifdef PLY_ENABLE_LIBDRM_INTEL -#include "ply-renderer-i915-driver.h" -#endif -#ifdef PLY_ENABLE_LIBDRM_RADEON -#include "ply-renderer-radeon-driver.h" -#endif -#ifdef PLY_ENABLE_LIBDRM_NOUVEAU -#include "ply-renderer-nouveau-driver.h" -#endif - -#ifdef PLY_ENABLE_LIBKMS -#include "ply-renderer-libkms-driver.h" -#endif #define BYTES_PER_PIXEL (4) @@ -412,42 +399,6 @@ destroy_backend (ply_renderer_backend_t *backend) free (backend); } -static char * -find_driver_for_device (const char *device_name) -{ - char *driver; - int major_number, minor_number; - struct stat file_attributes; - char *device_path; - char device_link_path[PATH_MAX + 1] = ""; - - if (stat (device_name, &file_attributes) < 0) - return NULL; - - if (!S_ISCHR (file_attributes.st_mode)) - return NULL; - - major_number = major (file_attributes.st_rdev); - minor_number = minor (file_attributes.st_rdev); - - asprintf (&device_path, "/sys/dev/char/%d:%d/device/driver", - major_number, minor_number); - - if (readlink (device_path, device_link_path, sizeof (device_link_path) - 1) < 0) - { - free (device_path); - return NULL; - } - free (device_path); - - driver = strrchr (device_link_path, '/'); - - if (driver == NULL) - return NULL; - - return strdup (driver + strlen ("/")); -} - static void activate (ply_renderer_backend_t *backend) { @@ -508,72 +459,24 @@ on_active_vt_changed (ply_renderer_backend_t *backend) static bool load_driver (ply_renderer_backend_t *backend) { - char *driver_name; int device_fd; - driver_name = find_driver_for_device (backend->device_name); - ply_trace ("Attempting to load driver '%s'", driver_name); - device_fd = drmOpen (driver_name, NULL); + ply_trace ("Opening '%s'", backend->device_name); + device_fd = open (backend->device_name, O_RDWR); if (device_fd < 0) { - ply_trace ("drmOpen failed"); - free (driver_name); + ply_trace ("open failed: %m"); return false; } - backend->driver_interface = NULL; -/* Try intel driver first if we're supporting the legacy GDM transition - * since it can map the kernel console, which gives us the ability to do - * a more seamless transition when plymouth quits before X starts - */ -#if defined(PLY_ENABLE_DEPRECATED_GDM_TRANSITION) && defined(PLY_ENABLE_LIBDRM_INTEL) - if (backend->driver_interface == NULL && strcmp (driver_name, "i915") == 0) - { - backend->driver_interface = ply_renderer_i915_driver_get_interface (); - backend->driver_supports_mapping_console = true; - } -#endif + backend->driver_interface = ply_renderer_generic_driver_get_interface (device_fd); + backend->driver_supports_mapping_console = false; if (backend->driver_interface == NULL) { - backend->driver_interface = ply_renderer_generic_driver_get_interface (device_fd); - backend->driver_supports_mapping_console = false; - } - -#ifdef PLY_ENABLE_LIBDRM_INTEL - if (backend->driver_interface == NULL && strcmp (driver_name, "i915") == 0) - { - backend->driver_interface = ply_renderer_i915_driver_get_interface (); - backend->driver_supports_mapping_console = true; - } -#endif -#ifdef PLY_ENABLE_LIBDRM_RADEON - if (backend->driver_interface == NULL && strcmp (driver_name, "radeon") == 0) - { - backend->driver_interface = ply_renderer_radeon_driver_get_interface (); - backend->driver_supports_mapping_console = false; - } -#endif -#ifdef PLY_ENABLE_LIBDRM_NOUVEAU - if (backend->driver_interface == NULL && strcmp (driver_name, "nouveau") == 0) - { - backend->driver_interface = ply_renderer_nouveau_driver_get_interface (); - backend->driver_supports_mapping_console = false; - } -#endif - - free (driver_name); - - if (backend->driver_interface == NULL) - { -#ifdef PLY_ENABLE_LIBKMS - backend->driver_interface = ply_renderer_libkms_driver_get_interface (); - backend->driver_supports_mapping_console = false; -#else close (device_fd); return false; -#endif } backend->driver = backend->driver_interface->create_driver (device_fd); @@ -619,6 +522,9 @@ open_device (ply_renderer_backend_t *backend) if (!load_driver (backend)) return false; + if (backend->terminal == NULL) + return true; + if (!ply_terminal_open (backend->terminal)) { ply_trace ("could not open terminal: %m"); @@ -647,10 +553,11 @@ close_device (ply_renderer_backend_t *backend) free_heads (backend); - ply_terminal_stop_watching_for_active_vt_change (backend->terminal, - (ply_terminal_active_vt_changed_handler_t) - on_active_vt_changed, - backend); + if (backend->terminal != NULL) + ply_terminal_stop_watching_for_active_vt_change (backend->terminal, + (ply_terminal_active_vt_changed_handler_t) + on_active_vt_changed, + backend); unload_driver (backend); } @@ -985,10 +892,17 @@ map_to_device (ply_renderer_backend_t *backend) node = next_node; } - if (ply_terminal_is_active (backend->terminal)) - activate (backend); + if (backend->terminal != NULL) + { + if (ply_terminal_is_active (backend->terminal)) + activate (backend); + else + ply_terminal_activate_vt (backend->terminal); + } else - ply_terminal_activate_vt (backend->terminal); + { + activate (backend); + } return head_mapped; } @@ -1116,8 +1030,11 @@ reset_scan_out_buffer_if_needed (ply_renderer_backend_t *backend, drmModeCrtc *controller; bool did_reset = false; - if (!ply_terminal_is_active (backend->terminal)) - return false; + if (backend->terminal != NULL) + { + if (!ply_terminal_is_active (backend->terminal)) + return false; + } controller = drmModeGetCrtc (backend->device_fd, head->controller_id); @@ -1151,8 +1068,11 @@ flush_head (ply_renderer_backend_t *backend, if (!backend->is_active) return; - ply_terminal_set_mode (backend->terminal, PLY_TERMINAL_MODE_GRAPHICS); - ply_terminal_set_unbuffered_input (backend->terminal); + if (backend->terminal != NULL) + { + ply_terminal_set_mode (backend->terminal, PLY_TERMINAL_MODE_GRAPHICS); + ply_terminal_set_unbuffered_input (backend->terminal); + } pixel_buffer = head->pixel_buffer; updated_region = ply_pixel_buffer_get_updated_areas (pixel_buffer); areas_to_flush = ply_region_get_sorted_rectangle_list (updated_region); @@ -1260,6 +1180,9 @@ open_input_source (ply_renderer_backend_t *backend, assert (backend != NULL); assert (has_input_source (backend, input_source)); + if (backend->terminal == NULL) + return false; + terminal_fd = ply_terminal_get_fd (backend->terminal); input_source->backend = backend; @@ -1290,6 +1213,9 @@ close_input_source (ply_renderer_backend_t *backend, assert (backend != NULL); assert (has_input_source (backend, input_source)); + if (backend->terminal == NULL) + return; + ply_event_loop_stop_watching_fd (backend->loop, input_source->terminal_input_watch); input_source->terminal_input_watch = NULL; input_source->backend = NULL; diff --git a/src/plugins/renderers/drm/ply-renderer-generic-driver.c b/src/plugins/renderers/drm/ply-renderer-generic-driver.c index 50fde64..45a8faa 100644 --- a/src/plugins/renderers/drm/ply-renderer-generic-driver.c +++ b/src/plugins/renderers/drm/ply-renderer-generic-driver.c @@ -71,6 +71,8 @@ struct _ply_renderer_driver { int device_fd; ply_hashtable_t *buffers; + + uint32_t requires_explicit_flushing : 1; }; static bool @@ -123,7 +125,7 @@ create_driver (int device_fd) driver = calloc (1, sizeof (ply_renderer_driver_t)); driver->device_fd = device_fd; - + driver->requires_explicit_flushing = true; driver->buffers = ply_hashtable_new (ply_hashtable_direct_hash, ply_hashtable_direct_compare); @@ -330,6 +332,22 @@ end_flush (ply_renderer_driver_t *driver, buffer = get_buffer_from_id (driver, buffer_id); assert (buffer != NULL); + + if (driver->requires_explicit_flushing) + { + struct drm_clip_rect flush_area; + int ret; + + flush_area.x1 = 0; + flush_area.y1 = 0; + flush_area.x2 = buffer->width; + flush_area.y2 = buffer->height; + + ret = drmModeDirtyFB (driver->device_fd, buffer->id, &flush_area, 1); + + if (ret == -ENOSYS) + driver->requires_explicit_flushing = false; + } } static void diff --git a/src/plugins/renderers/drm/ply-renderer-i915-driver.c b/src/plugins/renderers/drm/ply-renderer-i915-driver.c deleted file mode 100644 index 907a061..0000000 --- a/src/plugins/renderers/drm/ply-renderer-i915-driver.c +++ /dev/null @@ -1,383 +0,0 @@ -/* ply-renderer-i915-driver.c - interface to i915 drm driver - * - * Copyright (C) 2009 Red Hat, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - * - * Written by: Ray Strode - */ -#include "config.h" - -#include "ply-renderer-i915-driver.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "ply-hashtable.h" -#include "ply-logger.h" -#include "ply-renderer-driver.h" - -typedef struct _ply_renderer_buffer ply_renderer_buffer_t; - -struct _ply_renderer_buffer -{ - drm_intel_bo *object; - uint32_t id; - unsigned long width; - unsigned long height; - unsigned long row_stride; - - uint32_t added_fb : 1; -}; - -struct _ply_renderer_driver -{ - int device_fd; - drm_intel_bufmgr *manager; - - ply_hashtable_t *buffers; -}; - -static ply_renderer_driver_t * -create_driver (int device_fd) -{ - ply_renderer_driver_t *driver; - int page_size; - - driver = calloc (1, sizeof (ply_renderer_driver_t)); - driver->device_fd = device_fd; - - page_size = (int) sysconf (_SC_PAGE_SIZE); - - driver->manager = drm_intel_bufmgr_gem_init (driver->device_fd, page_size); - if (driver->manager == NULL) - { - ply_trace ("intel buffer manager could not be initialized"); - free (driver); - return NULL; - } - - driver->buffers = ply_hashtable_new (ply_hashtable_direct_hash, - ply_hashtable_direct_compare); - - return driver; -} - -static void -destroy_driver (ply_renderer_driver_t *driver) -{ - ply_hashtable_free (driver->buffers); - - ply_trace ("uninitializing intel buffer manager"); - drm_intel_bufmgr_destroy (driver->manager); - free (driver); -} - -static ply_renderer_buffer_t * -ply_renderer_buffer_new (ply_renderer_driver_t *driver, - drm_intel_bo *buffer_object, - uint32_t id, - unsigned long width, - unsigned long height, - unsigned long row_stride) -{ - ply_renderer_buffer_t *buffer; - - buffer = calloc (1, sizeof (ply_renderer_buffer_t)); - buffer->object = buffer_object; - buffer->id = id; - buffer->width = width; - buffer->height = height; - buffer->row_stride = row_stride; - - ply_trace ("returning %lux%lu buffer with stride %lu", - width, height, row_stride); - - return buffer; -} - -static drm_intel_bo * -create_intel_bo_from_handle (ply_renderer_driver_t *driver, - uint32_t handle) -{ - struct drm_gem_flink flink_request; - char *name; - drm_intel_bo *buffer_object; - - /* FIXME: This can't be the right way to do this. - * - * 1) It requires skirting around the API and using ioctls - * 2) It requires taking a local handle, turning it into a - * a global handle ("name"), just so we can use an api that - * will open the global name and grab the local handle from it. - */ - - memset (&flink_request, 0, sizeof (struct drm_gem_flink)); - flink_request.handle = handle; - - if (ioctl (driver->device_fd, DRM_IOCTL_GEM_FLINK, &flink_request) < 0) - { - ply_trace ("Could not export global name for handle %u", handle); - return NULL; - } - - asprintf (&name, "buffer %u", handle); - - buffer_object = drm_intel_bo_gem_create_from_name (driver->manager, - name, flink_request.name); - free (name); - - return buffer_object; -} - -static ply_renderer_buffer_t * -ply_renderer_buffer_new_from_id (ply_renderer_driver_t *driver, - uint32_t buffer_id) -{ - ply_renderer_buffer_t *buffer; - drmModeFB *fb; - drm_intel_bo *buffer_object; - - fb = drmModeGetFB (driver->device_fd, buffer_id); - - if (fb == NULL) - { - ply_trace ("could not get FB with buffer id %u", buffer_id); - return NULL; - } - - buffer_object = create_intel_bo_from_handle (driver, fb->handle); - - if (buffer_object == NULL) - { - ply_trace ("could not create buffer object from handle %lu", - (unsigned long) fb->handle); - drmModeFreeFB (fb); - return NULL; - } - - buffer = ply_renderer_buffer_new (driver, buffer_object, buffer_id, - fb->width, fb->height, fb->pitch); - drmModeFreeFB (fb); - - return buffer; -} - -static ply_renderer_buffer_t * -get_buffer_from_id (ply_renderer_driver_t *driver, - uint32_t buffer_id) -{ - static ply_renderer_buffer_t *buffer; - - buffer = ply_hashtable_lookup (driver->buffers, - (void *) (uintptr_t) buffer_id); - - return buffer; -} - -static bool -fetch_buffer (ply_renderer_driver_t *driver, - uint32_t buffer_id, - unsigned long *width, - unsigned long *height, - unsigned long *row_stride) -{ - ply_renderer_buffer_t *buffer; - - buffer = get_buffer_from_id (driver, buffer_id); - - if (buffer == NULL) - { - ply_trace ("could not fetch buffer %u, creating one", buffer_id); - buffer = ply_renderer_buffer_new_from_id (driver, buffer_id); - - if (buffer == NULL) - { - ply_trace ("could not create buffer either %u", buffer_id); - return false; - } - - ply_hashtable_insert (driver->buffers, - (void *) (uintptr_t) buffer_id, - buffer); - } - - if (width != NULL) - *width = buffer->width; - - if (height != NULL) - *height = buffer->height; - - if (row_stride != NULL) - *row_stride = buffer->row_stride; - - ply_trace ("fetched %lux%lu buffer with stride %lu", - buffer->width, buffer->height, buffer->row_stride); - return true; -} - -static uint32_t -create_buffer (ply_renderer_driver_t *driver, - unsigned long width, - unsigned long height, - unsigned long *row_stride) -{ - drm_intel_bo *buffer_object; - ply_renderer_buffer_t *buffer; - uint32_t buffer_id; - - *row_stride = ply_round_to_multiple (width * 4, 256); - - buffer_object = drm_intel_bo_alloc (driver->manager, - "frame buffer", - height * *row_stride, 0); - - if (buffer_object == NULL) - { - ply_trace ("Could not allocate GEM object for frame buffer: %m"); - return 0; - } - - if (drmModeAddFB (driver->device_fd, width, height, - 24, 32, *row_stride, buffer_object->handle, - &buffer_id) != 0) - { - ply_trace ("Could not set up GEM object as frame buffer: %m"); - drm_intel_bo_unreference (buffer_object); - return 0; - } - - buffer = ply_renderer_buffer_new (driver, - buffer_object, buffer_id, - width, height, *row_stride); - buffer->added_fb = true; - ply_hashtable_insert (driver->buffers, - (void *) (uintptr_t) buffer_id, - buffer); - - return buffer_id; -} - -static bool -map_buffer (ply_renderer_driver_t *driver, - uint32_t buffer_id) -{ - ply_renderer_buffer_t *buffer; - - buffer = get_buffer_from_id (driver, buffer_id); - - assert (buffer != NULL); - drm_intel_gem_bo_map_gtt (buffer->object); - - return true; -} - -static void -unmap_buffer (ply_renderer_driver_t *driver, - uint32_t buffer_id) -{ - ply_renderer_buffer_t *buffer; - - buffer = get_buffer_from_id (driver, buffer_id); - - assert (buffer != NULL); - drm_intel_gem_bo_unmap_gtt (buffer->object); -} - -static char * -begin_flush (ply_renderer_driver_t *driver, - uint32_t buffer_id) -{ - ply_renderer_buffer_t *buffer; - - buffer = get_buffer_from_id (driver, buffer_id); - - assert (buffer != NULL); - - return buffer->object->virtual; -} - -static void -end_flush (ply_renderer_driver_t *driver, - uint32_t buffer_id) -{ - ply_renderer_buffer_t *buffer; - - buffer = get_buffer_from_id (driver, buffer_id); - - assert (buffer != NULL); -} - -static void -destroy_buffer (ply_renderer_driver_t *driver, - uint32_t buffer_id) -{ - ply_renderer_buffer_t *buffer; - - buffer = get_buffer_from_id (driver, buffer_id); - - assert (buffer != NULL); - - if (buffer->added_fb) - drmModeRmFB (driver->device_fd, buffer->id); - - drm_intel_bo_unreference (buffer->object); - - ply_hashtable_remove (driver->buffers, - (void *) (uintptr_t) buffer_id); - free (buffer); -} - -ply_renderer_driver_interface_t * -ply_renderer_i915_driver_get_interface (void) -{ - static ply_renderer_driver_interface_t driver_interface = - { - .create_driver = create_driver, - .destroy_driver = destroy_driver, - .create_buffer = create_buffer, - .fetch_buffer = fetch_buffer, - .map_buffer = map_buffer, - .unmap_buffer = unmap_buffer, - .begin_flush = begin_flush, - .end_flush = end_flush, - .destroy_buffer = destroy_buffer, - }; - - return &driver_interface; -} - -/* vim: set ts=4 sw=4 et ai ci cino={.5s,^-2,+.5s,t0,g0,e-2,n-2,p2s,(0,=.5s,:.5s */ diff --git a/src/plugins/renderers/drm/ply-renderer-i915-driver.h b/src/plugins/renderers/drm/ply-renderer-i915-driver.h deleted file mode 100644 index dcc983c..0000000 --- a/src/plugins/renderers/drm/ply-renderer-i915-driver.h +++ /dev/null @@ -1,32 +0,0 @@ -/* ply-renderer-i915-driver.h - * - * Copyright (C) 2009 Red Hat, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - * - * Written By: Ray Strode - */ -#ifndef PLY_RENDERER_I915_DRIVER_H -#define PLY_RENDERER_I915_DRIVER_H - -#include "ply-renderer-driver.h" - -#ifndef PLY_HIDE_FUNCTION_DECLARATIONS -ply_renderer_driver_interface_t *ply_renderer_i915_driver_get_interface (void); -#endif - -#endif /* PLY_RENDERER_I915_DRIVER_H */ -/* vim: set ts=4 sw=4 et ai ci cino={.5s,^-2,+.5s,t0,g0,e-2,n-2,p2s,(0,=.5s,:.5s */ diff --git a/src/plugins/renderers/drm/ply-renderer-libkms-driver.c b/src/plugins/renderers/drm/ply-renderer-libkms-driver.c deleted file mode 100644 index 18c7ccf..0000000 --- a/src/plugins/renderers/drm/ply-renderer-libkms-driver.c +++ /dev/null @@ -1,430 +0,0 @@ -/* ply-renderer-libkms-driver.c - interface to libkms abstraction over drm drivers - * - * Copyright (C) 2010 Red Hat, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - * - * Written by: Ray Strode - */ -#include "config.h" - -#include "ply-renderer-libkms-driver.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "ply-array.h" -#include "ply-hashtable.h" -#include "ply-logger.h" -#include "ply-renderer-driver.h" - -typedef struct _ply_renderer_buffer ply_renderer_buffer_t; - -struct _ply_renderer_buffer -{ - struct kms_bo *object; - uint32_t id; - unsigned long width; - unsigned long height; - unsigned long row_stride; - - void *map_address; - - uint32_t added_fb : 1; -}; - -struct _ply_renderer_driver -{ - int device_fd; - struct kms_driver *driver; - - ply_hashtable_t *buffers; -}; - -static ply_renderer_driver_t * -create_driver (int device_fd) -{ - ply_renderer_driver_t *driver; - int result; - - driver = calloc (1, sizeof (ply_renderer_driver_t)); - driver->device_fd = device_fd; - - result = kms_create (driver->device_fd, &driver->driver); - if (result != 0) - { - ply_trace ("kms buffer driver could not be initialized: %d", result); - free (driver); - return NULL; - } - - driver->buffers = ply_hashtable_new (ply_hashtable_direct_hash, - ply_hashtable_direct_compare); - - return driver; -} - -static void -destroy_driver (ply_renderer_driver_t *driver) -{ - ply_hashtable_free (driver->buffers); - - ply_trace ("uninitializing kms buffer driver"); - kms_destroy (&driver->driver); - free (driver); -} - -static ply_renderer_buffer_t * -ply_renderer_buffer_new (ply_renderer_driver_t *driver, - struct kms_bo *buffer_object, - uint32_t id, - unsigned long width, - unsigned long height, - unsigned long row_stride) -{ - ply_renderer_buffer_t *buffer; - - buffer = calloc (1, sizeof (ply_renderer_buffer_t)); - buffer->object = buffer_object; - buffer->id = id; - buffer->width = width; - buffer->height = height; - buffer->row_stride = row_stride; - - ply_trace ("returning %lux%lu buffer with stride %lu", - width, height, row_stride); - - return buffer; -} - -static ply_renderer_buffer_t * -get_buffer_from_id (ply_renderer_driver_t *driver, - uint32_t id) -{ - static ply_renderer_buffer_t *buffer; - - buffer = ply_hashtable_lookup (driver->buffers, (void *) (uintptr_t) id); - - return buffer; -} - -static struct kms_bo * -create_kms_bo_from_handle (ply_renderer_driver_t *driver, - uint32_t handle) -{ - struct drm_gem_flink flink_request; - struct kms_bo *buffer_object; - ply_array_t *attributes; - int result; - - /* FIXME: This can't be the right way to do this. - * - * 1) It requires skirting around the API and using ioctls - * 2) It requires taking a local handle, turning it into a - * a global handle ("name"), just so we can use an api that - * will open the global name and grab the local handle from it. - */ - - memset (&flink_request, 0, sizeof (struct drm_gem_flink)); - flink_request.handle = handle; - - if (ioctl (driver->device_fd, DRM_IOCTL_GEM_FLINK, &flink_request) < 0) - { - ply_trace ("Could not export global name for handle %u", handle); - return NULL; - } - - attributes = ply_array_new (PLY_ARRAY_ELEMENT_TYPE_UINT32); - ply_array_add_uint32_element (attributes, KMS_HANDLE); - ply_array_add_uint32_element (attributes, flink_request.name); - ply_array_add_uint32_element (attributes, KMS_TERMINATE_PROP_LIST); - result = kms_bo_create (driver->driver, - (const unsigned *) - ply_array_get_uint32_elements (attributes), - &buffer_object); - ply_array_free (attributes); - - if (result != 0) - { - ply_trace ("could not create buffer object from global name %u: %d", - flink_request.name, result); - return NULL; - } - - return buffer_object; -} - -static ply_renderer_buffer_t * -ply_renderer_buffer_new_from_id (ply_renderer_driver_t *driver, - uint32_t buffer_id) -{ - ply_renderer_buffer_t *buffer; - drmModeFB *fb; - struct kms_bo *buffer_object; - - fb = drmModeGetFB (driver->device_fd, buffer_id); - - if (fb == NULL) - { - ply_trace ("could not get FB with buffer id %u", buffer_id); - return NULL; - } - - buffer_object = create_kms_bo_from_handle (driver, fb->handle); - - if (buffer_object == NULL) - { - ply_trace ("could not create buffer object from handle %lu", - (unsigned long) fb->handle); - drmModeFreeFB (fb); - return NULL; - } - - buffer = ply_renderer_buffer_new (driver, buffer_object, buffer_id, - fb->width, fb->height, fb->pitch); - drmModeFreeFB (fb); - - return buffer; -} - -static bool -fetch_buffer (ply_renderer_driver_t *driver, - uint32_t buffer_id, - unsigned long *width, - unsigned long *height, - unsigned long *row_stride) -{ - ply_renderer_buffer_t *buffer; - - buffer = get_buffer_from_id (driver, buffer_id); - - if (buffer == NULL) - { - ply_trace ("could not fetch buffer %u, creating one", buffer_id); - buffer = ply_renderer_buffer_new_from_id (driver, buffer_id); - - if (buffer == NULL) - { - ply_trace ("could not create buffer either %u", buffer_id); - return false; - } - - ply_hashtable_insert (driver->buffers, - (void *) (uintptr_t) buffer_id, - buffer); - } - - if (width != NULL) - *width = buffer->width; - - if (height != NULL) - *height = buffer->height; - - if (row_stride != NULL) - *row_stride = buffer->row_stride; - - ply_trace ("fetched %lux%lu buffer with stride %lu", - buffer->width, buffer->height, buffer->row_stride); - return true; -} - -static uint32_t -create_buffer (ply_renderer_driver_t *driver, - unsigned long width, - unsigned long height, - unsigned long *row_stride) -{ - struct kms_bo *buffer_object; - ply_renderer_buffer_t *buffer; - uint32_t buffer_id; - int result; - unsigned int handle; - ply_array_t *attributes; - - *row_stride = ply_round_to_multiple (width * 4, 256); - - attributes = ply_array_new (PLY_ARRAY_ELEMENT_TYPE_UINT32); - ply_array_add_uint32_element (attributes, KMS_BO_TYPE); - ply_array_add_uint32_element (attributes, KMS_BO_TYPE_SCANOUT_X8R8G8B8); - ply_array_add_uint32_element (attributes, KMS_WIDTH); - ply_array_add_uint32_element (attributes, (uint32_t) width); - ply_array_add_uint32_element (attributes, KMS_HEIGHT); - ply_array_add_uint32_element (attributes, (uint32_t) height); - ply_array_add_uint32_element (attributes, KMS_PITCH); - ply_array_add_uint32_element (attributes, (uint32_t) *row_stride); - ply_array_add_uint32_element (attributes, KMS_TERMINATE_PROP_LIST); - result = kms_bo_create (driver->driver, - (const unsigned *) - ply_array_get_uint32_elements (attributes), - &buffer_object); - ply_array_free (attributes); - - if (result != 0) - { - ply_trace ("Could not allocate GEM object for frame buffer: %d", result); - return 0; - } - - result = kms_bo_get_prop (buffer_object, KMS_HANDLE, &handle); - - if (result != 0) - { - ply_trace ("Could not retrieve handle from GEM object: %d", result); - - kms_bo_destroy (&buffer_object); - return 0; - } - - if (drmModeAddFB (driver->device_fd, width, height, - 24, 32, *row_stride, handle, - &buffer_id) != 0) - { - ply_trace ("Could not set up GEM object as frame buffer: %m"); - kms_bo_destroy (&buffer_object); - return 0; - } - - buffer = ply_renderer_buffer_new (driver, - buffer_object, buffer_id, - width, height, *row_stride); - buffer->added_fb = true; - ply_hashtable_insert (driver->buffers, - (void *) (uintptr_t) buffer_id, - buffer); - - return buffer_id; -} - -static bool -map_buffer (ply_renderer_driver_t *driver, - uint32_t buffer_id) -{ - ply_renderer_buffer_t *buffer; - int result; - - buffer = get_buffer_from_id (driver, buffer_id); - - assert (buffer != NULL); - - result = kms_bo_map (buffer->object, &buffer->map_address); - - if (result != 0) - { - ply_trace ("could not map buffer %u: %d", buffer_id, result); - buffer->map_address = MAP_FAILED; - return false; - } - - return true; -} - -static void -unmap_buffer (ply_renderer_driver_t *driver, - uint32_t buffer_id) -{ - ply_renderer_buffer_t *buffer; - - buffer = get_buffer_from_id (driver, buffer_id); - - assert (buffer != NULL); - - kms_bo_unmap (buffer->object); - buffer->map_address = MAP_FAILED; -} - -static char * -begin_flush (ply_renderer_driver_t *driver, - uint32_t buffer_id) -{ - ply_renderer_buffer_t *buffer; - - buffer = get_buffer_from_id (driver, buffer_id); - - assert (buffer != NULL); - - return (char *) buffer->map_address; -} - -static void -end_flush (ply_renderer_driver_t *driver, - uint32_t buffer_id) -{ - ply_renderer_buffer_t *buffer; - - buffer = get_buffer_from_id (driver, buffer_id); - - assert (buffer != NULL); -} - -static void -destroy_buffer (ply_renderer_driver_t *driver, - uint32_t buffer_id) -{ - ply_renderer_buffer_t *buffer; - - buffer = get_buffer_from_id (driver, buffer_id); - - assert (buffer != NULL); - - if (buffer->added_fb) - drmModeRmFB (driver->device_fd, buffer->id); - - kms_bo_destroy (&buffer->object); - - ply_hashtable_remove (driver->buffers, - (void *) (uintptr_t) buffer_id); - free (buffer); -} - -ply_renderer_driver_interface_t * -ply_renderer_libkms_driver_get_interface (void) -{ - static ply_renderer_driver_interface_t driver_interface = - { - .create_driver = create_driver, - .destroy_driver = destroy_driver, - .create_buffer = create_buffer, - .fetch_buffer = fetch_buffer, - .map_buffer = map_buffer, - .unmap_buffer = unmap_buffer, - .begin_flush = begin_flush, - .end_flush = end_flush, - .destroy_buffer = destroy_buffer, - }; - - return &driver_interface; -} - -/* vim: set ts=4 sw=4 et ai ci cino={.5s,^-2,+.5s,t0,g0,e-2,n-2,p2s,(0,=.5s,:.5s */ diff --git a/src/plugins/renderers/drm/ply-renderer-libkms-driver.h b/src/plugins/renderers/drm/ply-renderer-libkms-driver.h deleted file mode 100644 index b419a94..0000000 --- a/src/plugins/renderers/drm/ply-renderer-libkms-driver.h +++ /dev/null @@ -1,32 +0,0 @@ -/* ply-renderer-kms-driver.h - * - * Copyright (C) 2009 Red Hat, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - * - * Written By: Ray Strode - */ -#ifndef PLY_RENDERER_LIBKMS_DRIVER_H -#define PLY_RENDERER_LIBKMS_DRIVER_H - -#include "ply-renderer-driver.h" - -#ifndef PLY_HIDE_FUNCTION_DECLARATIONS -ply_renderer_driver_interface_t *ply_renderer_libkms_driver_get_interface (void); -#endif - -#endif /* PLY_RENDERER_LIBKMS_DRIVER_H */ -/* vim: set ts=4 sw=4 et ai ci cino={.5s,^-2,+.5s,t0,g0,e-2,n-2,p2s,(0,=.5s,:.5s */ diff --git a/src/plugins/renderers/drm/ply-renderer-nouveau-driver.c b/src/plugins/renderers/drm/ply-renderer-nouveau-driver.c deleted file mode 100644 index 2cef56e..0000000 --- a/src/plugins/renderers/drm/ply-renderer-nouveau-driver.c +++ /dev/null @@ -1,352 +0,0 @@ -/* ply-renderer-nouveau-driver.c - interface to nouveau drm driver - * - * Copyright (C) 2009 Red Hat, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - * - * Written by: Ray Strode - */ -#include "config.h" - -#include "ply-renderer-nouveau-driver.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "ply-hashtable.h" -#include "ply-logger.h" -#include "ply-renderer-driver.h" - -typedef struct _ply_renderer_buffer ply_renderer_buffer_t; - -struct _ply_renderer_buffer -{ - struct nouveau_bo *object; - uint32_t id; - unsigned long width; - unsigned long height; - unsigned long row_stride; - - uint32_t added_fb : 1; -}; - -struct _ply_renderer_driver -{ - int device_fd; - struct nouveau_device *device; - - ply_hashtable_t *buffers; -}; - -static ply_renderer_driver_t * -create_driver (int device_fd) -{ - ply_renderer_driver_t *driver; - - driver = calloc (1, sizeof (ply_renderer_driver_t)); - driver->device_fd = device_fd; - - if (nouveau_device_open_existing (&driver->device, true, - driver->device_fd, 0) < 0) - { - ply_trace ("could not open nouveau device"); - free (driver); - return NULL; - } - - driver->buffers = ply_hashtable_new (ply_hashtable_direct_hash, - ply_hashtable_direct_compare); - - return driver; -} - -static void -destroy_driver (ply_renderer_driver_t *driver) -{ - ply_hashtable_free (driver->buffers); - - ply_trace ("closing nouveau device"); - nouveau_device_close (&driver->device); - free (driver); -} - -static ply_renderer_buffer_t * -ply_renderer_buffer_new (ply_renderer_driver_t *driver, - struct nouveau_bo *buffer_object, - uint32_t id, - unsigned long width, - unsigned long height, - unsigned long row_stride) -{ - ply_renderer_buffer_t *buffer; - - buffer = calloc (1, sizeof (ply_renderer_buffer_t)); - buffer->object = buffer_object; - buffer->id = id; - buffer->width = width; - buffer->height = height; - buffer->row_stride = row_stride; - - ply_trace ("returning %lux%lu buffer with stride %lu", - width, height, row_stride); - - return buffer; -} - -static ply_renderer_buffer_t * -ply_renderer_buffer_new_from_id (ply_renderer_driver_t *driver, - uint32_t buffer_id) -{ - ply_renderer_buffer_t *buffer; - drmModeFB *fb; - struct nouveau_bo *buffer_object; - - fb = drmModeGetFB (driver->device_fd, buffer_id); - - if (fb == NULL) - { - ply_trace ("could not get FB with buffer id %u", buffer_id); - return NULL; - } - - if (nouveau_bo_wrap (driver->device, - fb->handle, &buffer_object) < 0) - { - ply_trace ("could not create buffer object from handle %lu", - (unsigned long) fb->handle); - drmModeFreeFB (fb); - return NULL; - } - - buffer = ply_renderer_buffer_new (driver, buffer_object, buffer_id, - fb->width, fb->height, fb->pitch); - drmModeFreeFB (fb); - - return buffer; -} - -static ply_renderer_buffer_t * -get_buffer_from_id (ply_renderer_driver_t *driver, - uint32_t id) -{ - static ply_renderer_buffer_t *buffer; - - buffer = ply_hashtable_lookup (driver->buffers, (void *) (uintptr_t) id); - - return buffer; -} - -static bool -fetch_buffer (ply_renderer_driver_t *driver, - uint32_t buffer_id, - unsigned long *width, - unsigned long *height, - unsigned long *row_stride) -{ - ply_renderer_buffer_t *buffer; - - buffer = get_buffer_from_id (driver, buffer_id); - - if (buffer == NULL) - { - ply_trace ("could not fetch buffer %u, creating one", buffer_id); - buffer = ply_renderer_buffer_new_from_id (driver, buffer_id); - - if (buffer == NULL) - { - ply_trace ("could not create buffer either %u", buffer_id); - return false; - } - - ply_hashtable_insert (driver->buffers, - (void *) (uintptr_t) buffer_id, - buffer); - } - - if (width != NULL) - *width = buffer->width; - - if (height != NULL) - *height = buffer->height; - - if (row_stride != NULL) - *row_stride = buffer->row_stride; - - ply_trace ("fetched %lux%lu buffer with stride %lu", - buffer->width, buffer->height, buffer->row_stride); - return true; -} - - -static uint32_t -create_buffer (ply_renderer_driver_t *driver, - unsigned long width, - unsigned long height, - unsigned long *row_stride) -{ - struct nouveau_bo *buffer_object; - ply_renderer_buffer_t *buffer; - uint32_t buffer_id; - - *row_stride = ply_round_to_multiple (width * 4, 256); - - buffer_object = NULL; - if (nouveau_bo_new (driver->device, - NOUVEAU_BO_VRAM | NOUVEAU_BO_MAP, 0, - height * *row_stride, &buffer_object) < 0) - { - ply_trace ("Could not allocate GEM object for frame buffer: %m"); - return 0; - } - - /* The map here forces the buffer object to be instantiated - * immediately (it's normally instantiated lazily when needed - * by other nouveau_bo api) - */ - nouveau_bo_map (buffer_object, NOUVEAU_BO_WR); - if (drmModeAddFB (driver->device_fd, width, height, - 24, 32, *row_stride, buffer_object->handle, - &buffer_id) != 0) - { - nouveau_bo_unmap (buffer_object); - ply_trace ("Could not set up GEM object as frame buffer: %m"); - nouveau_bo_ref (NULL, &buffer_object); - return 0; - } - nouveau_bo_unmap (buffer_object); - - buffer = ply_renderer_buffer_new (driver, - buffer_object, buffer_id, - width, height, *row_stride); - buffer->added_fb = true; - ply_hashtable_insert (driver->buffers, - (void *) (uintptr_t) buffer_id, - buffer); - - return buffer_id; -} - -static bool -map_buffer (ply_renderer_driver_t *driver, - uint32_t buffer_id) -{ - ply_renderer_buffer_t *buffer; - - buffer = get_buffer_from_id (driver, buffer_id); - - assert (buffer != NULL); - - return nouveau_bo_map (buffer->object, NOUVEAU_BO_WR) == 0; -} - -static void -unmap_buffer (ply_renderer_driver_t *driver, - uint32_t buffer_id) -{ - ply_renderer_buffer_t *buffer; - - buffer = get_buffer_from_id (driver, buffer_id); - - assert (buffer != NULL); - - nouveau_bo_unmap (buffer->object); -} - -static char * -begin_flush (ply_renderer_driver_t *driver, - uint32_t buffer_id) -{ - ply_renderer_buffer_t *buffer; - - buffer = get_buffer_from_id (driver, buffer_id); - - assert (buffer != NULL); - - return buffer->object->map; -} - -static void -end_flush (ply_renderer_driver_t *driver, - uint32_t buffer_id) -{ - ply_renderer_buffer_t *buffer; - - buffer = get_buffer_from_id (driver, buffer_id); - - assert (buffer != NULL); -} - -static void -destroy_buffer (ply_renderer_driver_t *driver, - uint32_t buffer_id) -{ - ply_renderer_buffer_t *buffer; - - buffer = get_buffer_from_id (driver, buffer_id); - - assert (buffer != NULL); - - if (buffer->added_fb) - drmModeRmFB (driver->device_fd, buffer->id); - - nouveau_bo_ref (NULL, &buffer->object); - - ply_hashtable_remove (driver->buffers, - (void *) (uintptr_t) buffer_id); - free (buffer); -} - -ply_renderer_driver_interface_t * -ply_renderer_nouveau_driver_get_interface (void) -{ - static ply_renderer_driver_interface_t driver_interface = - { - .create_driver = create_driver, - .destroy_driver = destroy_driver, - .create_buffer = create_buffer, - .fetch_buffer = fetch_buffer, - .map_buffer = map_buffer, - .unmap_buffer = unmap_buffer, - .begin_flush = begin_flush, - .end_flush = end_flush, - .destroy_buffer = destroy_buffer, - }; - - return &driver_interface; -} - -/* vim: set ts=4 sw=4 et ai ci cino={.5s,^-2,+.5s,t0,g0,e-2,n-2,p2s,(0,=.5s,:.5s */ diff --git a/src/plugins/renderers/drm/ply-renderer-nouveau-driver.h b/src/plugins/renderers/drm/ply-renderer-nouveau-driver.h deleted file mode 100644 index 1baed4a..0000000 --- a/src/plugins/renderers/drm/ply-renderer-nouveau-driver.h +++ /dev/null @@ -1,32 +0,0 @@ -/* ply-renderer-nouveau-driver.h - * - * Copyright (C) 2009 Red Hat, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - * - * Written By: Ray Strode - */ -#ifndef PLY_RENDERER_NOUVEAU_DRIVER_H -#define PLY_RENDERER_NOUVEAU_DRIVER_H - -#include "ply-renderer-driver.h" - -#ifndef PLY_HIDE_FUNCTION_DECLARATIONS -ply_renderer_driver_interface_t *ply_renderer_nouveau_driver_get_interface (void); -#endif - -#endif /* PLY_RENDERER_NOUVEAU_DRIVER_H */ -/* vim: set ts=4 sw=4 et ai ci cino={.5s,^-2,+.5s,t0,g0,e-2,n-2,p2s,(0,=.5s,:.5s */ diff --git a/src/plugins/renderers/drm/ply-renderer-radeon-driver.c b/src/plugins/renderers/drm/ply-renderer-radeon-driver.c deleted file mode 100644 index 36cee47..0000000 --- a/src/plugins/renderers/drm/ply-renderer-radeon-driver.c +++ /dev/null @@ -1,377 +0,0 @@ -/* ply-renderer-radeon-driver.c - interface to radeon drm driver - * - * Copyright (C) 2009 Red Hat, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - * - * Written by: Ray Strode - */ -#include "config.h" - -#include "ply-renderer-radeon-driver.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "ply-hashtable.h" -#include "ply-logger.h" -#include "ply-renderer-driver.h" - -typedef struct _ply_renderer_buffer ply_renderer_buffer_t; - -struct _ply_renderer_buffer -{ - struct radeon_bo *object; - uint32_t id; - unsigned long width; - unsigned long height; - unsigned long row_stride; - - uint32_t added_fb : 1; -}; - -struct _ply_renderer_driver -{ - int device_fd; - struct radeon_bo_manager *manager; - - ply_hashtable_t *buffers; -}; - -static ply_renderer_driver_t * -create_driver (int device_fd) -{ - ply_renderer_driver_t *driver; - - driver = calloc (1, sizeof (ply_renderer_driver_t)); - driver->device_fd = device_fd; - - driver->manager = radeon_bo_manager_gem_ctor (driver->device_fd); - if (driver->manager == NULL) - { - ply_trace ("radeon buffer manager could not be initialized"); - free (driver); - return NULL; - } - - driver->buffers = ply_hashtable_new (ply_hashtable_direct_hash, - ply_hashtable_direct_compare); - - return driver; -} - -static void -destroy_driver (ply_renderer_driver_t *driver) -{ - ply_hashtable_free (driver->buffers); - - ply_trace ("uninitializing radeon buffer manager"); - radeon_bo_manager_gem_dtor (driver->manager); - free (driver); -} - -static ply_renderer_buffer_t * -ply_renderer_buffer_new (ply_renderer_driver_t *driver, - struct radeon_bo *buffer_object, - uint32_t id, - unsigned long width, - unsigned long height, - unsigned long row_stride) -{ - ply_renderer_buffer_t *buffer; - - buffer = calloc (1, sizeof (ply_renderer_buffer_t)); - buffer->object = buffer_object; - buffer->id = id; - buffer->width = width; - buffer->height = height; - buffer->row_stride = row_stride; - - ply_trace ("returning %lux%lu buffer with stride %lu", - width, height, row_stride); - - return buffer; -} - -static ply_renderer_buffer_t * -get_buffer_from_id (ply_renderer_driver_t *driver, - uint32_t id) -{ - static ply_renderer_buffer_t *buffer; - - buffer = ply_hashtable_lookup (driver->buffers, (void *) (uintptr_t) id); - - return buffer; -} - -static struct radeon_bo * -create_radeon_bo_from_handle (ply_renderer_driver_t *driver, - uint32_t handle) -{ - struct drm_gem_flink flink_request; - struct radeon_bo *buffer_object; - - /* FIXME: This can't be the right way to do this. - * - * 1) It requires skirting around the API and using ioctls - * 2) It requires taking a local handle, turning it into a - * a global handle ("name"), just so we can use an api that - * will open the global name and grab the local handle from it. - */ - - memset (&flink_request, 0, sizeof (struct drm_gem_flink)); - flink_request.handle = handle; - - if (ioctl (driver->device_fd, DRM_IOCTL_GEM_FLINK, &flink_request) < 0) - { - ply_trace ("Could not export global name for handle %u", handle); - return NULL; - } - - buffer_object = radeon_bo_open (driver->manager, flink_request.name, - 0, 0, RADEON_GEM_DOMAIN_GTT, 0); - - return buffer_object; -} - -static ply_renderer_buffer_t * -ply_renderer_buffer_new_from_id (ply_renderer_driver_t *driver, - uint32_t buffer_id) -{ - ply_renderer_buffer_t *buffer; - drmModeFB *fb; - struct radeon_bo *buffer_object; - - fb = drmModeGetFB (driver->device_fd, buffer_id); - - if (fb == NULL) - { - ply_trace ("could not get FB with buffer id %u", buffer_id); - return NULL; - } - - buffer_object = create_radeon_bo_from_handle (driver, fb->handle); - - if (buffer_object == NULL) - { - ply_trace ("could not create buffer object from handle %lu", - (unsigned long) fb->handle); - drmModeFreeFB (fb); - return NULL; - } - - buffer = ply_renderer_buffer_new (driver, buffer_object, buffer_id, - fb->width, fb->height, fb->pitch); - drmModeFreeFB (fb); - - return buffer; -} - - -static bool -fetch_buffer (ply_renderer_driver_t *driver, - uint32_t buffer_id, - unsigned long *width, - unsigned long *height, - unsigned long *row_stride) -{ - ply_renderer_buffer_t *buffer; - - buffer = get_buffer_from_id (driver, buffer_id); - - if (buffer == NULL) - { - ply_trace ("could not fetch buffer %u, creating one", buffer_id); - buffer = ply_renderer_buffer_new_from_id (driver, buffer_id); - - if (buffer == NULL) - { - ply_trace ("could not create buffer either %u", buffer_id); - return false; - } - - ply_hashtable_insert (driver->buffers, - (void *) (uintptr_t) buffer_id, - buffer); - } - - if (width != NULL) - *width = buffer->width; - - if (height != NULL) - *height = buffer->height; - - if (row_stride != NULL) - *row_stride = buffer->row_stride; - - ply_trace ("fetched %lux%lu buffer with stride %lu", - buffer->width, buffer->height, buffer->row_stride); - return true; -} - -static uint32_t -create_buffer (ply_renderer_driver_t *driver, - unsigned long width, - unsigned long height, - unsigned long *row_stride) -{ - struct radeon_bo *buffer_object; - ply_renderer_buffer_t *buffer; - uint32_t buffer_id; - - *row_stride = ply_round_to_multiple (width * 4, 256); - - buffer_object = radeon_bo_open (driver->manager, 0, - height * *row_stride, - 0, RADEON_GEM_DOMAIN_GTT, 0); - - if (buffer_object == NULL) - { - ply_trace ("Could not allocate GEM object for frame buffer: %m"); - return 0; - } - - if (drmModeAddFB (driver->device_fd, width, height, - 24, 32, *row_stride, buffer_object->handle, - &buffer_id) != 0) - { - ply_trace ("Could not set up GEM object as frame buffer: %m"); - radeon_bo_unref (buffer_object); - return 0; - } - - buffer = ply_renderer_buffer_new (driver, - buffer_object, buffer_id, - width, height, *row_stride); - buffer->added_fb = true; - ply_hashtable_insert (driver->buffers, - (void *) (uintptr_t) buffer_id, - buffer); - - return buffer_id; -} - -static bool -map_buffer (ply_renderer_driver_t *driver, - uint32_t buffer_id) -{ - ply_renderer_buffer_t *buffer; - - buffer = get_buffer_from_id (driver, buffer_id); - - assert (buffer != NULL); - - return radeon_bo_map (buffer->object, true) == 0; -} - -static void -unmap_buffer (ply_renderer_driver_t *driver, - uint32_t buffer_id) -{ - ply_renderer_buffer_t *buffer; - - buffer = get_buffer_from_id (driver, buffer_id); - - assert (buffer != NULL); - - radeon_bo_unmap (buffer->object); -} - -static char * -begin_flush (ply_renderer_driver_t *driver, - uint32_t buffer_id) -{ - ply_renderer_buffer_t *buffer; - - buffer = get_buffer_from_id (driver, buffer_id); - - assert (buffer != NULL); - - return buffer->object->ptr; -} - -static void -end_flush (ply_renderer_driver_t *driver, - uint32_t buffer_id) -{ - ply_renderer_buffer_t *buffer; - - buffer = get_buffer_from_id (driver, buffer_id); - - assert (buffer != NULL); -} - -static void -destroy_buffer (ply_renderer_driver_t *driver, - uint32_t buffer_id) -{ - ply_renderer_buffer_t *buffer; - - buffer = get_buffer_from_id (driver, buffer_id); - - assert (buffer != NULL); - - if (buffer->added_fb) - drmModeRmFB (driver->device_fd, buffer->id); - - radeon_bo_unref (buffer->object); - - ply_hashtable_remove (driver->buffers, - (void *) (uintptr_t) buffer_id); - free (buffer); -} - -ply_renderer_driver_interface_t * -ply_renderer_radeon_driver_get_interface (void) -{ - static ply_renderer_driver_interface_t driver_interface = - { - .create_driver = create_driver, - .destroy_driver = destroy_driver, - .create_buffer = create_buffer, - .fetch_buffer = fetch_buffer, - .map_buffer = map_buffer, - .unmap_buffer = unmap_buffer, - .begin_flush = begin_flush, - .end_flush = end_flush, - .destroy_buffer = destroy_buffer, - }; - - return &driver_interface; -} - -/* vim: set ts=4 sw=4 et ai ci cino={.5s,^-2,+.5s,t0,g0,e-2,n-2,p2s,(0,=.5s,:.5s */ diff --git a/src/plugins/renderers/drm/ply-renderer-radeon-driver.h b/src/plugins/renderers/drm/ply-renderer-radeon-driver.h deleted file mode 100644 index dcec1b1..0000000 --- a/src/plugins/renderers/drm/ply-renderer-radeon-driver.h +++ /dev/null @@ -1,32 +0,0 @@ -/* ply-renderer-radeon-driver.h - * - * Copyright (C) 2009 Red Hat, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - * - * Written By: Ray Strode - */ -#ifndef PLY_RENDERER_RADEON_DRIVER_H -#define PLY_RENDERER_RADEON_DRIVER_H - -#include "ply-renderer-driver.h" - -#ifndef PLY_HIDE_FUNCTION_DECLARATIONS -ply_renderer_driver_interface_t *ply_renderer_radeon_driver_get_interface (void); -#endif - -#endif /* PLY_RENDERER_RADEON_DRIVER_H */ -/* vim: set ts=4 sw=4 et ai ci cino={.5s,^-2,+.5s,t0,g0,e-2,n-2,p2s,(0,=.5s,:.5s */ diff --git a/src/plugins/renderers/frame-buffer/Makefile.am b/src/plugins/renderers/frame-buffer/Makefile.am index 44f9d6a..12e1470 100644 --- a/src/plugins/renderers/frame-buffer/Makefile.am +++ b/src/plugins/renderers/frame-buffer/Makefile.am @@ -1,4 +1,4 @@ -INCLUDES = -I$(top_srcdir) \ +AM_CPPFLAGS = -I$(top_srcdir) \ -I$(srcdir)/../../../libply \ -I$(srcdir)/../../../libply-splash-core \ -I$(srcdir)/../../.. \ diff --git a/src/plugins/renderers/frame-buffer/plugin.c b/src/plugins/renderers/frame-buffer/plugin.c index 0e07943..dd73a0f 100644 --- a/src/plugins/renderers/frame-buffer/plugin.c +++ b/src/plugins/renderers/frame-buffer/plugin.c @@ -351,6 +351,9 @@ open_device (ply_renderer_backend_t *backend) return false; } + if (backend->terminal == NULL) + return true; + if (!ply_terminal_open (backend->terminal)) { ply_trace ("could not open terminal: %m"); @@ -376,10 +379,11 @@ static void close_device (ply_renderer_backend_t *backend) { - ply_terminal_stop_watching_for_active_vt_change (backend->terminal, - (ply_terminal_active_vt_changed_handler_t) - on_active_vt_changed, - backend); + if (backend->terminal != NULL) + ply_terminal_stop_watching_for_active_vt_change (backend->terminal, + (ply_terminal_active_vt_changed_handler_t) + on_active_vt_changed, + backend); uninitialize_head (backend, &backend->head); close (backend->device_fd); @@ -546,15 +550,22 @@ map_to_device (ply_renderer_backend_t *backend) return false; } - if (ply_terminal_is_active (backend->terminal)) + if (backend->terminal != NULL) { - ply_trace ("already on right vt, activating"); - activate (backend); + if (ply_terminal_is_active (backend->terminal)) + { + ply_trace ("already on right vt, activating"); + activate (backend); + } + else + { + ply_trace ("on wrong vt, changing vts"); + ply_terminal_activate_vt (backend->terminal); + } } else { - ply_trace ("on wrong vt, changing vts"); - ply_terminal_activate_vt (backend->terminal); + activate (backend); } return true; @@ -590,8 +601,11 @@ flush_head (ply_renderer_backend_t *backend, if (!backend->is_active) return; - ply_terminal_set_mode (backend->terminal, PLY_TERMINAL_MODE_GRAPHICS); - ply_terminal_set_unbuffered_input (backend->terminal); + if (backend->terminal != NULL) + { + ply_terminal_set_mode (backend->terminal, PLY_TERMINAL_MODE_GRAPHICS); + ply_terminal_set_unbuffered_input (backend->terminal); + } pixel_buffer = head->pixel_buffer; updated_region = ply_pixel_buffer_get_updated_areas (pixel_buffer); areas_to_flush = ply_region_get_sorted_rectangle_list (updated_region); @@ -685,6 +699,9 @@ open_input_source (ply_renderer_backend_t *backend, assert (backend != NULL); assert (has_input_source (backend, input_source)); + if (backend->terminal == NULL) + return false; + terminal_fd = ply_terminal_get_fd (backend->terminal); input_source->backend = backend; @@ -715,6 +732,9 @@ close_input_source (ply_renderer_backend_t *backend, assert (backend != NULL); assert (has_input_source (backend, input_source)); + if (backend->terminal == NULL) + return; + ply_event_loop_stop_watching_fd (backend->loop, input_source->terminal_input_watch); input_source->terminal_input_watch = NULL; input_source->backend = NULL; diff --git a/src/plugins/renderers/x11/Makefile.am b/src/plugins/renderers/x11/Makefile.am index fd142c0..33513ac 100644 --- a/src/plugins/renderers/x11/Makefile.am +++ b/src/plugins/renderers/x11/Makefile.am @@ -1,4 +1,4 @@ -INCLUDES = -I$(top_srcdir) \ +AM_CPPFLAGS = -I$(top_srcdir) \ -I$(srcdir)/../../../libply \ -I$(srcdir)/../../../libply-splash-core \ -I$(srcdir)/../../.. \ diff --git a/src/plugins/splash/Makefile.am b/src/plugins/splash/Makefile.am index 02f94fa..a19197b 100644 --- a/src/plugins/splash/Makefile.am +++ b/src/plugins/splash/Makefile.am @@ -1,2 +1,2 @@ -SUBDIRS = throbgress fade-throbber text details space-flares two-step script +SUBDIRS = throbgress fade-throbber text details space-flares two-step script tribar MAINTAINERCLEANFILES = Makefile.in diff --git a/src/plugins/splash/details/Makefile.am b/src/plugins/splash/details/Makefile.am index a656129..3be4755 100644 --- a/src/plugins/splash/details/Makefile.am +++ b/src/plugins/splash/details/Makefile.am @@ -1,4 +1,4 @@ -INCLUDES = -I$(top_srcdir) \ +AM_CPPFLAGS = -I$(top_srcdir) \ -I$(srcdir)/../../../libply \ -I$(srcdir)/../../../libply-splash-core \ -I$(srcdir)/../../.. \ diff --git a/src/plugins/splash/fade-throbber/Makefile.am b/src/plugins/splash/fade-throbber/Makefile.am index f7b559b..6bbb490 100644 --- a/src/plugins/splash/fade-throbber/Makefile.am +++ b/src/plugins/splash/fade-throbber/Makefile.am @@ -1,4 +1,4 @@ -INCLUDES = -I$(top_srcdir) \ +AM_CPPFLAGS = -I$(top_srcdir) \ -I$(srcdir)/../../../libply \ -I$(srcdir)/../../../libply-splash-core \ -I$(srcdir)/../../../libply-splash-graphics \ diff --git a/src/plugins/splash/script/Makefile.am b/src/plugins/splash/script/Makefile.am index 0f2b0f7..ce46df6 100644 --- a/src/plugins/splash/script/Makefile.am +++ b/src/plugins/splash/script/Makefile.am @@ -1,4 +1,4 @@ -INCLUDES = -I$(top_srcdir) \ +AM_CPPFLAGS = -I$(top_srcdir) \ -I$(srcdir)/../../../libply \ -I$(srcdir)/../../../libply-splash-core \ -I$(srcdir)/../../../libply-splash-graphics \ diff --git a/src/plugins/splash/script/script-debug.c b/src/plugins/splash/script/script-debug.c index 355c2b2..118574b 100644 --- a/src/plugins/splash/script/script-debug.c +++ b/src/plugins/splash/script/script-debug.c @@ -19,6 +19,10 @@ * * Written by: Charlie Brej */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "ply-hashtable.h" #include #include diff --git a/src/plugins/splash/script/script-execute.c b/src/plugins/splash/script/script-execute.c index 6abd3a6..c06959b 100644 --- a/src/plugins/splash/script/script-execute.c +++ b/src/plugins/splash/script/script-execute.c @@ -19,7 +19,11 @@ * * Written by: Charlie Brej */ -#define _GNU_SOURCE + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "ply-hashtable.h" #include "ply-list.h" #include "ply-logger.h" diff --git a/src/plugins/splash/script/script-lib-image.c b/src/plugins/splash/script/script-lib-image.c index 5be27fb..f08be31 100644 --- a/src/plugins/splash/script/script-lib-image.c +++ b/src/plugins/splash/script/script-lib-image.c @@ -19,7 +19,9 @@ * * Written by: Charlie Brej */ -#define _GNU_SOURCE + +#include "config.h" + #include "ply-image.h" #include "ply-label.h" #include "ply-pixel-buffer.h" @@ -36,8 +38,6 @@ #include #include -#include "config.h" - #include "script-lib-image.script.h" static void image_free (script_obj_t *obj) diff --git a/src/plugins/splash/script/script-lib-math.c b/src/plugins/splash/script/script-lib-math.c index a1afc04..3f2dc79 100644 --- a/src/plugins/splash/script/script-lib-math.c +++ b/src/plugins/splash/script/script-lib-math.c @@ -19,7 +19,10 @@ * * Written by: Charlie Brej */ -#define _GNU_SOURCE + +#include "config.h" + +#include "ply-utils.h" #include "script.h" #include "script-parse.h" #include "script-execute.h" @@ -31,7 +34,6 @@ #include #include -#include "config.h" #include "script-lib-math.script.h" diff --git a/src/plugins/splash/script/script-lib-plymouth.c b/src/plugins/splash/script/script-lib-plymouth.c index 5c648a6..ab2ec44 100644 --- a/src/plugins/splash/script/script-lib-plymouth.c +++ b/src/plugins/splash/script/script-lib-plymouth.c @@ -19,7 +19,9 @@ * * Written by: Charlie Brej */ -#define _GNU_SOURCE + +#include "config.h" + #include "ply-boot-splash-plugin.h" #include "ply-utils.h" #include "script.h" @@ -32,8 +34,6 @@ #include #include -#include "config.h" - #include "script-lib-plymouth.script.h" static script_return_t plymouth_set_function (script_state_t *state, @@ -64,6 +64,7 @@ static script_return_t plymouth_get_mode (script_state_t *state, case PLY_BOOT_SPLASH_MODE_UPDATES: obj = script_obj_new_string ("updates"); break; + case PLY_BOOT_SPLASH_MODE_INVALID: default: obj = script_obj_new_string ("unknown"); break; diff --git a/src/plugins/splash/script/script-lib-string.c b/src/plugins/splash/script/script-lib-string.c index dbd63fe..0b836eb 100644 --- a/src/plugins/splash/script/script-lib-string.c +++ b/src/plugins/splash/script/script-lib-string.c @@ -19,7 +19,9 @@ * * Written by: Charlie Brej */ -#define _GNU_SOURCE + +#include "config.h" + #include "script.h" #include "script-parse.h" #include "script-execute.h" @@ -31,8 +33,6 @@ #include #include -#include "config.h" - #include "script-lib-string.script.h" diff --git a/src/plugins/splash/script/script-object.c b/src/plugins/splash/script/script-object.c index 465fef6..7c16c94 100644 --- a/src/plugins/splash/script/script-object.c +++ b/src/plugins/splash/script/script-object.c @@ -19,7 +19,11 @@ * * Written by: Charlie Brej */ -#define _GNU_SOURCE + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "ply-hashtable.h" #include "ply-list.h" #include "ply-bitarray.h" diff --git a/src/plugins/splash/script/script-parse.c b/src/plugins/splash/script/script-parse.c index 10eb667..4adf273 100644 --- a/src/plugins/splash/script/script-parse.c +++ b/src/plugins/splash/script/script-parse.c @@ -19,7 +19,11 @@ * * Written by: Charlie Brej */ -#define _GNU_SOURCE + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "ply-hashtable.h" #include "ply-list.h" #include "ply-bitarray.h" diff --git a/src/plugins/splash/script/script-scan.c b/src/plugins/splash/script/script-scan.c index ead752f..5d1aa64 100644 --- a/src/plugins/splash/script/script-scan.c +++ b/src/plugins/splash/script/script-scan.c @@ -19,6 +19,10 @@ * * Written by: Charlie Brej */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include @@ -26,6 +30,7 @@ #include #include #include +#include #include "ply-bitarray.h" #include "script-scan.h" @@ -61,7 +66,7 @@ static script_scan_t *script_scan_new (void) script_scan_t *script_scan_file (const char *filename) { - int fd = open (filename, O_RDONLY); + int fd = open (filename, O_RDONLY|O_CLOEXEC); if (fd < 0) return NULL; script_scan_t *scan = script_scan_new (); scan->name = strdup (filename); @@ -367,11 +372,13 @@ static script_scan_token_t *script_scan_peek_token (script_scan_t *scan, { int i; - if (scan->tokencount <= n) + /* we're screwed long before we ever actually hit INT_MAX; but at least + * we shouldn't get ourselves stuck in an infinite loop. */ + if (scan->tokencount <= n && n < INT_MAX) { scan->tokens = realloc (scan->tokens, (n + 1) * sizeof (script_scan_token_t *)); - for (i = scan->tokencount; i <= n; i++) /* FIXME warning about possibely inifnite loop */ + for (i = scan->tokencount; i <= n; i++) { scan->tokens[i] = malloc (sizeof (script_scan_token_t)); scan->tokens[i]->type = SCRIPT_SCAN_TOKEN_TYPE_EMPTY; diff --git a/src/plugins/splash/script/script.c b/src/plugins/splash/script/script.c index 635a8b4..3290825 100644 --- a/src/plugins/splash/script/script.c +++ b/src/plugins/splash/script/script.c @@ -19,7 +19,11 @@ * * Written by: Charlie Brej */ -#define _GNU_SOURCE + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "ply-hashtable.h" #include "ply-list.h" #include "ply-bitarray.h" diff --git a/src/plugins/splash/space-flares/Makefile.am b/src/plugins/splash/space-flares/Makefile.am index 0d22a2e..24fdb39 100644 --- a/src/plugins/splash/space-flares/Makefile.am +++ b/src/plugins/splash/space-flares/Makefile.am @@ -1,4 +1,4 @@ -INCLUDES = -I$(top_srcdir) \ +AM_CPPFLAGS = -I$(top_srcdir) \ -I$(srcdir)/../../../libply \ -I$(srcdir)/../../../libply-splash-core \ -I$(srcdir)/../../../libply-splash-graphics \ diff --git a/src/plugins/splash/text/Makefile.am b/src/plugins/splash/text/Makefile.am index f4c21a8..7ccefb2 100644 --- a/src/plugins/splash/text/Makefile.am +++ b/src/plugins/splash/text/Makefile.am @@ -1,4 +1,4 @@ -INCLUDES = -I$(top_srcdir) \ +AM_CPPFLAGS = -I$(top_srcdir) \ -I$(srcdir)/../../../libply \ -I$(srcdir)/../../../libply-splash-core \ -I$(srcdir)/../../.. \ diff --git a/src/plugins/splash/text/plugin.c b/src/plugins/splash/text/plugin.c index af81635..fb97c14 100644 --- a/src/plugins/splash/text/plugin.c +++ b/src/plugins/splash/text/plugin.c @@ -1,6 +1,5 @@ -/* text.c - boot splash plugin - * - * Copyright (C) 2008 Red Hat, Inc. +/* + * Copyright (C) 2008-2012 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,8 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. * - * Written by: Adam Jackson - * Ray Strode */ #include "config.h" @@ -49,7 +46,7 @@ #include "ply-list.h" #include "ply-logger.h" #include "ply-text-display.h" -#include "ply-text-progress-bar.h" +#include "ply-text-step-bar.h" #include "ply-utils.h" #include @@ -78,7 +75,7 @@ typedef struct { ply_boot_splash_plugin_t *plugin; ply_text_display_t *display; - ply_text_progress_bar_t *progress_bar; + ply_text_step_bar_t *step_bar; } view_t; @@ -97,7 +94,7 @@ view_new (ply_boot_splash_plugin_t *plugin, view->plugin = plugin; view->display = display; - view->progress_bar = ply_text_progress_bar_new (); + view->step_bar = ply_text_step_bar_new (); return view; } @@ -105,7 +102,7 @@ view_new (ply_boot_splash_plugin_t *plugin, static void view_free (view_t *view) { - ply_text_progress_bar_free (view->progress_bar); + ply_text_step_bar_free (view->step_bar); free (view); } @@ -180,10 +177,10 @@ view_start_animation (view_t *view) 0xffffff); ply_terminal_set_color_hex_value (terminal, PLY_TERMINAL_COLOR_BLUE, - 0x0073B3); + 0x3465a4); ply_terminal_set_color_hex_value (terminal, PLY_TERMINAL_COLOR_BROWN, - 0x00457E); + 0x979a9b); ply_text_display_set_background_color (view->display, PLY_TERMINAL_COLOR_BLACK); @@ -192,11 +189,11 @@ view_start_animation (view_t *view) if (plugin->mode == PLY_BOOT_SPLASH_MODE_SHUTDOWN) { - ply_text_progress_bar_hide (view->progress_bar); + ply_text_step_bar_hide (view->step_bar); return; } - ply_text_progress_bar_show (view->progress_bar, + ply_text_step_bar_show (view->step_bar, view->display); } @@ -452,7 +449,7 @@ stop_animation (ply_boot_splash_plugin_t *plugin) view = ply_list_node_get_data (node); next_node = ply_list_get_next_node (plugin->views, node); - ply_text_progress_bar_hide (view->progress_bar); + ply_text_step_bar_hide (view->step_bar); node = next_node; } @@ -571,8 +568,8 @@ on_boot_progress (ply_boot_splash_plugin_t *plugin, view = ply_list_node_get_data (node); next_node = ply_list_get_next_node (plugin->views, node); - ply_text_progress_bar_set_percent_done (view->progress_bar, percent_done); - ply_text_progress_bar_draw (view->progress_bar); + ply_text_step_bar_set_percent_done (view->step_bar, percent_done); + ply_text_step_bar_draw (view->step_bar); node = next_node; } diff --git a/src/plugins/splash/throbgress/Makefile.am b/src/plugins/splash/throbgress/Makefile.am index 8f93fd2..2ac1b0c 100644 --- a/src/plugins/splash/throbgress/Makefile.am +++ b/src/plugins/splash/throbgress/Makefile.am @@ -1,4 +1,4 @@ -INCLUDES = -I$(top_srcdir) \ +AM_CPPFLAGS = -I$(top_srcdir) \ -I$(srcdir)/../../../libply \ -I$(srcdir)/../../../libply-splash-core \ -I$(srcdir)/../../../libply-splash-graphics \ diff --git a/src/plugins/splash/throbgress/plugin.c b/src/plugins/splash/throbgress/plugin.c index 5ed6c06..fba809b 100644 --- a/src/plugins/splash/throbgress/plugin.c +++ b/src/plugins/splash/throbgress/plugin.c @@ -247,6 +247,8 @@ pause_views (ply_boot_splash_plugin_t *plugin) { ply_list_node_t *node; + ply_trace ("pausing views"); + node = ply_list_get_first_node (plugin->views); while (node != NULL) { @@ -267,6 +269,8 @@ unpause_views (ply_boot_splash_plugin_t *plugin) { ply_list_node_t *node; + ply_trace ("unpausing views"); + node = ply_list_get_first_node (plugin->views); while (node != NULL) { @@ -431,6 +435,8 @@ destroy_plugin (ply_boot_splash_plugin_t *plugin) if (plugin == NULL) return; + ply_trace ("destroying plugin"); + if (plugin->loop != NULL) { ply_event_loop_stop_watching_for_exit (plugin->loop, (ply_event_loop_exit_handler_t) @@ -510,6 +516,8 @@ start_animation (ply_boot_splash_plugin_t *plugin) if (plugin->is_animating) return; + ply_trace ("starting animation"); + node = ply_list_get_first_node (plugin->views); while (node != NULL) { @@ -542,6 +550,9 @@ stop_animation (ply_boot_splash_plugin_t *plugin, if (!plugin->is_animating) return; + ply_trace ("stopping animation%s", + trigger != NULL? " with trigger" : ""); + plugin->is_animating = false; node = ply_list_get_first_node (plugin->views); @@ -619,6 +630,7 @@ add_pixel_display (ply_boot_splash_plugin_t *plugin, { view_t *view; + ply_trace ("adding pixel display to plugin"); view = view_new (plugin, display); ply_pixel_display_set_draw_handler (view->display, @@ -634,6 +646,7 @@ remove_pixel_display (ply_boot_splash_plugin_t *plugin, { ply_list_node_t *node; + ply_trace ("removing pixel display from plugin"); node = ply_list_get_first_node (plugin->views); while (node != NULL) { @@ -745,6 +758,7 @@ hide_splash_screen (ply_boot_splash_plugin_t *plugin, { assert (plugin != NULL); + ply_trace ("hiding splash"); if (plugin->loop != NULL) { stop_animation (plugin, NULL); @@ -765,6 +779,7 @@ show_password_prompt (ply_boot_splash_plugin_t *plugin, { ply_list_node_t *node; + ply_trace ("showing password prompt"); node = ply_list_get_first_node (plugin->views); while (node != NULL) { @@ -788,6 +803,7 @@ show_prompt (ply_boot_splash_plugin_t *plugin, { ply_list_node_t *node; + ply_trace ("showing prompt"); node = ply_list_get_first_node (plugin->views); while (node != NULL) { @@ -807,6 +823,7 @@ show_prompt (ply_boot_splash_plugin_t *plugin, static void on_root_mounted (ply_boot_splash_plugin_t *plugin) { + ply_trace ("root filesystem mounted"); plugin->root_is_mounted = true; } @@ -814,8 +831,10 @@ static void become_idle (ply_boot_splash_plugin_t *plugin, ply_trigger_t *idle_trigger) { + ply_trace ("deactivation requested"); if (plugin->is_idle) { + ply_trace ("plugin is already idle"); ply_trigger_pull (idle_trigger, NULL); return; } @@ -829,6 +848,7 @@ hide_prompt (ply_boot_splash_plugin_t *plugin) { ply_list_node_t *node; + ply_trace ("hiding prompt"); node = ply_list_get_first_node (plugin->views); while (node != NULL) { @@ -844,6 +864,7 @@ hide_prompt (ply_boot_splash_plugin_t *plugin) } } + static void show_message (ply_boot_splash_plugin_t *plugin, const char *message) diff --git a/src/plugins/splash/tribar/Makefile.am b/src/plugins/splash/tribar/Makefile.am new file mode 100644 index 0000000..9b11502 --- /dev/null +++ b/src/plugins/splash/tribar/Makefile.am @@ -0,0 +1,23 @@ +AM_CPPFLAGS = -I$(top_srcdir) \ + -I$(srcdir)/../../../libply \ + -I$(srcdir)/../../../libply-splash-core \ + -I$(srcdir)/../../.. \ + -I$(srcdir)/../.. \ + -I$(srcdir)/.. \ + -I$(srcdir) + +plugindir = $(libdir)/plymouth +plugin_LTLIBRARIES = tribar.la + +tribar_la_CFLAGS = $(PLYMOUTH_CFLAGS) \ + -DPLYMOUTH_BACKGROUND_COLOR=$(background_color) \ + -DPLYMOUTH_BACKGROUND_END_COLOR=$(background_end_color) \ + -DPLYMOUTH_BACKGROUND_START_COLOR=$(background_start_color) + +tribar_la_LDFLAGS = -module -avoid-version -export-dynamic +tribar_la_LIBADD = $(PLYMOUTH_LIBS) \ + ../../../libply/libply.la \ + ../../../libply-splash-core/libply-splash-core.la +tribar_la_SOURCES = $(srcdir)/plugin.c + +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/plugins/splash/tribar/plugin.c b/src/plugins/splash/tribar/plugin.c new file mode 100644 index 0000000..4458bad --- /dev/null +++ b/src/plugins/splash/tribar/plugin.c @@ -0,0 +1,740 @@ +/* + * + * Copyright (C) 2008 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: Adam Jackson + * Ray Strode + */ +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ply-trigger.h" +#include "ply-boot-splash-plugin.h" +#include "ply-buffer.h" +#include "ply-event-loop.h" +#include "ply-key-file.h" +#include "ply-list.h" +#include "ply-logger.h" +#include "ply-text-display.h" +#include "ply-text-progress-bar.h" +#include "ply-utils.h" + +#include + +typedef enum { + PLY_BOOT_SPLASH_DISPLAY_NORMAL, + PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY, + PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY +} ply_boot_splash_display_type_t; + +struct _ply_boot_splash_plugin +{ + ply_event_loop_t *loop; + ply_boot_splash_mode_t mode; + + ply_list_t *views; + + ply_boot_splash_display_type_t state; + + char *message; + + uint32_t is_animating : 1; +}; + +typedef struct +{ + ply_boot_splash_plugin_t *plugin; + ply_text_display_t *display; + ply_text_progress_bar_t *progress_bar; + +} view_t; + +ply_boot_splash_plugin_interface_t *ply_boot_splash_plugin_get_interface (void); + +static void hide_splash_screen (ply_boot_splash_plugin_t *plugin, + ply_event_loop_t *loop); + +static view_t * +view_new (ply_boot_splash_plugin_t *plugin, + ply_text_display_t *display) +{ + view_t *view; + + view = calloc (1, sizeof (view_t)); + view->plugin = plugin; + view->display = display; + + view->progress_bar = ply_text_progress_bar_new (); + + return view; +} + +static void +view_free (view_t *view) +{ + ply_text_progress_bar_free (view->progress_bar); + + free (view); +} + +static void +view_show_message (view_t *view) +{ + ply_boot_splash_plugin_t *plugin; + int display_width, display_height; + + plugin = view->plugin; + + display_width = ply_text_display_get_number_of_columns (view->display); + display_height = ply_text_display_get_number_of_rows (view->display); + + ply_text_display_set_cursor_position (view->display, 0, + display_height / 2); + ply_text_display_clear_line (view->display); + ply_text_display_set_cursor_position (view->display, + (display_width - + strlen (plugin->message)) / 2, + display_height / 2); + + ply_text_display_write (view->display, "%s", plugin->message); +} + +static void +view_show_prompt (view_t *view, + const char *prompt, + const char *entered_text) +{ + + int display_width, display_height; + int i; + + display_width = ply_text_display_get_number_of_columns (view->display); + display_height = ply_text_display_get_number_of_rows (view->display); + ply_text_display_set_background_color (view->display, PLY_TERMINAL_COLOR_DEFAULT); + ply_text_display_clear_screen (view->display); + + ply_text_display_set_cursor_position (view->display, 0, display_height / 2); + + for (i=0; i < display_width; i++) + ply_text_display_write (view->display, "%c", ' '); + + ply_text_display_set_cursor_position (view->display, + display_width / 2 - (strlen (prompt)), + display_height / 2); + + ply_text_display_write (view->display, "%s:%s", prompt, entered_text); + + ply_text_display_show_cursor (view->display); +} + +static void +view_start_animation (view_t *view) +{ + ply_boot_splash_plugin_t *plugin; + ply_terminal_t *terminal; + + assert (view != NULL); + + plugin = view->plugin; + + terminal = ply_text_display_get_terminal (view->display); + + ply_terminal_set_color_hex_value (terminal, + PLY_TERMINAL_COLOR_BLACK, + 0x000000); + ply_terminal_set_color_hex_value (terminal, + PLY_TERMINAL_COLOR_WHITE, + 0xffffff); + ply_terminal_set_color_hex_value (terminal, + PLY_TERMINAL_COLOR_BLUE, + 0x0073B3); + ply_terminal_set_color_hex_value (terminal, + PLY_TERMINAL_COLOR_BROWN, + 0x00457E); + + ply_text_display_set_background_color (view->display, + PLY_TERMINAL_COLOR_BLACK); + ply_text_display_clear_screen (view->display); + ply_text_display_hide_cursor (view->display); + + if (plugin->mode == PLY_BOOT_SPLASH_MODE_SHUTDOWN) + { + ply_text_progress_bar_hide (view->progress_bar); + return; + } + + ply_text_progress_bar_show (view->progress_bar, + view->display); +} + +static void +view_redraw (view_t *view) +{ + unsigned long screen_width, screen_height; + + screen_width = ply_text_display_get_number_of_columns (view->display); + screen_height = ply_text_display_get_number_of_rows (view->display); + + ply_text_display_draw_area (view->display, 0, 0, + screen_width, screen_height); +} + +static void +redraw_views (ply_boot_splash_plugin_t *plugin) +{ + ply_list_node_t *node; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + view_redraw (view); + + node = next_node; + } +} + +static void +view_hide (view_t *view) +{ + if (view->display != NULL) + { + ply_terminal_t *terminal; + + terminal = ply_text_display_get_terminal (view->display); + + ply_text_display_set_background_color (view->display, PLY_TERMINAL_COLOR_DEFAULT); + ply_text_display_clear_screen (view->display); + ply_text_display_show_cursor (view->display); + + ply_terminal_reset_colors (terminal); + } +} + +static void +hide_views (ply_boot_splash_plugin_t *plugin) +{ + ply_list_node_t *node; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + view_hide (view); + + node = next_node; + } +} + +static void +pause_views (ply_boot_splash_plugin_t *plugin) +{ + ply_list_node_t *node; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + ply_text_display_pause_updates (view->display); + + node = next_node; + } +} + +static void +unpause_views (ply_boot_splash_plugin_t *plugin) +{ + ply_list_node_t *node; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + ply_text_display_unpause_updates (view->display); + + node = next_node; + } +} + +static ply_boot_splash_plugin_t * +create_plugin (ply_key_file_t *key_file) +{ + ply_boot_splash_plugin_t *plugin; + + ply_trace ("creating plugin"); + + plugin = calloc (1, sizeof (ply_boot_splash_plugin_t)); + plugin->message = NULL; + + plugin->views = ply_list_new (); + + return plugin; +} + +static void +detach_from_event_loop (ply_boot_splash_plugin_t *plugin) +{ + plugin->loop = NULL; + + ply_trace ("detaching from event loop"); +} + +static void +free_views (ply_boot_splash_plugin_t *plugin) +{ + ply_list_node_t *node; + + node = ply_list_get_first_node (plugin->views); + + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + view_free (view); + ply_list_remove_node (plugin->views, node); + + node = next_node; + } + + ply_list_free (plugin->views); + plugin->views = NULL; +} + +static void +destroy_plugin (ply_boot_splash_plugin_t *plugin) +{ + ply_trace ("destroying plugin"); + + if (plugin == NULL) + return; + + /* It doesn't ever make sense to keep this plugin on screen + * after exit + */ + hide_splash_screen (plugin, plugin->loop); + + free_views (plugin); + if (plugin->message != NULL) + free (plugin->message); + + free (plugin); +} + +static void +show_message (ply_boot_splash_plugin_t *plugin) +{ + ply_list_node_t *node; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + view_show_message (view); + + node = next_node; + } +} + +static void +start_animation (ply_boot_splash_plugin_t *plugin) +{ + ply_list_node_t *node; + + assert (plugin != NULL); + assert (plugin->loop != NULL); + + redraw_views (plugin); + + if (plugin->message != NULL) + show_message (plugin); + + if (plugin->is_animating) + return; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + view_start_animation (view); + + node = next_node; + } + + plugin->is_animating = true; +} + +static void +stop_animation (ply_boot_splash_plugin_t *plugin) +{ + ply_list_node_t *node; + + assert (plugin != NULL); + assert (plugin->loop != NULL); + + if (!plugin->is_animating) + return; + + plugin->is_animating = false; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + ply_text_progress_bar_hide (view->progress_bar); + + node = next_node; + } + redraw_views (plugin); +} + +static void +on_draw (view_t *view, + ply_terminal_t *terminal, + int x, + int y, + int width, + int height) +{ + ply_text_display_clear_screen (view->display); +} + +static void +add_text_display (ply_boot_splash_plugin_t *plugin, + ply_text_display_t *display) +{ + view_t *view; + ply_terminal_t *terminal; + + view = view_new (plugin, display); + + terminal = ply_text_display_get_terminal (view->display); + if (ply_terminal_open (terminal)) + ply_terminal_activate_vt (terminal); + + ply_text_display_set_draw_handler (view->display, + (ply_text_display_draw_handler_t) + on_draw, view); + + ply_list_append_data (plugin->views, view); +} + +static void +remove_text_display (ply_boot_splash_plugin_t *plugin, + ply_text_display_t *display) +{ + ply_list_node_t *node; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + view_t *view; + ply_list_node_t *next_node; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + if (view->display == display) + { + ply_text_display_set_draw_handler (view->display, + NULL, NULL); + view_free (view); + ply_list_remove_node (plugin->views, node); + return; + } + + node = next_node; + } +} + +static bool +show_splash_screen (ply_boot_splash_plugin_t *plugin, + ply_event_loop_t *loop, + ply_buffer_t *boot_buffer, + ply_boot_splash_mode_t mode) +{ + assert (plugin != NULL); + + plugin->loop = loop; + plugin->mode = mode; + ply_event_loop_watch_for_exit (loop, (ply_event_loop_exit_handler_t) + detach_from_event_loop, + plugin); + + ply_show_new_kernel_messages (false); + start_animation (plugin); + + return true; +} + +static void +update_status (ply_boot_splash_plugin_t *plugin, + const char *status) +{ + assert (plugin != NULL); + + ply_trace ("status update"); +} + +static void +on_boot_progress (ply_boot_splash_plugin_t *plugin, + double duration, + double percent_done) +{ + ply_list_node_t *node; + double total_duration; + + total_duration = duration / percent_done; + + /* Fun made-up smoothing function to make the growth asymptotic: + * fraction(time,estimate)=1-2^(-(time^1.45)/estimate) */ + percent_done = 1.0 - pow (2.0, -pow (duration, 1.45) / total_duration) * (1.0 - percent_done); + + node = ply_list_get_first_node (plugin->views); + + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + ply_text_progress_bar_set_percent_done (view->progress_bar, percent_done); + ply_text_progress_bar_draw (view->progress_bar); + + node = next_node; + } +} + +static void +hide_splash_screen (ply_boot_splash_plugin_t *plugin, + ply_event_loop_t *loop) +{ + assert (plugin != NULL); + + ply_trace ("hiding splash screen"); + + if (plugin->loop != NULL) + { + stop_animation (plugin); + + ply_event_loop_stop_watching_for_exit (plugin->loop, + (ply_event_loop_exit_handler_t) + detach_from_event_loop, + plugin); + detach_from_event_loop (plugin); + } + + hide_views (plugin); + ply_show_new_kernel_messages (true); +} + +static void +display_normal (ply_boot_splash_plugin_t *plugin) +{ + pause_views (plugin); + if (plugin->state != PLY_BOOT_SPLASH_DISPLAY_NORMAL) + { + plugin->state = PLY_BOOT_SPLASH_DISPLAY_NORMAL; + start_animation (plugin); + redraw_views (plugin); + } + unpause_views (plugin); +} + +static void +display_message (ply_boot_splash_plugin_t *plugin, + const char *message) +{ + if (plugin->message != NULL) + free (plugin->message); + + plugin->message = strdup (message); + start_animation (plugin); +} + +static void +show_password_prompt (ply_boot_splash_plugin_t *plugin, + const char *prompt, + int bullets) +{ + ply_list_node_t *node; + int i; + char *entered_text; + + entered_text = calloc (bullets + 1, sizeof (char)); + + for (i = 0; i < bullets; i++) + entered_text[i] = '*'; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + view_show_prompt (view, prompt, entered_text); + + node = next_node; + } + free (entered_text); +} + +static void +show_prompt (ply_boot_splash_plugin_t *plugin, + const char *prompt, + const char *text) +{ + ply_list_node_t *node; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) + { + ply_list_node_t *next_node; + view_t *view; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + view_show_prompt (view, prompt, text); + + node = next_node; + } +} + +static void +display_password (ply_boot_splash_plugin_t *plugin, + const char *prompt, + int bullets) +{ + pause_views (plugin); + if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_NORMAL) + stop_animation (plugin); + + plugin->state = PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY; + + if (!prompt) + prompt = "Password"; + + show_password_prompt (plugin, prompt, bullets); + + unpause_views (plugin); +} + +static void +display_question (ply_boot_splash_plugin_t *plugin, + const char *prompt, + const char *entry_text) +{ + pause_views (plugin); + if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_NORMAL) + stop_animation (plugin); + + plugin->state = PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY; + + if (!prompt) + prompt = "Password"; + + show_prompt (plugin, prompt, entry_text); + + unpause_views (plugin); +} + +ply_boot_splash_plugin_interface_t * +ply_boot_splash_plugin_get_interface (void) +{ + static ply_boot_splash_plugin_interface_t plugin_interface = + { + .create_plugin = create_plugin, + .destroy_plugin = destroy_plugin, + .add_text_display = add_text_display, + .remove_text_display = remove_text_display, + .show_splash_screen = show_splash_screen, + .update_status = update_status, + .on_boot_progress = on_boot_progress, + .hide_splash_screen = hide_splash_screen, + .display_normal = display_normal, + .display_message = display_message, + .display_password = display_password, + .display_question = display_question, + }; + + return &plugin_interface; +} + +/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ diff --git a/src/plugins/splash/two-step/Makefile.am b/src/plugins/splash/two-step/Makefile.am index 7310d6c..f3a6aaa 100644 --- a/src/plugins/splash/two-step/Makefile.am +++ b/src/plugins/splash/two-step/Makefile.am @@ -1,4 +1,4 @@ -INCLUDES = -I$(top_srcdir) \ +AM_CPPFLAGS = -I$(top_srcdir) \ -I$(srcdir)/../../../libply \ -I$(srcdir)/../../../libply-splash-core \ -I$(srcdir)/../../../libply-splash-graphics \ diff --git a/src/plugins/splash/two-step/plugin.c b/src/plugins/splash/two-step/plugin.c index 2998beb..f48b41e 100644 --- a/src/plugins/splash/two-step/plugin.c +++ b/src/plugins/splash/two-step/plugin.c @@ -89,8 +89,9 @@ typedef struct ply_throbber_t *throbber; ply_label_t *label; ply_label_t *message_label; - ply_rectangle_t box_area, lock_area; + ply_rectangle_t box_area, lock_area, watermark_area; ply_trigger_t *end_trigger; + ply_image_t *background_image; } view_t; struct _ply_boot_splash_plugin @@ -101,10 +102,15 @@ struct _ply_boot_splash_plugin ply_image_t *box_image; ply_image_t *corner_image; ply_image_t *header_image; + ply_image_t *background_tile_image; + ply_image_t *watermark_image; ply_list_t *views; ply_boot_splash_display_type_t state; + double watermark_horizontal_alignment; + double watermark_vertical_alignment; + double animation_horizontal_alignment; double animation_vertical_alignment; char *animation_dir; @@ -176,12 +182,37 @@ view_free (view_t *view) ply_label_free (view->label); ply_label_free (view->message_label); + if (view->background_image != NULL) + ply_image_free (view->background_image); + free (view); } static bool view_load (view_t *view) { + unsigned long screen_width, screen_height; + ply_boot_splash_plugin_t *plugin; + + plugin = view->plugin; + + screen_width = ply_pixel_display_get_width (view->display); + screen_height = ply_pixel_display_get_height (view->display); + + if (plugin->background_tile_image != NULL) + { + ply_trace ("tiling background to %lux%lu", screen_width, screen_height); + view->background_image = ply_image_tile (plugin->background_tile_image, screen_width, screen_height); + } + + if (plugin->watermark_image != NULL) + { + view->watermark_area.width = ply_image_get_width (plugin->watermark_image); + view->watermark_area.height = ply_image_get_height (plugin->watermark_image); + view->watermark_area.x = screen_width * plugin->watermark_horizontal_alignment - ply_image_get_width (plugin->watermark_image) * plugin->watermark_horizontal_alignment; + view->watermark_area.y = screen_height * plugin->watermark_vertical_alignment - ply_image_get_height (plugin->watermark_image) * plugin->watermark_vertical_alignment; + } + ply_trace ("loading entry"); if (!ply_entry_load (view->entry)) return false; @@ -519,6 +550,14 @@ create_plugin (ply_key_file_t *key_file) plugin->header_image = ply_image_new (image_path); free (image_path); + asprintf (&image_path, "%s/background-tile.png", image_dir); + plugin->background_tile_image = ply_image_new (image_path); + free (image_path); + + asprintf (&image_path, "%s/watermark.png", image_dir); + plugin->watermark_image = ply_image_new (image_path); + free (image_path); + plugin->animation_dir = image_dir; alignment = ply_key_file_get_value (key_file, "two-step", "HorizontalAlignment"); @@ -535,6 +574,20 @@ create_plugin (ply_key_file_t *key_file) plugin->animation_vertical_alignment = .5; free (alignment); + alignment = ply_key_file_get_value (key_file, "two-step", "WatermarkHorizontalAlignment"); + if (alignment != NULL) + plugin->watermark_horizontal_alignment = strtod (alignment, NULL); + else + plugin->watermark_horizontal_alignment = 1.0; + free (alignment); + + alignment = ply_key_file_get_value (key_file, "two-step", "WatermarkVerticalAlignment"); + if (alignment != NULL) + plugin->watermark_vertical_alignment = strtod (alignment, NULL); + else + plugin->watermark_vertical_alignment = .5; + free (alignment); + plugin->transition = PLY_PROGRESS_ANIMATION_TRANSITION_NONE; transition = ply_key_file_get_value (key_file, "two-step", "Transition"); if (transition != NULL) @@ -653,6 +706,12 @@ destroy_plugin (ply_boot_splash_plugin_t *plugin) if (plugin->header_image != NULL) ply_image_free (plugin->header_image); + if (plugin->background_tile_image != NULL) + ply_image_free (plugin->background_tile_image); + + if (plugin->watermark_image != NULL) + ply_image_free (plugin->watermark_image); + free (plugin->animation_dir); free_views (plugin); free (plugin); @@ -813,6 +872,21 @@ draw_background (view_t *view, else ply_pixel_buffer_fill_with_hex_color (pixel_buffer, &area, plugin->background_start_color); + + if (view->background_image != NULL) + { + uint32_t *data; + data = ply_image_get_data (view->background_image); + ply_pixel_buffer_fill_with_argb32_data (pixel_buffer, &area, data); + } + + if (plugin->watermark_image != NULL) + { + uint32_t *data; + + data = ply_image_get_data (plugin->watermark_image); + ply_pixel_buffer_fill_with_argb32_data (pixel_buffer, &view->watermark_area, data); + } } static void @@ -997,6 +1071,26 @@ show_splash_screen (ply_boot_splash_plugin_t *plugin, } } + if (plugin->background_tile_image != NULL) + { + ply_trace ("loading background tile image"); + if (!ply_image_load (plugin->background_tile_image)) + { + ply_image_free (plugin->background_tile_image); + plugin->background_tile_image = NULL; + } + } + + if (plugin->watermark_image != NULL) + { + ply_trace ("loading watermark image"); + if (!ply_image_load (plugin->watermark_image)) + { + ply_image_free (plugin->watermark_image); + plugin->watermark_image = NULL; + } + } + if (!load_views (plugin)) { ply_trace ("couldn't load views"); @@ -1067,6 +1161,9 @@ on_boot_progress (ply_boot_splash_plugin_t *plugin, if (plugin->state != PLY_BOOT_SPLASH_DISPLAY_NORMAL) return; + if (plugin->is_idle) + return; + if (percent_done >= SHOW_ANIMATION_PERCENT) { if (plugin->stop_trigger == NULL) diff --git a/src/ply-boot-server.c b/src/ply-boot-server.c index f15ade7..3e67bfb 100644 --- a/src/ply-boot-server.c +++ b/src/ply-boot-server.c @@ -776,7 +776,7 @@ ply_boot_server_on_new_connection (ply_boot_server_t *server) assert (server != NULL); - fd = accept (server->socket_fd, NULL, NULL); + fd = accept4 (server->socket_fd, NULL, NULL, SOCK_CLOEXEC); if (fd < 0) return; @@ -831,183 +831,4 @@ ply_boot_server_attach_to_event_loop (ply_boot_server_t *server, server); } -#ifdef PLY_BOOT_SERVER_ENABLE_TEST - -#include - -#include "ply-event-loop.h" -#include "ply-boot-server.h" - -static void -on_update (ply_event_loop_t *loop, - const char *status) -{ - printf ("new status is '%s'\n", status); -} - -static void -on_newroot (ply_event_loop_t *loop) -{ - printf ("got newroot request\n"); -} - -static void -on_system_initialized (ply_event_loop_t *loop) -{ - printf ("got sysinit done request\n"); -} - -static void -on_show_splash (ply_event_loop_t *loop) -{ - printf ("got show splash request\n"); -} - -static void -on_hide_splash (ply_event_loop_t *loop) -{ - printf ("got hide splash request\n"); -} - -static void -on_deactivate (ply_event_loop_t *loop) -{ - printf ("got deactivate request\n"); -} - -static void -on_reactivate (ply_event_loop_t *loop) -{ - printf ("got reactivate request\n"); -} - -static void -on_quit (ply_event_loop_t *loop) -{ - printf ("got quit request, quiting...\n"); - ply_event_loop_exit (loop, 0); -} - -static void -on_error (ply_event_loop_t *loop) -{ - printf ("got error starting service\n"); -} - -static char * -on_ask_for_password (ply_event_loop_t *loop) -{ - printf ("got password request, returning 'password'...\n"); - - return strdup ("password"); -} - -static void -on_ask_question (ply_event_loop_t *loop) -{ - printf ("got question request\n"); - return; -} - -static void -on_display_message (ply_event_loop_t *loop) -{ - printf ("got display message request\n"); - return; -} - -static void -on_hide_message (ply_event_loop_t *loop) -{ - printf ("got hide message request\n"); - return; -} - -static void -on_watch_for_keystroke (ply_event_loop_t *loop) -{ - printf ("got keystroke request\n"); - - return; -} - -static void -on_progress_pause (ply_event_loop_t *loop) -{ - printf ("got progress pause request\n"); - - return; -} - -static void -on_progress_unpause (ply_event_loop_t *loop) -{ - printf ("got progress unpause request\n"); - - return; -} - -static void -on_ignore_keystroke (ply_event_loop_t *loop) -{ - printf ("got keystroke ignore request\n"); - - return; -} - -static bool -on_has_active_vt (ply_event_loop_t *loop) -{ - printf ("got has_active vt? request\n"); - return true; -} - -int -main (int argc, - char **argv) -{ - ply_event_loop_t *loop; - ply_boot_server_t *server; - int exit_code; - - exit_code = 0; - - loop = ply_event_loop_new (); - - server = ply_boot_server_new ((ply_boot_server_update_handler_t) on_update, - (ply_boot_server_change_mode_handler_t) on_change_mode, - (ply_boot_server_system_update_handler_t) on_system_update, - (ply_boot_server_ask_for_password_handler_t) on_ask_for_password, - (ply_boot_server_ask_question_handler_t) on_ask_question, - (ply_boot_server_display_message_handler_t) on_display_message, - (ply_boot_server_hide_message_handler_t) on_hide_message, - (ply_boot_server_watch_for_keystroke_handler_t) on_watch_for_keystroke, - (ply_boot_server_ignore_keystroke_handler_t) on_ignore_keystroke, - (ply_boot_server_progress_pause_handler_t) on_progress_pause, - (ply_boot_server_progress_unpause_handler_t) on_progress_unpause, - (ply_boot_server_show_splash_handler_t) on_show_splash, - (ply_boot_server_hide_splash_handler_t) on_hide_splash, - (ply_boot_server_newroot_handler_t) on_newroot, - (ply_boot_server_system_initialized_handler_t) on_system_initialized, - (ply_boot_server_error_handler_t) on_error, - (ply_boot_server_deactivate_handler_t) on_deactivate, - (ply_boot_server_reactivate_handler_t) on_reactivate, - (ply_boot_server_quit_handler_t) on_quit, - (ply_boot_server_has_active_vt_handler_t) on_has_active_vt, - loop); - - if (!ply_boot_server_listen (server)) - { - perror ("could not start boot status daemon"); - return errno; - } - - ply_boot_server_attach_to_event_loop (server, loop); - exit_code = ply_event_loop_run (loop); - ply_boot_server_free (server); - - return exit_code; -} - -#endif /* PLY_BOOT_SERVER_ENABLE_TEST */ /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ diff --git a/src/plymouthd.defaults b/src/plymouthd.defaults index 46417d6..fc48b15 100644 --- a/src/plymouthd.defaults +++ b/src/plymouthd.defaults @@ -2,3 +2,4 @@ # upgrades. [Daemon] Theme=spinner +ShowDelay=5 diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am deleted file mode 100644 index 86a8ea6..0000000 --- a/src/tests/Makefile.am +++ /dev/null @@ -1,18 +0,0 @@ -INCLUDES = \ - -I$(top_srcdir) \ - -I$(srcdir)/.. \ - -I$(srcdir)/../libply \ - -I$(srcdir)/../libply-splash-core \ - -I$(srcdir) -TESTS = - -if ENABLE_TESTS -include $(srcdir)/ply-boot-server-test.am -include $(srcdir)/ply-boot-splash-test.am -endif - -noinst_PROGRAMS = $(TESTS) - -# our tests aren't unit tests, so clear for now -TESTS = -MAINTAINERCLEANFILES = Makefile.in diff --git a/src/tests/ply-boot-server-test.am b/src/tests/ply-boot-server-test.am deleted file mode 100644 index cc28348..0000000 --- a/src/tests/ply-boot-server-test.am +++ /dev/null @@ -1,8 +0,0 @@ -TESTS += ply-boot-server-test - -ply_boot_server_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_BOOT_SERVER_ENABLE_TEST -ply_boot_server_test_LDADD = $(PLYMOUTH_LIBS) ../libply/libply.la - -ply_boot_server_test_SOURCES = \ - $(srcdir)/../ply-boot-server.h \ - $(srcdir)/../ply-boot-server.c diff --git a/src/tests/ply-boot-splash-test.am b/src/tests/ply-boot-splash-test.am deleted file mode 100644 index 9dd1598..0000000 --- a/src/tests/ply-boot-splash-test.am +++ /dev/null @@ -1,25 +0,0 @@ -TESTS += ply-boot-splash-test - -ply_boot_splash_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_BOOT_SPLASH_ENABLE_TEST \ - -DPLYMOUTH_TIME_DIRECTORY=\"/var/lib/plymouth\" \ - -DPLYMOUTH_PLUGIN_PATH=\"$(PLYMOUTH_PLUGIN_PATH)\" \ - -DPLYMOUTH_THEME_PATH=\"$(PLYMOUTH_THEME_PATH)/\" - -ply_boot_splash_test_LDADD = $(PLYMOUTH_LIBS) ../libply/libply.la - -ply_boot_splash_test_SOURCES = \ - $(srcdir)/../libply-splash-core/ply-boot-splash-plugin.h \ - $(srcdir)/../libply-splash-core/ply-keyboard.h \ - $(srcdir)/../libply-splash-core/ply-keyboard.c \ - $(srcdir)/../libply-splash-core/ply-pixel-buffer.h \ - $(srcdir)/../libply-splash-core/ply-pixel-buffer.c \ - $(srcdir)/../libply-splash-core/ply-pixel-display.h \ - $(srcdir)/../libply-splash-core/ply-pixel-display.c \ - $(srcdir)/../libply-splash-core/ply-renderer.h \ - $(srcdir)/../libply-splash-core/ply-renderer.c \ - $(srcdir)/../libply-splash-core/ply-terminal.h \ - $(srcdir)/../libply-splash-core/ply-terminal.c \ - $(srcdir)/../libply-splash-core/ply-text-display.h \ - $(srcdir)/../libply-splash-core/ply-text-display.c \ - $(srcdir)/../libply-splash-core/ply-boot-splash.h \ - $(srcdir)/../libply-splash-core/ply-boot-splash.c diff --git a/src/upstart-bridge/Makefile.am b/src/upstart-bridge/Makefile.am index 628ef20..a16cd11 100644 --- a/src/upstart-bridge/Makefile.am +++ b/src/upstart-bridge/Makefile.am @@ -1,4 +1,4 @@ -INCLUDES = -I$(top_srcdir) \ +AM_CPPFLAGS = -I$(top_srcdir) \ -I$(top_srcdir)/src \ -I$(top_srcdir)/src/libply \ -I$(top_srcdir)/src/client \ diff --git a/src/viewer/Makefile.am b/src/viewer/Makefile.am index 6ade690..0c5c3ec 100644 --- a/src/viewer/Makefile.am +++ b/src/viewer/Makefile.am @@ -1,7 +1,7 @@ SUBDIRS = . EXTRA_DIST= -INCLUDES = -I$(top_srcdir) \ +AM_CPPFLAGS = -I$(top_srcdir) \ -I$(srcdir) if WITH_LOG_VIEWER plymouth_log_viewerdir = $(bindir) diff --git a/src/viewer/plymouth-log-viewer.c b/src/viewer/plymouth-log-viewer.c index c20e391..ca54e0f 100644 --- a/src/viewer/plymouth-log-viewer.c +++ b/src/viewer/plymouth-log-viewer.c @@ -20,6 +20,10 @@ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/systemd-units/Makefile.am b/systemd-units/Makefile.am index 3aa44df..89355ac 100644 --- a/systemd-units/Makefile.am +++ b/systemd-units/Makefile.am @@ -25,7 +25,8 @@ install-data-hook: $(DESTDIR)$(SYSTEMD_UNIT_DIR)/poweroff.target.wants \ $(DESTDIR)$(SYSTEMD_UNIT_DIR)/halt.target.wants (cd $(DESTDIR)$(SYSTEMD_UNIT_DIR)/initrd-switch-root.target.wants && \ - rm -f plymouth-switch-root.service && \ + rm -f plymouth-start.service plymouth-switch-root.service && \ + $(LN_S) ../plymouth-start.service && \ $(LN_S) ../plymouth-switch-root.service) (cd $(DESTDIR)$(SYSTEMD_UNIT_DIR)/sysinit.target.wants && \ rm -f plymouth-start.service plymouth-read-write.service && \ @@ -51,7 +52,7 @@ install-data-hook: uninstall-hook: rm -f \ (cd $(DESTDIR)$(SYSTEMD_UNIT_DIR)/initrd-switch-root.target.wants && \ - rm -f plymouth-switch-root.service) \ + rm -f plymouth-start.service plymouth-switch-root.service) \ (cd $(DESTDIR)$(SYSTEMD_UNIT_DIR)/sysinit.target.wants && \ rm -f plymouth-start.service plymouth-read-write.service) \ (cd $(DESTDIR)$(SYSTEMD_UNIT_DIR)/multi-user.target.wants && \ diff --git a/systemd-units/plymouth-halt.service.in b/systemd-units/plymouth-halt.service.in index 8fd6c48..fd27e10 100644 --- a/systemd-units/plymouth-halt.service.in +++ b/systemd-units/plymouth-halt.service.in @@ -1,7 +1,7 @@ [Unit] Description=Show Plymouth Halt Screen -After=getty@tty1.service prefdm.service plymouth-start.service -Before=halt.service +After=getty@tty1.service display-manager.service plymouth-start.service +Before=systemd-halt.service DefaultDependencies=no ConditionKernelCommandLine=!plymouth.enable=0 @@ -9,3 +9,6 @@ ConditionKernelCommandLine=!plymouth.enable=0 ExecStart=@PLYMOUTH_DAEMON_DIR@/plymouthd --mode=shutdown --attach-to-session ExecStartPost=-@PLYMOUTH_CLIENT_DIR@/plymouth show-splash Type=forking + +[Install] +WantedBy=halt.target diff --git a/systemd-units/plymouth-kexec.service.in b/systemd-units/plymouth-kexec.service.in index 6ee0461..8aa661d 100644 --- a/systemd-units/plymouth-kexec.service.in +++ b/systemd-units/plymouth-kexec.service.in @@ -1,7 +1,7 @@ [Unit] Description=Show Plymouth Reboot with kexec Screen -After=getty@tty1.service prefdm.service plymouth-start.service -Before=kexec.service +After=getty@tty1.service display-manager.service plymouth-start.service +Before=systemd-kexec.service DefaultDependencies=no ConditionKernelCommandLine=!plymouth.enable=0 @@ -9,3 +9,6 @@ ConditionKernelCommandLine=!plymouth.enable=0 ExecStart=@PLYMOUTH_DAEMON_DIR@/plymouthd --mode=shutdown --attach-to-session ExecStartPost=-@PLYMOUTH_CLIENT_DIR@/plymouth show-splash Type=forking + +[Install] +WantedBy=kexec.target diff --git a/systemd-units/plymouth-poweroff.service.in b/systemd-units/plymouth-poweroff.service.in index 3e2a83c..305ece6 100644 --- a/systemd-units/plymouth-poweroff.service.in +++ b/systemd-units/plymouth-poweroff.service.in @@ -1,7 +1,7 @@ [Unit] Description=Show Plymouth Power Off Screen -After=getty@tty1.service prefdm.service plymouth-start.service -Before=poweroff.service +After=getty@tty1.service display-manager.service plymouth-start.service +Before=systemd-poweroff.service DefaultDependencies=no ConditionKernelCommandLine=!plymouth.enable=0 @@ -9,3 +9,5 @@ ConditionKernelCommandLine=!plymouth.enable=0 ExecStart=@PLYMOUTH_DAEMON_DIR@/plymouthd --mode=shutdown --attach-to-session ExecStartPost=-@PLYMOUTH_CLIENT_DIR@/plymouth show-splash Type=forking +[Install] +WantedBy=poweroff.target diff --git a/systemd-units/plymouth-quit-wait.service.in b/systemd-units/plymouth-quit-wait.service.in index 9fc20e7..1c431b6 100644 --- a/systemd-units/plymouth-quit-wait.service.in +++ b/systemd-units/plymouth-quit-wait.service.in @@ -5,4 +5,6 @@ After=rc-local.service plymouth-start.service systemd-user-sessions.service [Service] ExecStart=-@PLYMOUTH_CLIENT_DIR@/plymouth --wait Type=oneshot -TimeoutSec=20 +TimeoutSec=0 +[Install] +WantedBy=multi-user.target diff --git a/systemd-units/plymouth-quit.service.in b/systemd-units/plymouth-quit.service.in index cf9901e..24c11bb 100644 --- a/systemd-units/plymouth-quit.service.in +++ b/systemd-units/plymouth-quit.service.in @@ -6,3 +6,5 @@ After=rc-local.service plymouth-start.service systemd-user-sessions.service ExecStart=-@PLYMOUTH_CLIENT_DIR@/plymouth quit Type=oneshot TimeoutSec=20 +[Install] +WantedBy=multi-user.target diff --git a/systemd-units/plymouth-read-write.service.in b/systemd-units/plymouth-read-write.service.in index 55b975e..5abfc49 100644 --- a/systemd-units/plymouth-read-write.service.in +++ b/systemd-units/plymouth-read-write.service.in @@ -8,3 +8,5 @@ ConditionPathExists=!/etc/initrd-release [Service] ExecStart=-@PLYMOUTH_CLIENT_DIR@/plymouth update-root-fs --read-write Type=oneshot +[Install] +WantedBy=sysinit.target diff --git a/systemd-units/plymouth-reboot.service.in b/systemd-units/plymouth-reboot.service.in index a6e86e4..ce56855 100644 --- a/systemd-units/plymouth-reboot.service.in +++ b/systemd-units/plymouth-reboot.service.in @@ -1,7 +1,7 @@ [Unit] Description=Show Plymouth Reboot Screen -After=getty@tty1.service prefdm.service plymouth-start.service -Before=reboot.service +After=getty@tty1.service display-manager.service plymouth-start.service +Before=systemd-reboot.service DefaultDependencies=no ConditionKernelCommandLine=!plymouth.enable=0 @@ -9,3 +9,5 @@ ConditionKernelCommandLine=!plymouth.enable=0 ExecStart=@PLYMOUTH_DAEMON_DIR@/plymouthd --mode=shutdown --attach-to-session ExecStartPost=-@PLYMOUTH_CLIENT_DIR@/plymouth show-splash Type=forking +[Install] +WantedBy=reboot.target diff --git a/systemd-units/plymouth-start.service.in b/systemd-units/plymouth-start.service.in index bbff9f5..0d5ff2a 100644 --- a/systemd-units/plymouth-start.service.in +++ b/systemd-units/plymouth-start.service.in @@ -1,14 +1,16 @@ [Unit] Description=Show Plymouth Boot Screen DefaultDependencies=no -Wants=systemd-ask-password-plymouth.path -After=systemd-vconsole-setup.service systemd-udev-trigger.service +Wants=systemd-ask-password-plymouth.path systemd-vconsole-setup.service +After=systemd-vconsole-setup.service systemd-udev-trigger.service systemd-udevd.service Before=systemd-ask-password-plymouth.service ConditionKernelCommandLine=!plymouth.enable=0 [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=-@PLYMOUTH_CLIENT_DIR@/plymouth show-splash Type=forking KillMode=none SendSIGKILL=no +[Install] +WantedBy=sysinit.target diff --git a/systemd-units/systemd-ask-password-plymouth.service.in b/systemd-units/systemd-ask-password-plymouth.service.in index aa9ffc2..0c3acde 100644 --- a/systemd-units/systemd-ask-password-plymouth.service.in +++ b/systemd-units/systemd-ask-password-plymouth.service.in @@ -9,4 +9,4 @@ ConditionKernelCommandLine=!plymouth.enable=0 ConditionPathExists=/run/plymouth/pid [Service] -ExecStart=/bin/systemd-tty-ask-password-agent --watch --plymouth +ExecStart=@SYSTEMD_ASK_PASSWORD_AGENT@ --watch --plymouth diff --git a/themes/Makefile.am b/themes/Makefile.am index cfd149e..72e642b 100644 --- a/themes/Makefile.am +++ b/themes/Makefile.am @@ -1,2 +1,2 @@ -SUBDIRS = spinfinity fade-in text details solar glow script spinner +SUBDIRS = spinfinity fade-in text details solar glow script spinner tribar MAINTAINERCLEANFILES = Makefile.in diff --git a/themes/text/text.plymouth b/themes/text/text.plymouth index a2db9e6..126eb09 100644 --- a/themes/text/text.plymouth +++ b/themes/text/text.plymouth @@ -1,4 +1,4 @@ [Plymouth Theme] Name=Text -Description=Text mode theme with tricolor progress bar +Description=Text mode theme with a 3 box countdown ModuleName=text diff --git a/themes/tribar/Makefile.am b/themes/tribar/Makefile.am new file mode 100644 index 0000000..3066d2f --- /dev/null +++ b/themes/tribar/Makefile.am @@ -0,0 +1,4 @@ +themedir = $(datadir)/plymouth/themes/tribar +dist_theme_DATA = tribar.plymouth + +MAINTAINERCLEANFILES = Makefile.in diff --git a/themes/tribar/tribar.plymouth b/themes/tribar/tribar.plymouth new file mode 100644 index 0000000..6db7b4e --- /dev/null +++ b/themes/tribar/tribar.plymouth @@ -0,0 +1,4 @@ +[Plymouth Theme] +Name=Tribar +Description=Text mode theme with tricolor progress bar +ModuleName=tribar