diff --git a/dev-python/pyinotify-python2/Manifest b/dev-python/pyinotify-python2/Manifest
new file mode 100644
index 000000000..080a2077f
--- /dev/null
+++ b/dev-python/pyinotify-python2/Manifest
@@ -0,0 +1 @@
+DIST pyinotify-0.9.6.tar.gz 60998 BLAKE2B 7fb55cfe5b2c02682b5842d95859a58f218ab591a4eee689b707e804c6fe8cde4cc1fb3dfbf54a044ff743deefa0ee5551bc6e27ca4dda1c608218a6c24597b2 SHA512 b52de43293b06b32236e90b7c33fac061f3095cd7d4aecec89a099d56020db1a85440ab9dcc8b521238c001fc49a1f37d1b16d621bc1acab4d7273aebcaadbc5
diff --git a/dev-python/pyinotify-python2/metadata.xml b/dev-python/pyinotify-python2/metadata.xml
new file mode 100644
index 000000000..f7724f180
--- /dev/null
+++ b/dev-python/pyinotify-python2/metadata.xml
@@ -0,0 +1,7 @@
+
+
+
+
+ maintainer-wanted
+
+
diff --git a/dev-python/pyinotify-python2/pyinotify-python2-0.9.6.ebuild b/dev-python/pyinotify-python2/pyinotify-python2-0.9.6.ebuild
new file mode 100644
index 000000000..5c1a8e66a
--- /dev/null
+++ b/dev-python/pyinotify-python2/pyinotify-python2-0.9.6.ebuild
@@ -0,0 +1,36 @@
+# Copyright 1999-2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+PYTHON_COMPAT=( python2_7 )
+PYTHON_REQ_USE="threads(+)"
+
+inherit distutils-r1
+
+MY_PN=pyinotify
+MY_P=$MY_PN-$PV
+
+DESCRIPTION="Python module used for monitoring filesystems events"
+HOMEPAGE="
+ http://trac.dbzteam.org/pyinotify
+ https://pypi.org/project/pyinotify/
+ https://github.com/seb-m/pyinotify/"
+SRC_URI="http://seb.dbzteam.org/pub/pyinotify/releases/${MY_P}.tar.gz"
+
+LICENSE="MIT"
+SLOT="0"
+KEYWORDS="~alpha amd64 arm arm64 hppa ~ia64 ~mips ppc ppc64 ~riscv s390 sparc x86 ~amd64-linux ~x86-linux"
+
+RESTRICT="test"
+
+RDEPEND="
+ !dev-python/${MY_PN}[python_targets_python2_7]
+"
+
+S="${WORKDIR}/${MY_PN}-${PV}"
+
+python_install_all() {
+ distutils-r1_python_install_all
+ rm -r ${D}/usr/share
+}
diff --git a/eclass/calculate-utils-r11.eclass b/eclass/calculate-utils-r11.eclass
index e1cf1cfef..0ac91a7de 100644
--- a/eclass/calculate-utils-r11.eclass
+++ b/eclass/calculate-utils-r11.eclass
@@ -228,6 +228,7 @@ RDEPEND="
dev-python/dbus-python2
media-gfx/imagemagick[jpeg]
dev-python/PyQt5-python2
+ dev-python/pyinotify-python2
)
dbus? (
diff --git a/media-libs/avidemux-plugins/Manifest b/media-libs/avidemux-plugins/Manifest
deleted file mode 100644
index 0110f985e..000000000
--- a/media-libs/avidemux-plugins/Manifest
+++ /dev/null
@@ -1,3 +0,0 @@
-AUX avidemux-plugins-2.6.20-optional-pulse.patch 743 BLAKE2B e60a7433e539d49d5bff7dea62bfda984866dd72b93158827ee5ed785d77174db3fbde9e67c9c3fdc8d652485d8e704c075811c65848ef48f78490c6a3061b7f SHA512 dcec29c63aa7eb828fc1aaf4b54edb76290e3c7655b00002efa8036f0572b1c0111c30e873b925bb606e8e672e177ba8d103100b1fb55dcc830b83e4a5556710
-DIST avidemux-2.7.4.tar.gz 23815808 BLAKE2B 3a7206f04f568f28dd4d5116c580dd780b057a59e94dd61a2abe5dadfa557291a0c50f917ad1926f9f9a82d01af065c06138f954320e2d9c174fda7583a6b265 SHA512 36d857837cd6a74039a414df16367cd8cbf615173bcc531e57dc0dbfc2e002b1c0c4a80cef73a0d8f25d305deca809af0b5cbcdbad8c311324fa2e64381fd10b
-EBUILD avidemux-plugins-2.7.4-r1.ebuild 4225 BLAKE2B cb708b89c9eca201e17e04db27da9c5e081813fa3d37af0cfd2e2378d8593930640d3abb233342c289633fb77ab78caf5c54ac9bff252dc872fd9160b350f00f SHA512 d8de926fd6480103d9ff2086acbe1653b9c48e66f1d767142f9faa7fdfdd90fce931503d6702543fa4ea54a7a224f7d1f0a496f69357b005c294fb329a187f54
diff --git a/media-libs/avidemux-plugins/avidemux-plugins-2.7.4-r1.ebuild b/media-libs/avidemux-plugins/avidemux-plugins-2.7.4-r1.ebuild
deleted file mode 100644
index ece0e3a91..000000000
--- a/media-libs/avidemux-plugins/avidemux-plugins-2.7.4-r1.ebuild
+++ /dev/null
@@ -1,161 +0,0 @@
-# Copyright 1999-2020 Gentoo Authors
-# Distributed under the terms of the GNU General Public License v2
-
-EAPI=7
-
-CMAKE_MAKEFILE_GENERATOR="emake"
-PYTHON_COMPAT=( python3_7 )
-
-inherit cmake python-single-r1
-
-DESCRIPTION="Plugins for the video editor media-video/avidemux"
-HOMEPAGE="http://fixounet.free.fr/avidemux"
-SRC_URI="https://github.com/mean00/avidemux2/archive/${PV}.tar.gz -> avidemux-${PV}.tar.gz"
-
-# Multiple licenses because of all the bundled stuff.
-LICENSE="GPL-1 GPL-2 MIT PSF-2 public-domain"
-SLOT="2.7"
-IUSE="a52 aac aften alsa amr dcaenc debug dts fdk fontconfig fribidi jack lame libsamplerate cpu_flags_x86_mmx nvenc opengl opus oss pulseaudio qt5 truetype twolame vdpau vorbis vpx x264 x265 xv xvid"
-KEYWORDS="~amd64 ~x86"
-
-REQUIRED_USE="${PYTHON_REQUIRED_USE}"
-
-COMMON_DEPEND="${PYTHON_DEPS}
- ~media-libs/avidemux-core-${PV}:${SLOT}[vdpau?]
- ~media-video/avidemux-${PV}:${SLOT}[opengl?,qt5?]
- dev-lang/spidermonkey:0=
- dev-libs/libxml2:2
- media-libs/a52dec
- media-libs/libass:0=
- media-libs/libmad
- media-libs/libmp4v2
- media-libs/libpng:0=
- virtual/libiconv
- aac? (
- media-libs/faac
- media-libs/faad2
- )
- aften? ( media-libs/aften )
- alsa? ( media-libs/alsa-lib )
- amr? ( media-libs/opencore-amr )
- dcaenc? ( media-sound/dcaenc )
- dts? ( media-libs/libdca )
- fdk? ( media-libs/fdk-aac:0= )
- fontconfig? ( media-libs/fontconfig:1.0 )
- fribidi? ( dev-libs/fribidi )
- jack? (
- media-sound/jack-audio-connection-kit
- libsamplerate? ( media-libs/libsamplerate )
- )
- lame? ( media-sound/lame )
- nvenc? ( amd64? ( media-video/nvidia_video_sdk ) )
- opus? ( media-libs/opus )
- pulseaudio? ( media-sound/pulseaudio )
- qt5? (
- dev-qt/qtcore:5
- dev-qt/qtgui:5
- dev-qt/qtwidgets:5
- )
- truetype? ( media-libs/freetype:2 )
- twolame? ( media-sound/twolame )
- vorbis? ( media-libs/libvorbis )
- vpx? ( media-libs/libvpx:0= )
- x264? ( media-libs/x264:0= )
- x265? ( media-libs/x265:0= )
- xv? (
- x11-libs/libX11
- x11-libs/libXext
- x11-libs/libXv
- )
- xvid? ( media-libs/xvid )
-"
-DEPEND="${COMMON_DEPEND}
- oss? ( virtual/os-headers )
-"
-RDEPEND="${COMMON_DEPEND}
- !/var/lib/calculate/-runlevels-$PN
+ if [[ -d /var/lib/calculate ]]
+ then
+ find /etc/runlevels/{default,boot,sysinit,shutdown} >/var/lib/calculate/-runlevels-$PN
+ fi
}
# dispatching unmerge or update package
@@ -84,7 +90,10 @@ pkg_postrm_unmerge() {
# save contents file for correct package updating by cl-core-setup
pkg_postrm_update() {
- cp /var/db/pkg/${CATEGORY}/${PF}/CONTENTS /var/lib/calculate/-CONTENTS-$PN
+ if [[ -d /var/lib/calculate ]]
+ then
+ cp /var/db/pkg/${CATEGORY}/${PF}/CONTENTS /var/lib/calculate/-CONTENTS-$PN
+ fi
}
pre_pkg_postrm() {
diff --git a/profiles/templates/3.6/2_ac_install_merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth b/profiles/templates/3.6/2_ac_install_merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth
index febb52a9f..dd0099715 100644
--- a/profiles/templates/3.6/2_ac_install_merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth
+++ b/profiles/templates/3.6/2_ac_install_merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth
@@ -1,33 +1,51 @@
-# Calculate format=kde path=/usr/share/plymouth/themes/calculate
+# Calculate format=kde path=/usr/share/plymouth/themes/calculate pkg(sys-boot/plymouth-calculate-plugin)>=0.9.5
[Plymouth Theme]
Name=Calculate
-Description=Simple theme that shows progressbar, image and text for shutdown
+Description=Calculate spinner theme
ModuleName=calculate
[calculate]
ImageDir=/usr/share/plymouth/themes/calculate
-BootBackgroundStartColor=0x#-ini(theme.splash-silent-background-color-begin)-#
-BootBackgroundEndColor=0x#-ini(theme.splash-silent-background-color-end)-#
-ShutdownBackgroundStartColor=0x#-ini(theme.splash-shutdown-background-color-begin)-#
-ShutdownBackgroundEndColor=0x#-ini(theme.splash-shutdown-background-color-end)-#
-!ShutdownProgressbarColor=
-!BootProgressbarColor=
+
+[boot-up]
+BackgroundStartColor=0x#-ini(theme.splash-silent-background-color-begin)-#
+BackgroundEndColor=0x#-ini(theme.splash-silent-background-color-end)-#
#?ini(theme.splash-silent-picture)!=&&ini(theme.splash-silent-type)==background#
-BootImage=/usr/share/plymouth/themes/calculate/boot
+WatermarkImage=/usr/share/plymouth/themes/calculate/boot
#ini#
#?ini(theme.splash-silent-picture)!=&&ini(theme.splash-silent-type)==logo#
-BootImage=/usr/share/plymouth/themes/calculate/boot.png
+WatermarkImage=/usr/share/plymouth/themes/calculate/boot.png
#ini#
#?ini(theme.splash-silent-picture)==||exists(#-ini(theme.splash-silent-picture)-#)==#
-!BootImage=
+!WatermarkImage
#ini#
+
+[shutdown]
+BackgroundStartColor=0x#-ini(theme.splash-shutdown-background-color-begin)-#
+BackgroundEndColor=0x#-ini(theme.splash-shutdown-background-color-end)-#
+#?ini(theme.splash-shutdown-picture)!=&&ini(theme.splash-shutdown-type)==background#
+WatermarkImage=/usr/share/plymouth/themes/calculate/.shutdown
+#ini#
+#?ini(theme.splash-shutdown-picture)!=&&ini(theme.splash-shutdown-type)==logo#
+WatermarkImage=/usr/share/plymouth/themes/calculate/.shutdown.png
+#ini#
+#?ini(theme.splash-shutdown-picture)==||exists(#-ini(theme.splash-shutdown-picture)-#)==#
+!WatermarkImage=
+#ini#
+TitleColor=0x#-ini(theme.splash-shutdown-text-color)-#
+Title=S h u t t i n g d o w n
+
+[reboot]
+BackgroundStartColor=0x#-ini(theme.splash-shutdown-background-color-begin)-#
+BackgroundEndColor=0x#-ini(theme.splash-shutdown-background-color-end)-#
#?ini(theme.splash-shutdown-picture)!=&&ini(theme.splash-shutdown-type)==background#
-ShutdownImage=/usr/share/plymouth/themes/calculate/.shutdown
+WatermarkImage=/usr/share/plymouth/themes/calculate/.shutdown
#ini#
#?ini(theme.splash-shutdown-picture)!=&&ini(theme.splash-shutdown-type)==logo#
-ShutdownImage=/usr/share/plymouth/themes/calculate/.shutdown.png
+WatermarkImage=/usr/share/plymouth/themes/calculate/.shutdown.png
#ini#
#?ini(theme.splash-shutdown-picture)==||exists(#-ini(theme.splash-shutdown-picture)-#)==#
-!ShutdownImage=
+!WatermarkImage=
#ini#
-ShutdownTextColor=0x#-ini(theme.splash-shutdown-text-color)-#
+TitleColor=0x#-ini(theme.splash-shutdown-text-color)-#
+Title=S h u t t i n g d o w n
diff --git a/profiles/templates/3.6/2_ac_install_merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth-0.9.4 b/profiles/templates/3.6/2_ac_install_merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth-0.9.4
new file mode 100644
index 000000000..bcebbb8a1
--- /dev/null
+++ b/profiles/templates/3.6/2_ac_install_merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth-0.9.4
@@ -0,0 +1,33 @@
+# Calculate format=kde path=/usr/share/plymouth/themes/calculate pkg(sys-boot/plymouth-calculate-plugin)<0.9.5 name=calculate.plymouth
+[Plymouth Theme]
+Name=Calculate
+Description=Simple theme that shows progressbar, image and text for shutdown
+ModuleName=calculate
+
+[calculate]
+ImageDir=/usr/share/plymouth/themes/calculate
+BootBackgroundStartColor=0x#-ini(theme.splash-silent-background-color-begin)-#
+BootBackgroundEndColor=0x#-ini(theme.splash-silent-background-color-end)-#
+ShutdownBackgroundStartColor=0x#-ini(theme.splash-shutdown-background-color-begin)-#
+ShutdownBackgroundEndColor=0x#-ini(theme.splash-shutdown-background-color-end)-#
+!ShutdownProgressbarColor=
+!BootProgressbarColor=
+#?ini(theme.splash-silent-picture)!=&&ini(theme.splash-silent-type)==background#
+BootImage=/usr/share/plymouth/themes/calculate/boot
+#ini#
+#?ini(theme.splash-silent-picture)!=&&ini(theme.splash-silent-type)==logo#
+BootImage=/usr/share/plymouth/themes/calculate/boot.png
+#ini#
+#?ini(theme.splash-silent-picture)==||exists(#-ini(theme.splash-silent-picture)-#)==#
+!BootImage=
+#ini#
+#?ini(theme.splash-shutdown-picture)!=&&ini(theme.splash-shutdown-type)==background#
+ShutdownImage=/usr/share/plymouth/themes/calculate/.shutdown
+#ini#
+#?ini(theme.splash-shutdown-picture)!=&&ini(theme.splash-shutdown-type)==logo#
+ShutdownImage=/usr/share/plymouth/themes/calculate/.shutdown.png
+#ini#
+#?ini(theme.splash-shutdown-picture)==||exists(#-ini(theme.splash-shutdown-picture)-#)==#
+!ShutdownImage=
+#ini#
+ShutdownTextColor=0x#-ini(theme.splash-shutdown-text-color)-#
diff --git a/profiles/templates/3.6/3_ac_install_live/1-merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth b/profiles/templates/3.6/3_ac_install_live/1-merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth
index 415d6b40b..0150e927c 100644
--- a/profiles/templates/3.6/3_ac_install_live/1-merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth
+++ b/profiles/templates/3.6/3_ac_install_live/1-merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth
@@ -1,12 +1,26 @@
-# Calculate format=kde path=/usr/share/plymouth/themes/calculate
+# Calculate format=kde path=/usr/share/plymouth/themes/calculate pkg(sys-boot/plymouth-calculate-plugin)>=0.9.5 name=calculate.plymouth
[calculate]
+Font=DroidSans #-sum(yres,,#-cut(1,x,#-list(cl_resolutions,0)-#)-#)-##-sum(km,yres*16/1080,km)-#
+TitleFont=DroidSans #-sum(yres,,#-cut(1,x,#-list(cl_resolutions,0)-#)-#)-##-sum(km,yres*20/1080,km)-#
+
+[shutdown]
#?os_install_locale_lang==ru_RU#
-ShutdownText=З а в е р ш е н и е р а б о т ы
+Title=З а в е р ш е н и е р а б о т ы
#os_install_locale_lang#
#?os_install_locale_lang==fr_FR#
-ShutdownText=A r r ê t e n c o u r s
+Title=A r r ê t e n c o u r s
#os_install_locale_lang#
#?os_install_locale_lang!=ru_RU&&os_install_locale_lang!=fr_FR#
-ShutdownText=S h u t t i n g d o w n
+Title=S h u t t i n g d o w n
+#os_install_locale_lang#
+
+[reboot]
+#?os_install_locale_lang==ru_RU#
+Title=З а в е р ш е н и е р а б о т ы
+#os_install_locale_lang#
+#?os_install_locale_lang==fr_FR#
+Title=A r r ê t e n c o u r s
+#os_install_locale_lang#
+#?os_install_locale_lang!=ru_RU&&os_install_locale_lang!=fr_FR#
+Title=S h u t t i n g d o w n
#os_install_locale_lang#
-ShutdownFont=DroidSans #-sum(yres,,#-cut(1,x,#-list(cl_resolutions,0)-#)-#)-##-sum(km,yres*20/1080,km)-#
diff --git a/profiles/templates/3.6/3_ac_install_live/1-merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth-0.9.4 b/profiles/templates/3.6/3_ac_install_live/1-merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth-0.9.4
new file mode 100644
index 000000000..df6e32177
--- /dev/null
+++ b/profiles/templates/3.6/3_ac_install_live/1-merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth-0.9.4
@@ -0,0 +1,12 @@
+# Calculate format=kde path=/usr/share/plymouth/themes/calculate pkg(sys-boot/plymouth-calculate-plugin)<0.9.5 name=calculate.plymouth
+[calculate]
+#?os_install_locale_lang==ru_RU#
+ShutdownText=З а в е р ш е н и е р а б о т ы
+#os_install_locale_lang#
+#?os_install_locale_lang==fr_FR#
+ShutdownText=A r r ê t e n c o u r s
+#os_install_locale_lang#
+#?os_install_locale_lang!=ru_RU&&os_install_locale_lang!=fr_FR#
+ShutdownText=S h u t t i n g d o w n
+#os_install_locale_lang#
+ShutdownFont=DroidSans #-sum(yres,,#-cut(1,x,#-list(cl_resolutions,0)-#)-#)-##-sum(km,yres*20/1080,km)-#
diff --git a/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-init_fb-0.9.4.patch b/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-init_fb-0.9.4.patch
new file mode 100644
index 000000000..9e65b0cb6
--- /dev/null
+++ b/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-init_fb-0.9.4.patch
@@ -0,0 +1,188 @@
+# Calculate format=diff merge(sys-boot/plymouth)<0.9.5
+commit 4ec46d8b9a1fdd4eb791013bae98e4ca34b412de
+Author: Mir Calculate
+Date: Wed Feb 13 15:35:50 2019 +0300
+
+ Изменён порядок инициализации framebuffer для plymouth
+
+ Добавлена переменная конфигурационного файла
+ FBDeviceTimeout, по истечении которого plymouth будет ожидать не только DRM
+ устройства, но и framebuffer. По истечении DeviceTimeout plymouth будет
+ запущен для text mode.
+
+diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c
+index 55248ac..4350324 100644
+--- a/src/libply-splash-core/ply-device-manager.c
++++ b/src/libply-splash-core/ply-device-manager.c
+@@ -39,12 +39,14 @@
+ #include "ply-hashtable.h"
+ #include "ply-list.h"
+ #include "ply-utils.h"
++#include
+
+ #define SUBSYSTEM_DRM "drm"
+ #define SUBSYSTEM_FRAME_BUFFER "graphics"
+
+ #ifdef HAVE_UDEV
+ static void create_devices_from_udev (ply_device_manager_t *manager);
++static void create_fb_devices_from_udev (ply_device_manager_t *manager);
+ #endif
+
+ static bool create_devices_for_terminal_and_renderer_type (ply_device_manager_t *manager,
+@@ -81,6 +83,7 @@ struct _ply_device_manager
+
+ uint32_t paused : 1;
+ uint32_t device_timeout_elapsed : 1;
++ uint32_t fb_device_timeout_elapsed : 1;
+ };
+
+ static void
+@@ -361,7 +364,12 @@ on_udev_event (ply_device_manager_t *manager)
+ ply_trace ("ignoring since we're already using text splash for local console");
+ else
+ create_devices_for_udev_device (manager, device);
+- } else {
++ } else if (manager->fb_device_timeout_elapsed && strcmp (subsystem, SUBSYSTEM_FRAME_BUFFER) == 0){
++ if (manager->local_console_managed && manager->local_console_is_text)
++ ply_trace ("ignoring since we're already using text splash for local console");
++ else
++ create_devices_for_udev_device (manager, device);
++ } else {
+ ply_trace ("ignoring since we only handle subsystem %s devices after timeout", subsystem);
+ }
+ } else if (strcmp (action, "remove") == 0) {
+@@ -539,6 +547,9 @@ ply_device_manager_free (ply_device_manager_t *manager)
+ ply_event_loop_stop_watching_for_timeout (manager->loop,
+ (ply_event_loop_timeout_handler_t)
+ create_devices_from_udev, manager);
++ ply_event_loop_stop_watching_for_timeout (manager->loop,
++ (ply_event_loop_timeout_handler_t)
++ create_fb_devices_from_udev, manager);
+
+ if (manager->udev_monitor != NULL)
+ udev_monitor_unref (manager->udev_monitor);
+@@ -838,6 +849,24 @@ create_devices_from_udev (ply_device_manager_t *manager)
+ ply_trace ("Creating non-graphical devices, since there's no suitable graphics hardware");
+ create_non_graphical_devices (manager);
+ }
++
++static void
++create_fb_devices_from_udev (ply_device_manager_t *manager)
++{
++ bool found_drm_device, found_fb_device;
++
++ manager->fb_device_timeout_elapsed = true;
++
++ if (manager->paused) {
++ ply_trace ("create_fb_devices_from_udev timeout elapsed while paused, deferring execution");
++ return;
++ }
++
++ ply_trace ("Timeout elapsed, looking for framebuffer devices from udev");
++
++ found_drm_device = create_devices_for_subsystem (manager, SUBSYSTEM_DRM);
++ found_fb_device = create_devices_for_subsystem (manager, SUBSYSTEM_FRAME_BUFFER);
++}
+ #endif
+
+ static void
+@@ -851,6 +880,7 @@ create_fallback_devices (ply_device_manager_t *manager)
+
+ void
+ ply_device_manager_watch_devices (ply_device_manager_t *manager,
++ double fb_device_timeout,
+ double device_timeout,
+ ply_keyboard_added_handler_t keyboard_added_handler,
+ ply_keyboard_removed_handler_t keyboard_removed_handler,
+@@ -870,6 +900,9 @@ ply_device_manager_watch_devices (ply_device_manager_t *manager,
+ manager->text_display_removed_handler = text_display_removed_handler;
+ manager->event_handler_data = data;
+
++ if (isnan (fb_device_timeout))
++ fb_device_timeout = 5;
++
+ /* Try to create devices for each serial device right away, if possible
+ */
+ done_with_initial_devices_setup = create_devices_from_terminals (manager);
+@@ -892,6 +925,10 @@ ply_device_manager_watch_devices (ply_device_manager_t *manager,
+ #ifdef HAVE_UDEV
+ watch_for_udev_events (manager);
+ create_devices_for_subsystem (manager, SUBSYSTEM_DRM);
++ ply_event_loop_watch_for_timeout (manager->loop,
++ fb_device_timeout,
++ (ply_event_loop_timeout_handler_t)
++ create_fb_devices_from_udev, manager);
+ ply_event_loop_watch_for_timeout (manager->loop,
+ device_timeout,
+ (ply_event_loop_timeout_handler_t)
+@@ -1035,6 +1072,10 @@ ply_device_manager_unpause (ply_device_manager_t *manager)
+ ply_trace ("ply_device_manager_unpause() called, resuming watching for udev events");
+ manager->paused = false;
+ #ifdef HAVE_UDEV
++ if (manager->fb_device_timeout_elapsed) {
++ ply_trace ("ply_device_manager_unpause(): timeout elapsed while paused, looking for framebuffer udev devices");
++ create_fb_devices_from_udev (manager);
++ }
+ if (manager->device_timeout_elapsed) {
+ ply_trace ("ply_device_manager_unpause(): timeout elapsed while paused, looking for udev devices");
+ create_devices_from_udev (manager);
+diff --git a/src/libply-splash-core/ply-device-manager.h b/src/libply-splash-core/ply-device-manager.h
+index 389b636..37198a2 100644
+--- a/src/libply-splash-core/ply-device-manager.h
++++ b/src/libply-splash-core/ply-device-manager.h
+@@ -47,6 +47,7 @@ typedef void (* ply_text_display_removed_handler_t) (void *, ply_text_display_t
+ ply_device_manager_t *ply_device_manager_new (const char *default_tty,
+ ply_device_manager_flags_t flags);
+ void ply_device_manager_watch_devices (ply_device_manager_t *manager,
++ double fb_device_timeout,
+ double device_timeout,
+ ply_keyboard_added_handler_t keyboard_added_handler,
+ ply_keyboard_removed_handler_t keyboard_removed_handler,
+diff --git a/src/main.c b/src/main.c
+index ddc1883..f8f980c 100644
+--- a/src/main.c
++++ b/src/main.c
+@@ -103,6 +103,7 @@ typedef struct
+ double start_time;
+ double splash_delay;
+ double device_timeout;
++ double fb_device_timeout;
+
+ uint32_t no_boot_log : 1;
+ uint32_t showing_details : 1;
+@@ -340,6 +341,19 @@ load_settings (state_t *state,
+ }
+ }
+
++ if (isnan (state->fb_device_timeout)) {
++ char *timeout_string;
++
++ timeout_string = ply_key_file_get_value (key_file, "Daemon", "FBDeviceTimeout");
++
++ if (timeout_string != NULL) {
++ state->fb_device_timeout = atof (timeout_string);
++ ply_trace ("Framebuffer device timeout is set to %lf", state->fb_device_timeout);
++
++ free (timeout_string);
++ }
++ }
++
+ scale_string = ply_key_file_get_value (key_file, "Daemon", "DeviceScale");
+
+ if (scale_string != NULL) {
+@@ -1100,6 +1114,7 @@ load_devices (state_t *state,
+ state->local_console_terminal = ply_device_manager_get_default_terminal (state->device_manager);
+
+ ply_device_manager_watch_devices (state->device_manager,
++ state->fb_device_timeout,
+ state->device_timeout,
+ (ply_keyboard_added_handler_t)
+ on_keyboard_added,
+@@ -2269,6 +2284,7 @@ main (int argc,
+ state.progress = ply_progress_new ();
+ state.splash_delay = NAN;
+ state.device_timeout = NAN;
++ state.fb_device_timeout = NAN;
+
+ ply_progress_load_cache (state.progress,
+ get_cache_file_for_mode (state.mode));
diff --git a/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-init_fb.patch b/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-init_fb.patch
index e9a4373ea..fb7f7f623 100644
--- a/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-init_fb.patch
+++ b/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-init_fb.patch
@@ -1,17 +1,6 @@
-# Calculate format=diff
-commit 4ec46d8b9a1fdd4eb791013bae98e4ca34b412de
-Author: Mir Calculate
-Date: Wed Feb 13 15:35:50 2019 +0300
-
- Изменён порядок инициализации framebuffer для plymouth
-
- Добавлена переменная конфигурационного файла
- FBDeviceTimeout, по истечении которого plymouth будет ожидать не только DRM
- устройства, но и framebuffer. По истечении DeviceTimeout plymouth будет
- запущен для text mode.
-
+# Calculate format=diff merge(sys-boot/plymouth)>=0.9.5
diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c
-index 55248ac..4350324 100644
+index f65d731..954a241 100644
--- a/src/libply-splash-core/ply-device-manager.c
+++ b/src/libply-splash-core/ply-device-manager.c
@@ -39,12 +39,14 @@
@@ -29,29 +18,29 @@ index 55248ac..4350324 100644
#endif
static bool create_devices_for_terminal_and_renderer_type (ply_device_manager_t *manager,
-@@ -81,6 +83,7 @@ struct _ply_device_manager
+@@ -84,6 +86,7 @@ struct _ply_device_manager
uint32_t paused : 1;
uint32_t device_timeout_elapsed : 1;
-+ uint32_t fb_device_timeout_elapsed : 1;
++ uint32_t fb_device_timeout_elapsed : 1;
+ uint32_t found_drm_device : 1;
+ uint32_t found_fb_device : 1;
};
-
- static void
-@@ -361,7 +364,12 @@ on_udev_event (ply_device_manager_t *manager)
+@@ -442,7 +445,12 @@ on_udev_event (ply_device_manager_t *manager)
ply_trace ("ignoring since we're already using text splash for local console");
else
- create_devices_for_udev_device (manager, device);
+ on_drm_udev_add_or_change (manager, action, device);
- } else {
+ } else if (manager->fb_device_timeout_elapsed && strcmp (subsystem, SUBSYSTEM_FRAME_BUFFER) == 0){
+ if (manager->local_console_managed && manager->local_console_is_text)
+ ply_trace ("ignoring since we're already using text splash for local console");
+ else
-+ create_devices_for_udev_device (manager, device);
++ on_drm_udev_add_or_change (manager, action, device);
+ } else {
ply_trace ("ignoring since we only handle subsystem %s devices after timeout", subsystem);
}
} else if (strcmp (action, "remove") == 0) {
-@@ -539,6 +547,9 @@ ply_device_manager_free (ply_device_manager_t *manager)
+@@ -620,6 +628,9 @@ ply_device_manager_free (ply_device_manager_t *manager)
ply_event_loop_stop_watching_for_timeout (manager->loop,
(ply_event_loop_timeout_handler_t)
create_devices_from_udev, manager);
@@ -61,7 +50,7 @@ index 55248ac..4350324 100644
if (manager->udev_monitor != NULL)
udev_monitor_unref (manager->udev_monitor);
-@@ -838,6 +849,24 @@ create_devices_from_udev (ply_device_manager_t *manager)
+@@ -917,6 +928,22 @@ create_devices_from_udev (ply_device_manager_t *manager)
ply_trace ("Creating non-graphical devices, since there's no suitable graphics hardware");
create_non_graphical_devices (manager);
}
@@ -69,8 +58,6 @@ index 55248ac..4350324 100644
+static void
+create_fb_devices_from_udev (ply_device_manager_t *manager)
+{
-+ bool found_drm_device, found_fb_device;
-+
+ manager->fb_device_timeout_elapsed = true;
+
+ if (manager->paused) {
@@ -80,31 +67,31 @@ index 55248ac..4350324 100644
+
+ ply_trace ("Timeout elapsed, looking for framebuffer devices from udev");
+
-+ found_drm_device = create_devices_for_subsystem (manager, SUBSYSTEM_DRM);
-+ found_fb_device = create_devices_for_subsystem (manager, SUBSYSTEM_FRAME_BUFFER);
++ create_devices_for_subsystem (manager, SUBSYSTEM_DRM);
++ create_devices_for_subsystem (manager, SUBSYSTEM_FRAME_BUFFER);
+}
#endif
static void
-@@ -851,6 +880,7 @@ create_fallback_devices (ply_device_manager_t *manager)
+@@ -930,6 +957,7 @@ create_fallback_devices (ply_device_manager_t *manager)
void
ply_device_manager_watch_devices (ply_device_manager_t *manager,
-+ double fb_device_timeout,
++ double fb_device_timeout,
double device_timeout,
ply_keyboard_added_handler_t keyboard_added_handler,
ply_keyboard_removed_handler_t keyboard_removed_handler,
-@@ -870,6 +900,9 @@ ply_device_manager_watch_devices (ply_device_manager_t *manager,
+@@ -949,6 +977,9 @@ ply_device_manager_watch_devices (ply_device_manager_t *manager,
manager->text_display_removed_handler = text_display_removed_handler;
manager->event_handler_data = data;
-+ if (isnan (fb_device_timeout))
-+ fb_device_timeout = 5;
++ if (isnan (fb_device_timeout))
++ fb_device_timeout = 5;
+
/* Try to create devices for each serial device right away, if possible
*/
done_with_initial_devices_setup = create_devices_from_terminals (manager);
-@@ -892,6 +925,10 @@ ply_device_manager_watch_devices (ply_device_manager_t *manager,
+@@ -971,6 +1002,10 @@ ply_device_manager_watch_devices (ply_device_manager_t *manager,
#ifdef HAVE_UDEV
watch_for_udev_events (manager);
create_devices_for_subsystem (manager, SUBSYSTEM_DRM);
@@ -115,12 +102,12 @@ index 55248ac..4350324 100644
ply_event_loop_watch_for_timeout (manager->loop,
device_timeout,
(ply_event_loop_timeout_handler_t)
-@@ -1035,6 +1072,10 @@ ply_device_manager_unpause (ply_device_manager_t *manager)
+@@ -1114,6 +1149,10 @@ ply_device_manager_unpause (ply_device_manager_t *manager)
ply_trace ("ply_device_manager_unpause() called, resuming watching for udev events");
manager->paused = false;
#ifdef HAVE_UDEV
+ if (manager->fb_device_timeout_elapsed) {
-+ ply_trace ("ply_device_manager_unpause(): timeout elapsed while paused, looking for framebuffer udev devices");
++ ply_trace ("ply_device_manager_unpause(): timeout elapsed while paused, looking for udev devices");
+ create_fb_devices_from_udev (manager);
+ }
if (manager->device_timeout_elapsed) {
@@ -139,10 +126,10 @@ index 389b636..37198a2 100644
ply_keyboard_added_handler_t keyboard_added_handler,
ply_keyboard_removed_handler_t keyboard_removed_handler,
diff --git a/src/main.c b/src/main.c
-index ddc1883..f8f980c 100644
+index 850c3b0..13c9272 100644
--- a/src/main.c
+++ b/src/main.c
-@@ -103,6 +103,7 @@ typedef struct
+@@ -97,6 +97,7 @@ typedef struct
double start_time;
double splash_delay;
double device_timeout;
@@ -150,7 +137,7 @@ index ddc1883..f8f980c 100644
uint32_t no_boot_log : 1;
uint32_t showing_details : 1;
-@@ -340,6 +341,19 @@ load_settings (state_t *state,
+@@ -317,6 +318,19 @@ load_settings (state_t *state,
}
}
@@ -170,7 +157,7 @@ index ddc1883..f8f980c 100644
scale_string = ply_key_file_get_value (key_file, "Daemon", "DeviceScale");
if (scale_string != NULL) {
-@@ -1100,6 +1114,7 @@ load_devices (state_t *state,
+@@ -1096,6 +1110,7 @@ load_devices (state_t *state,
state->local_console_terminal = ply_device_manager_get_default_terminal (state->device_manager);
ply_device_manager_watch_devices (state->device_manager,
@@ -178,7 +165,7 @@ index ddc1883..f8f980c 100644
state->device_timeout,
(ply_keyboard_added_handler_t)
on_keyboard_added,
-@@ -2269,6 +2284,7 @@ main (int argc,
+@@ -2244,6 +2259,7 @@ main (int argc,
state.progress = ply_progress_new ();
state.splash_delay = NAN;
state.device_timeout = NAN;
diff --git a/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-shutdown-0.9.4.patch b/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-shutdown-0.9.4.patch
new file mode 100644
index 000000000..d31fef9c7
--- /dev/null
+++ b/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-shutdown-0.9.4.patch
@@ -0,0 +1,23 @@
+# Calculate format=diff merge(sys-boot/plymouth)<0.9.5
+commit c0e512de2352611112c5476e0032514e2b2d713c
+Author: Mir Calculate
+Date: Tue Feb 19 12:17:41 2019 +0300
+
+ Добавлена возможность указать запуск splash только для shutdown
+
+diff --git a/src/main.c b/src/main.c
+index f8f980c..c702c10 100644
+--- a/src/main.c
++++ b/src/main.c
+@@ -916,6 +916,11 @@ plymouth_should_show_default_splash (state_t *state)
+ return true;
+ }
+
++ if (ply_kernel_command_line_has_argument ("splash=shutdown") && state->mode == PLY_MODE_SHUTDOWN) {
++ ply_trace ("using default splash because kernel command line has option \"splash=shutdown\"");
++ return true;
++ }
++
+ if (ply_kernel_command_line_has_argument ("splash=silent")) {
+ ply_trace ("using default splash because kernel command line has option \"splash=silent\"");
+ return true;
diff --git a/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-shutdown.patch b/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-shutdown.patch
index 828758b41..a6fea453e 100644
--- a/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-shutdown.patch
+++ b/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-shutdown.patch
@@ -1,4 +1,4 @@
-# Calculate format=diff
+# Calculate format=diff pkg(sys-boot/plymouth)>=0.9.5
commit c0e512de2352611112c5476e0032514e2b2d713c
Author: Mir Calculate
Date: Tue Feb 19 12:17:41 2019 +0300
@@ -13,7 +13,7 @@ index f8f980c..c702c10 100644
return true;
}
-+ if (ply_kernel_command_line_has_argument ("splash=shutdown") && state->mode == PLY_MODE_SHUTDOWN) {
++ if (ply_kernel_command_line_has_argument ("splash=shutdown") && state->mode == PLY_BOOT_SPLASH_MODE_SHUTDOWN) {
+ ply_trace ("using default splash because kernel command line has option \"splash=shutdown\"");
+ return true;
+ }
diff --git a/sys-apps/calculate-utils/calculate-utils-3.6.8.15.ebuild b/sys-apps/calculate-utils/calculate-utils-3.6.8.15-r1.ebuild
similarity index 100%
rename from sys-apps/calculate-utils/calculate-utils-3.6.8.15.ebuild
rename to sys-apps/calculate-utils/calculate-utils-3.6.8.15-r1.ebuild
diff --git a/sys-boot/plymouth-calculate-plugin/Manifest b/sys-boot/plymouth-calculate-plugin/Manifest
index 8c959d026..c41ebb209 100644
--- a/sys-boot/plymouth-calculate-plugin/Manifest
+++ b/sys-boot/plymouth-calculate-plugin/Manifest
@@ -1 +1,2 @@
DIST plymouth-0.9.4.tar.xz 1103496 BLAKE2B abad2cefb89e9d17b77113396d7203090544759b3dd7f73f67153d9f126db28e5366d36aa11e2335566bf4046bebd50d8d9dd47c75634446fb3a0314cd458925 SHA512 83eb2de7e6d0980e9f7fa4e0b0f20c46a8238051d84bc38dbbb5dfa438e41c1a39846dcd652374256d9f1fe79967b154a3576cd9c433ef816b6c962be2d31e93
+DIST plymouth-0.9.5.tar.xz 1186200 BLAKE2B 8fd073703773fcf7f3e26454c860f094fb4b3d712c56c9df6716ef11815a79f7d5b078ab6c6567b76421026d84a086f95865bf9f3e4ae6363cb1ffc2caa68537 SHA512 686220e8d5b1a8be298156786d979d0e3fb9e010b930d0e8082a2bb152cf07c1bf493d820c243838a1771ee859dc0b4723bd9f10ee434a94a096ce9236c36ce9
diff --git a/sys-boot/plymouth-calculate-plugin/files/0.9.5-calculate.plymouth b/sys-boot/plymouth-calculate-plugin/files/0.9.5-calculate.plymouth
new file mode 100644
index 000000000..d23ed1b73
--- /dev/null
+++ b/sys-boot/plymouth-calculate-plugin/files/0.9.5-calculate.plymouth
@@ -0,0 +1,74 @@
+[Plymouth Theme]
+Name=Calculate
+Description=Calculate spinner theme
+ModuleName=calculate
+
+[calculate]
+Font=DroidSans 12
+TitleFont=DroidSans 30
+ImageDir=/usr/share/plymouth/themes/calculate
+DialogHorizontalAlignment=.5
+DialogVerticalAlignment=.382
+TitleHorizontalAlignment=.5
+TitleVerticalAlignment=.5
+HorizontalAlignment=.5
+VerticalAlignment=.5
+WatermarkHorizontalAlignment=.5
+WatermarkVerticalAlignment=.5
+Transition=none
+TransitionDuration=0.0
+BackgroundStartColor=0x000000
+BackgroundEndColor=0x000000
+ProgressBarBackgroundColor=0x606060
+ProgressBarForegroundColor=0xffffff
+DialogClearsFirmwareBackground=true
+MessageBelowAnimation=true
+
+[boot-up]
+UseEndAnimation=false
+UseFirmwareBackground=false
+VerticalAlignmentType=below_watermark
+VerticalAlignment=.0
+WatermarkImage=/usr/share/plymouth/themes/calculate/boot.png
+
+[shutdown]
+UseEndAnimation=false
+UseFirmwareBackground=false
+Title=Shutdown...
+TitleColor=0xaaaaaa
+VerticalAlignment=.0
+VerticalAlignmentType=below_title
+WatermarkImage=/usr/share/plymouth/themes/calculate/.shutdown
+
+[reboot]
+UseEndAnimation=false
+UseFirmwareBackground=false
+Title=Reboot...
+TitleColor=0xaaaaaa
+VerticalAlignment=.0
+VerticalAlignmentType=below_title
+WatermarkImage=/usr/share/plymouth/themes/calculate/.shutdown
+
+[updates]
+UseFirmwareBackground=false
+SuppressMessages=true
+ProgressBarShowPercentComplete=true
+UseProgressBar=true
+Title=Installing Updates...
+SubTitle=Do not turn off your computer
+
+[system-upgrade]
+UseFirmwareBackground=false
+SuppressMessages=true
+ProgressBarShowPercentComplete=true
+UseProgressBar=true
+Title=Upgrading System...
+SubTitle=Do not turn off your computer
+
+[firmware-upgrade]
+UseFirmwareBackground=false
+SuppressMessages=true
+ProgressBarShowPercentComplete=true
+UseProgressBar=true
+Title=Upgrading Firmware...
+SubTitle=Do not turn off your computer
diff --git a/sys-boot/plymouth-calculate-plugin/files/0.9.5-plugin.c b/sys-boot/plymouth-calculate-plugin/files/0.9.5-plugin.c
new file mode 100644
index 000000000..98d0c809a
--- /dev/null
+++ b/sys-boot/plymouth-calculate-plugin/files/0.9.5-plugin.c
@@ -0,0 +1,2223 @@
+/*
+ *
+ * Copyright (C) 2009-2019 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: William Jon McCann, Hans de Goede
+ *
+ */
+#include "config.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "ply-boot-splash-plugin.h"
+#include "ply-buffer.h"
+#include "ply-capslock-icon.h"
+#include "ply-entry.h"
+#include "ply-event-loop.h"
+#include "ply-label.h"
+#include "ply-list.h"
+#include "ply-logger.h"
+#include "ply-image.h"
+#include "ply-key-file.h"
+#include "ply-keymap-icon.h"
+#include "ply-trigger.h"
+#include "ply-pixel-buffer.h"
+#include "ply-pixel-display.h"
+#include "ply-utils.h"
+#include "ply-i18n.h"
+
+#include "ply-animation.h"
+#include "ply-progress-animation.h"
+#include "ply-throbber.h"
+#include "ply-progress-bar.h"
+
+#include
+
+#ifndef FRAMES_PER_SECOND
+#define FRAMES_PER_SECOND 30
+#endif
+
+#ifndef SHOW_ANIMATION_FRACTION
+#define SHOW_ANIMATION_FRACTION 0.9
+#endif
+
+#define PROGRESS_BAR_WIDTH 400
+#define PROGRESS_BAR_HEIGHT 5
+
+#define BGRT_STATUS_ORIENTATION_OFFSET_0 (0 << 1)
+#define BGRT_STATUS_ORIENTATION_OFFSET_90 (1 << 1)
+#define BGRT_STATUS_ORIENTATION_OFFSET_180 (2 << 1)
+#define BGRT_STATUS_ORIENTATION_OFFSET_270 (3 << 1)
+#define BGRT_STATUS_ORIENTATION_OFFSET_MASK (3 << 1)
+
+typedef enum
+{
+ PLY_BOOT_SPLASH_DISPLAY_NORMAL,
+ PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY,
+ PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY
+} ply_boot_splash_display_type_t;
+
+typedef enum
+{
+ PROGRESS_FUNCTION_TYPE_WWOODS,
+ PROGRESS_FUNCTION_TYPE_LINEAR,
+} progress_function_t;
+
+typedef struct
+{
+ ply_boot_splash_plugin_t *plugin;
+ ply_pixel_display_t *display;
+ ply_entry_t *entry;
+ ply_keymap_icon_t *keymap_icon;
+ ply_capslock_icon_t *capslock_icon;
+ ply_animation_t *end_animation;
+ ply_progress_animation_t *progress_animation;
+ ply_progress_bar_t *progress_bar;
+ ply_throbber_t *throbber;
+ ply_label_t *label;
+ ply_label_t *message_label;
+ ply_label_t *title_label;
+ ply_label_t *subtitle_label;
+ ply_rectangle_t box_area, lock_area, watermark_area, title_area, dialog_area;
+ ply_trigger_t *end_trigger;
+ ply_pixel_buffer_t *background_buffer;
+ ply_image_t *watermark_image;
+ int animation_bottom;
+} view_t;
+
+typedef struct
+{
+ bool suppress_messages;
+ bool progress_bar_show_percent_complete;
+ bool use_progress_bar;
+ bool use_animation;
+ bool use_end_animation;
+ bool use_firmware_background;
+ char *title;
+ char *subtitle;
+ uint32_t background_start_color;
+ uint32_t background_end_color;
+ uint32_t title_color;
+ char *watermark_imagename;
+ double animation_horizontal_alignment;
+ double animation_vertical_alignment;
+ char *animation_vertical_alignment_type;
+} mode_settings_t;
+
+struct _ply_boot_splash_plugin
+{
+ ply_event_loop_t *loop;
+ ply_boot_splash_mode_t mode;
+ mode_settings_t mode_settings[PLY_BOOT_SPLASH_MODE_COUNT];
+ char *font;
+ ply_image_t *lock_image;
+ ply_image_t *box_image;
+ ply_image_t *corner_image;
+ ply_image_t *header_image;
+ ply_image_t *background_tile_image;
+ ply_image_t *background_bgrt_image;
+ ply_list_t *views;
+
+ ply_boot_splash_display_type_t state;
+
+ double dialog_horizontal_alignment;
+ double dialog_vertical_alignment;
+
+ double title_horizontal_alignment;
+ double title_vertical_alignment;
+ char *title_font;
+
+ double watermark_horizontal_alignment;
+ double watermark_vertical_alignment;
+ char *watermark_imagename;
+
+ double animation_horizontal_alignment;
+ double animation_vertical_alignment;
+ char *animation_vertical_alignment_type;
+ char *animation_dir;
+
+ ply_progress_animation_transition_t transition;
+ double transition_duration;
+
+ uint32_t background_start_color;
+ uint32_t background_end_color;
+ uint32_t title_color;
+ int background_bgrt_raw_width;
+ int background_bgrt_raw_height;
+
+ double progress_bar_horizontal_alignment;
+ double progress_bar_vertical_alignment;
+ long progress_bar_width;
+ long progress_bar_height;
+ uint32_t progress_bar_bg_color;
+ uint32_t progress_bar_fg_color;
+
+ progress_function_t progress_function;
+
+ ply_trigger_t *idle_trigger;
+ ply_trigger_t *stop_trigger;
+
+ uint32_t root_is_mounted : 1;
+ uint32_t is_visible : 1;
+ uint32_t is_animating : 1;
+ uint32_t is_idle : 1;
+ uint32_t use_firmware_background : 1;
+ uint32_t dialog_clears_firmware_background : 1;
+ uint32_t message_below_animation : 1;
+};
+
+ply_boot_splash_plugin_interface_t *ply_boot_splash_plugin_get_interface (void);
+
+static void stop_animation (ply_boot_splash_plugin_t *plugin);
+static void detach_from_event_loop (ply_boot_splash_plugin_t *plugin);
+static void display_message (ply_boot_splash_plugin_t *plugin,
+ const char *message);
+static void become_idle (ply_boot_splash_plugin_t *plugin,
+ ply_trigger_t *idle_trigger);
+static void view_show_message (view_t *view, const char *message);
+
+bool is_dir(const char* path) {
+ struct stat path_stat;
+ stat(path, &path_stat);
+ return S_ISDIR(path_stat.st_mode);
+}
+
+void image_get_res(const char *basedir, int *xres, int *yres)
+{
+ FILE *fp;
+ char buf[512];
+ int oxres, oyres;
+
+ oxres = *xres;
+ oyres = *yres;
+ snprintf(buf, 512, "%s/%dx%d.png", basedir, oxres, oyres);
+
+ fp = fopen(buf, "r");
+ if (!fp) {
+ *xres = 1024;
+ *yres = 768;
+ unsigned int t, tx, ty, mdist = 0xffffffff;
+ struct dirent *dent;
+ DIR *tdir;
+
+ snprintf(buf, 512, "%s", basedir);
+ tdir = opendir(buf);
+ if (!tdir) {
+ *xres = 0;
+ *yres = 0;
+ return;
+ }
+ while ((dent = readdir(tdir))) {
+ if (sscanf(dent->d_name, "%dx%d.png", &tx, &ty) != 2)
+ continue;
+
+ /* We only want configs for resolutions smaller than the current one,
+ * so that we can actually fit the image on the screen. */
+ if (tx >= oxres || ty >= oyres)
+ continue;
+
+ t = (tx - oxres) * (tx - oxres) + (ty - oyres) * (ty - oyres);
+
+ /* Penalize configs for resolutions with different aspect ratios. */
+ if (oxres / oyres != tx / ty)
+ t *= 10;
+
+ if (t < mdist) {
+ *xres = tx;
+ *yres = ty;
+ mdist = t;
+ }
+ }
+ closedir(tdir);
+ } else {
+ fclose(fp);
+ }
+}
+
+char *detect_image(const char *logo_image, int xres, int yres) {
+ char *buf;
+ if(logo_image != NULL) {
+ if(is_dir(logo_image)) {
+ image_get_res(logo_image, &xres, &yres);
+ if(asprintf(&buf, "%s/%dx%d.png", logo_image, xres, yres) != -1)
+ return buf;
+ } else {
+ return strdup (logo_image);
+ }
+ }
+ return NULL;
+}
+
+long
+calculate_animation_y(view_t *view, double animation_vertical_alignment,
+ char *animation_vertical_alignment_type, unsigned long screen_height, long height)
+{
+ ply_boot_splash_plugin_t *plugin;
+ plugin = view->plugin;
+ long y;
+ if (animation_vertical_alignment_type == NULL) {
+ y = animation_vertical_alignment * screen_height - height / 2.0;
+ } else if (strcmp(animation_vertical_alignment_type,
+ "below_title") == 0) {
+ y = view->title_area.y + view->title_area.height;
+ if( y + height >= screen_height) {
+ y = animation_vertical_alignment * screen_height - height / 2.0;
+ } else {
+ y += animation_vertical_alignment * (screen_height - y);
+ if( animation_vertical_alignment != 0.0) {
+ y -= height / 2;
+ }
+ }
+ } else if (strcmp(animation_vertical_alignment_type,
+ "below_watermark") == 0 && view->watermark_image != NULL) {
+ y = view->watermark_area.y + view->watermark_area.height;
+ if( y + height >= screen_height) {
+ y = animation_vertical_alignment * screen_height - height / 2.0;
+ } else {
+ y += animation_vertical_alignment * (screen_height - y);
+ if( animation_vertical_alignment != 0.0) {
+ y -= height / 2;
+ }
+ }
+ } else {
+ y = animation_vertical_alignment * screen_height - height / 2.0;
+ }
+ return y;
+}
+
+static view_t *
+view_new (ply_boot_splash_plugin_t *plugin,
+ ply_pixel_display_t *display)
+{
+ view_t *view;
+
+ view = calloc (1, sizeof(view_t));
+ view->plugin = plugin;
+ view->display = display;
+ view->watermark_image = NULL;
+
+ view->entry = ply_entry_new (plugin->animation_dir);
+ view->keymap_icon = ply_keymap_icon_new (display, plugin->animation_dir);
+ view->capslock_icon = ply_capslock_icon_new (plugin->animation_dir);
+ view->progress_animation = ply_progress_animation_new (plugin->animation_dir,
+ "progress-");
+ ply_progress_animation_set_transition (view->progress_animation,
+ plugin->transition,
+ plugin->transition_duration);
+
+ view->progress_bar = ply_progress_bar_new ();
+ ply_progress_bar_set_colors (view->progress_bar,
+ plugin->progress_bar_fg_color,
+ plugin->progress_bar_bg_color);
+
+ view->throbber = ply_throbber_new (plugin->animation_dir,
+ "throbber-");
+
+ view->label = ply_label_new ();
+ ply_label_set_font (view->label, plugin->font);
+
+ view->message_label = ply_label_new ();
+ ply_label_set_font (view->message_label, plugin->font);
+
+ view->title_label = ply_label_new ();
+ ply_label_set_font (view->title_label, plugin->title_font);
+
+ view->subtitle_label = ply_label_new ();
+ ply_label_set_font (view->subtitle_label, plugin->font);
+
+ return view;
+}
+
+static void
+view_free (view_t *view)
+{
+ ply_entry_free (view->entry);
+ ply_keymap_icon_free (view->keymap_icon);
+ ply_capslock_icon_free (view->capslock_icon);
+ ply_animation_free (view->end_animation);
+ ply_progress_animation_free (view->progress_animation);
+ ply_progress_bar_free (view->progress_bar);
+ ply_throbber_free (view->throbber);
+ ply_label_free (view->label);
+ ply_label_free (view->message_label);
+ ply_label_free (view->title_label);
+ ply_label_free (view->subtitle_label);
+
+ if (view->watermark_image != NULL)
+ ply_image_free (view->watermark_image);
+
+ if (view->background_buffer != NULL)
+ ply_pixel_buffer_free (view->background_buffer);
+
+ free (view);
+}
+
+static void
+view_load_end_animation (view_t *view)
+{
+ ply_boot_splash_plugin_t *plugin = view->plugin;
+ const char *animation_prefix;
+
+ if (!plugin->mode_settings[plugin->mode].use_end_animation)
+ return;
+
+ ply_trace ("loading animation");
+
+ switch (plugin->mode) {
+ case PLY_BOOT_SPLASH_MODE_BOOT_UP:
+ case PLY_BOOT_SPLASH_MODE_UPDATES:
+ case PLY_BOOT_SPLASH_MODE_SYSTEM_UPGRADE:
+ case PLY_BOOT_SPLASH_MODE_FIRMWARE_UPGRADE:
+ animation_prefix = "startup-animation-";
+ break;
+ case PLY_BOOT_SPLASH_MODE_SHUTDOWN:
+ case PLY_BOOT_SPLASH_MODE_REBOOT:
+ animation_prefix = "shutdown-animation-";
+ break;
+ case PLY_BOOT_SPLASH_MODE_INVALID:
+ default:
+ ply_trace ("unexpected splash mode 0x%x\n", plugin->mode);
+ return;
+ }
+
+ ply_trace ("trying prefix: %s", animation_prefix);
+ view->end_animation = ply_animation_new (plugin->animation_dir,
+ animation_prefix);
+
+ if (ply_animation_load (view->end_animation))
+ return;
+ ply_animation_free (view->end_animation);
+
+ ply_trace ("now trying more general prefix: animation-");
+ view->end_animation = ply_animation_new (plugin->animation_dir,
+ "animation-");
+ if (ply_animation_load (view->end_animation))
+ return;
+ ply_animation_free (view->end_animation);
+
+ ply_trace ("now trying old compat prefix: throbber-");
+ view->end_animation = ply_animation_new (plugin->animation_dir,
+ "throbber-");
+ if (ply_animation_load (view->end_animation)) {
+ /* files named throbber- are for end animation, so
+ * there's no throbber */
+ ply_throbber_free (view->throbber);
+ view->throbber = NULL;
+ return;
+ }
+
+ ply_trace ("optional animation didn't load");
+ ply_animation_free (view->end_animation);
+ view->end_animation = NULL;
+ plugin->mode_settings[plugin->mode].use_end_animation = false;
+}
+
+static bool
+get_bgrt_sysfs_info(int *x_offset, int *y_offset,
+ ply_pixel_buffer_rotation_t *rotation)
+{
+ bool ret = false;
+ char buf[64];
+ int status;
+ FILE *f;
+
+ f = fopen("/sys/firmware/acpi/bgrt/status", "r");
+ if (!f)
+ return false;
+
+ if (!fgets(buf, sizeof(buf), f))
+ goto out;
+
+ if (sscanf(buf, "%d", &status) != 1)
+ goto out;
+
+ fclose(f);
+
+ switch (status & BGRT_STATUS_ORIENTATION_OFFSET_MASK) {
+ case BGRT_STATUS_ORIENTATION_OFFSET_0:
+ *rotation = PLY_PIXEL_BUFFER_ROTATE_UPRIGHT;
+ break;
+ case BGRT_STATUS_ORIENTATION_OFFSET_90:
+ *rotation = PLY_PIXEL_BUFFER_ROTATE_COUNTER_CLOCKWISE;
+ break;
+ case BGRT_STATUS_ORIENTATION_OFFSET_180:
+ *rotation = PLY_PIXEL_BUFFER_ROTATE_UPSIDE_DOWN;
+ break;
+ case BGRT_STATUS_ORIENTATION_OFFSET_270:
+ *rotation = PLY_PIXEL_BUFFER_ROTATE_CLOCKWISE;
+ break;
+ }
+
+ f = fopen("/sys/firmware/acpi/bgrt/xoffset", "r");
+ if (!f)
+ return false;
+
+ if (!fgets(buf, sizeof(buf), f))
+ goto out;
+
+ if (sscanf(buf, "%d", x_offset) != 1)
+ goto out;
+
+ fclose(f);
+
+ f = fopen("/sys/firmware/acpi/bgrt/yoffset", "r");
+ if (!f)
+ return false;
+
+ if (!fgets(buf, sizeof(buf), f))
+ goto out;
+
+ if (sscanf(buf, "%d", y_offset) != 1)
+ goto out;
+
+ ret = true;
+out:
+ fclose(f);
+ return ret;
+}
+
+/* The Microsoft boot logo spec says that the logo must use a black background
+ * and have its center at 38.2% from the screen's top (golden ratio).
+ * We reproduce this exactly here so that we get a background which is an exact
+ * match of the firmware's boot splash.
+ * At the time of writing this comment this is documented in a document called
+ * "Boot screen components" which is available here:
+ * https://docs.microsoft.com/en-us/windows-hardware/drivers/bringup/boot-screen-components
+ * Note that we normally do not use the firmware reported x and y-offset as
+ * that is based on the EFI fb resolution which may not be the native
+ * resolution of the screen (esp. when using multiple heads).
+ */
+static void
+view_set_bgrt_background (view_t *view)
+{
+ ply_pixel_buffer_rotation_t panel_rotation = PLY_PIXEL_BUFFER_ROTATE_UPRIGHT;
+ ply_pixel_buffer_rotation_t bgrt_rotation = PLY_PIXEL_BUFFER_ROTATE_UPRIGHT;
+ int x_offset, y_offset, sysfs_x_offset, sysfs_y_offset, width, height;
+ int panel_width = 0, panel_height = 0, panel_scale = 1;
+ int screen_width, screen_height, screen_scale;
+ ply_pixel_buffer_t *bgrt_buffer;
+ bool have_panel_props;
+
+ if (!view->plugin->background_bgrt_image)
+ return;
+
+ if (!get_bgrt_sysfs_info(&sysfs_x_offset, &sysfs_y_offset,
+ &bgrt_rotation)) {
+ ply_trace ("get bgrt sysfs info failed");
+ return;
+ }
+
+ screen_width = ply_pixel_display_get_width (view->display);
+ screen_height = ply_pixel_display_get_height (view->display);
+ screen_scale = ply_pixel_display_get_device_scale (view->display);
+
+ bgrt_buffer = ply_image_get_buffer (view->plugin->background_bgrt_image);
+
+ have_panel_props = ply_renderer_get_panel_properties (ply_pixel_display_get_renderer (view->display),
+ &panel_width, &panel_height,
+ &panel_rotation, &panel_scale);
+
+ /*
+ * Some buggy Lenovo 2-in-1s with a 90 degree rotated panel, behave as
+ * if the panel is mounted up-right / not rotated at all. These devices
+ * have a buggy efifb size (landscape resolution instead of the actual
+ * portrait resolution of the panel), this gets fixed-up by the kernel.
+ * These buggy devices also do not pre-rotate the bgrt_image nor do
+ * they set the ACPI-6.2 rotation status-bits. We can detect this by
+ * checking that the bgrt_image is perfectly centered horizontally
+ * when we use the panel's height as the width.
+ */
+ if (have_panel_props &&
+ (panel_rotation == PLY_PIXEL_BUFFER_ROTATE_CLOCKWISE ||
+ panel_rotation == PLY_PIXEL_BUFFER_ROTATE_COUNTER_CLOCKWISE) &&
+ (panel_width - view->plugin->background_bgrt_raw_width) / 2 != sysfs_x_offset &&
+ (panel_height - view->plugin->background_bgrt_raw_width) / 2 == sysfs_x_offset)
+ bgrt_rotation = panel_rotation;
+
+ /*
+ * Before the ACPI 6.2 specification, the BGRT table did not contain
+ * any rotation information, so to make sure that the firmware-splash
+ * showed the right way up the firmware would contain a pre-rotated
+ * image. Starting with ACPI 6.2 the bgrt status fields has 2 bits
+ * to tell the firmware the image needs to be rotated before being
+ * displayed.
+ * If these bits are set then the firmwares-splash is not pre-rotated,
+ * in this case we must not rotate it when rendering and when doing
+ * comparisons with the panel-size we must use the post rotation
+ * panel-size.
+ */
+ if (bgrt_rotation != PLY_PIXEL_BUFFER_ROTATE_UPRIGHT) {
+ if (bgrt_rotation != panel_rotation) {
+ ply_trace ("bgrt orientation mismatch, bgrt_rot %d panel_rot %d", (int)bgrt_rotation, (int)panel_rotation);
+ return;
+ }
+
+ /* Set panel properties to their post-rotations values */
+ if (panel_rotation == PLY_PIXEL_BUFFER_ROTATE_CLOCKWISE ||
+ panel_rotation == PLY_PIXEL_BUFFER_ROTATE_COUNTER_CLOCKWISE) {
+ int temp = panel_width;
+ panel_width = panel_height;
+ panel_height = temp;
+ }
+ panel_rotation = PLY_PIXEL_BUFFER_ROTATE_UPRIGHT;
+ }
+
+ if (have_panel_props) {
+ ply_pixel_buffer_set_device_rotation (bgrt_buffer, panel_rotation);
+ ply_pixel_buffer_set_device_scale (bgrt_buffer, panel_scale);
+ }
+
+ width = ply_pixel_buffer_get_width (bgrt_buffer);
+ height = ply_pixel_buffer_get_height (bgrt_buffer);
+
+ x_offset = (screen_width - width) / 2;
+ y_offset = screen_height * 382 / 1000 - height / 2;
+
+ /*
+ * On laptops / tablets the LCD panel is typically brought up in
+ * its native resolution, so we can trust the x- and y-offset values
+ * provided by the firmware to be correct for a screen with the panels
+ * resolution.
+ *
+ * Moreover some laptop / tablet firmwares to do all kind of hacks wrt
+ * the y offset. This happens especially on devices where the panel is
+ * mounted 90 degrees rotated, but also on other devices.
+ *
+ * So on devices with an internal LCD panel, we prefer to use the
+ * firmware provided offsets, to make sure we match its quirky behavior.
+ *
+ * We check that the x-offset matches what we expect for the panel's
+ * native resolution to make sure that the values are indeed for the
+ * panel's native resolution and then we correct for any difference
+ * between the (external) screen's and the panel's resolution.
+ */
+ if (have_panel_props &&
+ (panel_width - view->plugin->background_bgrt_raw_width) / 2 == sysfs_x_offset) {
+ if (panel_rotation == PLY_PIXEL_BUFFER_ROTATE_CLOCKWISE ||
+ panel_rotation == PLY_PIXEL_BUFFER_ROTATE_COUNTER_CLOCKWISE) {
+ /*
+ * For left side up panels the y_offset is from the
+ * right side of the image once rotated upright (the
+ * top of the physicial LCD panel is on the right side).
+ * Our coordinates have the left side as 0, so we need
+ * to "flip" the y_offset in this case.
+ */
+ if (panel_rotation == PLY_PIXEL_BUFFER_ROTATE_COUNTER_CLOCKWISE)
+ sysfs_y_offset = panel_height - view->plugin->background_bgrt_raw_height - sysfs_y_offset;
+
+ /* 90 degrees rotated, swap x and y */
+ x_offset = sysfs_y_offset / panel_scale;
+ y_offset = sysfs_x_offset / panel_scale;
+
+ x_offset += (screen_width - panel_height / panel_scale) / 2;
+ y_offset += (screen_height - panel_width / panel_scale) * 382 / 1000;
+ } else {
+ /* Normal orientation */
+ x_offset = sysfs_x_offset / panel_scale;
+ y_offset = sysfs_y_offset / panel_scale;
+
+ x_offset += (screen_width - panel_width / panel_scale) / 2;
+ y_offset += (screen_height - panel_height / panel_scale) * 382 / 1000;
+ }
+ }
+
+ /*
+ * On desktops (no panel) we normally do not use the BGRT provided
+ * xoffset and yoffset because the resolution they are intended for
+ * may be differtent then the resolution of the current display.
+ *
+ * On some desktops (no panel) the image gets centered not only
+ * horizontally, but also vertically. In this case our default of using
+ * the golden ratio for the vertical position causes the BGRT image
+ * to jump. To avoid this we check here if the provided xoffset and
+ * yoffset perfectly center the image and in that case we use them.
+ */
+ if (!have_panel_props && screen_scale == 1 &&
+ (screen_width - width ) / 2 == sysfs_x_offset &&
+ (screen_height - height) / 2 == sysfs_y_offset) {
+ x_offset = sysfs_x_offset;
+ y_offset = sysfs_y_offset;
+ }
+
+ ply_trace ("using %dx%d bgrt image centered at %dx%d for %dx%d screen",
+ width, height, x_offset, y_offset, screen_width, screen_height);
+
+ view->background_buffer = ply_pixel_buffer_new (screen_width * screen_scale, screen_height * screen_scale);
+ ply_pixel_buffer_set_device_scale (view->background_buffer, screen_scale);
+ ply_pixel_buffer_fill_with_hex_color (view->background_buffer, NULL, 0x000000);
+ if (x_offset >= 0 && y_offset >= 0) {
+ bgrt_buffer = ply_pixel_buffer_rotate_upright (bgrt_buffer);
+ ply_pixel_buffer_fill_with_buffer (view->background_buffer, bgrt_buffer, x_offset, y_offset);
+ ply_pixel_buffer_free (bgrt_buffer);
+ }
+}
+
+static bool
+view_load (view_t *view)
+{
+ unsigned long x, y, width, title_height = 0, subtitle_height = 0;
+ unsigned long screen_width, screen_height, screen_scale;
+ char *image_dir, *image_path;
+ ply_boot_splash_plugin_t *plugin;
+ ply_pixel_buffer_t *buffer;
+
+ plugin = view->plugin;
+
+ screen_width = ply_pixel_display_get_width (view->display);
+ screen_height = ply_pixel_display_get_height (view->display);
+
+ buffer = ply_renderer_get_buffer_for_head(
+ ply_pixel_display_get_renderer (view->display),
+ ply_pixel_display_get_renderer_head (view->display));
+ screen_scale = ply_pixel_buffer_get_device_scale (buffer);
+
+ view_set_bgrt_background (view);
+
+ if (!view->background_buffer && plugin->background_tile_image != NULL) {
+ ply_trace ("tiling background to %lux%lu", screen_width, screen_height);
+
+ /* Create a buffer at screen scale so that we only do the slow interpolating scale once */
+ view->background_buffer = ply_pixel_buffer_new (screen_width * screen_scale, screen_height * screen_scale);
+ ply_pixel_buffer_set_device_scale (view->background_buffer, screen_scale);
+
+ if (plugin->background_start_color != plugin->background_end_color)
+ ply_pixel_buffer_fill_with_gradient (view->background_buffer, NULL,
+ plugin->background_start_color,
+ plugin->background_end_color);
+ else
+ ply_pixel_buffer_fill_with_hex_color (view->background_buffer, NULL,
+ plugin->background_start_color);
+
+ buffer = ply_pixel_buffer_tile (ply_image_get_buffer (plugin->background_tile_image), screen_width, screen_height);
+ ply_pixel_buffer_fill_with_buffer (view->background_buffer, buffer, 0, 0);
+ ply_pixel_buffer_free (buffer);
+ }
+
+ if (view->watermark_image == NULL && plugin->mode_settings[plugin->mode].watermark_imagename) {
+ image_path = detect_image(plugin->mode_settings[plugin->mode].watermark_imagename,
+ screen_width, screen_height);
+ ply_trace ("assing watermark %s", image_path);
+ view->watermark_image = ply_image_new (image_path);
+ free (image_path);
+ }
+ if (view->watermark_image != NULL) {
+ ply_trace ("loading watermark image");
+ if (!ply_image_load (view->watermark_image)) {
+ ply_image_free (view->watermark_image);
+ view->watermark_image = NULL;
+ }
+ }
+
+ if (view->watermark_image != NULL) {
+ view->watermark_area.width = ply_image_get_width (view->watermark_image);
+ view->watermark_area.height = ply_image_get_height (view->watermark_image);
+ view->watermark_area.x = screen_width * plugin->watermark_horizontal_alignment - ply_image_get_width (view->watermark_image) * plugin->watermark_horizontal_alignment;
+ view->watermark_area.y = screen_height * plugin->watermark_vertical_alignment - ply_image_get_height (view->watermark_image) * plugin->watermark_vertical_alignment;
+ ply_trace ("using %ldx%ld watermark centered at %ldx%ld for %ldx%ld screen",
+ view->watermark_area.width, view->watermark_area.height,
+ view->watermark_area.x, view->watermark_area.y,
+ screen_width, screen_height);
+ }
+
+ ply_trace ("loading entry");
+ if (!ply_entry_load (view->entry))
+ return false;
+
+ ply_keymap_icon_load (view->keymap_icon);
+ ply_capslock_icon_load (view->capslock_icon);
+
+ view_load_end_animation (view);
+
+ if (view->progress_animation != NULL) {
+ ply_trace ("loading progress animation");
+ if (!ply_progress_animation_load (view->progress_animation)) {
+ ply_trace ("optional progress animation wouldn't load");
+ ply_progress_animation_free (view->progress_animation);
+ view->progress_animation = NULL;
+ }
+ } else {
+ ply_trace ("this theme has no progress animation");
+ }
+
+ if (view->throbber != NULL) {
+ ply_trace ("loading throbber");
+ if (!ply_throbber_load (view->throbber)) {
+ ply_trace ("optional throbber was not loaded");
+ ply_throbber_free (view->throbber);
+ view->throbber = NULL;
+ }
+ } else {
+ ply_trace ("this theme has no throbber\n");
+ }
+
+ if (plugin->mode_settings[plugin->mode].title) {
+ ply_label_set_text (view->title_label,
+ _(plugin->mode_settings[plugin->mode].title));
+ title_height = ply_label_get_height (view->title_label);
+ } else {
+ ply_label_hide (view->title_label);
+ }
+
+ if (plugin->mode_settings[plugin->mode].subtitle) {
+ ply_label_set_text (view->subtitle_label,
+ _(plugin->mode_settings[plugin->mode].subtitle));
+ subtitle_height = ply_label_get_height (view->subtitle_label);
+ } else {
+ ply_label_hide (view->subtitle_label);
+ }
+
+ y = (screen_height - title_height - 2 * subtitle_height) * plugin->title_vertical_alignment;
+
+ view->title_area.width = 0;
+ view->title_area.height = 0;
+ view->title_area.x = -1;
+ view->title_area.y = 0;
+ if (plugin->mode_settings[plugin->mode].title) {
+ width = ply_label_get_width (view->title_label);
+ x = (screen_width - width) * plugin->title_horizontal_alignment;
+ ply_trace ("using %ldx%ld title centered at %ldx%ld for %ldx%ld screen",
+ width, title_height, x, y, screen_width, screen_height);
+ ply_label_show (view->title_label, view->display, x, y);
+ view->title_area.width = width;
+ view->title_area.height = 2 * title_height;
+ view->title_area.x = x;
+ view->title_area.y = y;
+
+ /* Use subtitle_height pixels seperation between title and subtitle */
+ y += title_height + subtitle_height;
+ }
+
+ if (plugin->mode_settings[plugin->mode].subtitle) {
+ width = ply_label_get_width (view->subtitle_label);
+ x = (screen_width - width) * plugin->title_horizontal_alignment;
+ ply_trace ("using %ldx%ld subtitle centered at %ldx%ld for %ldx%ld screen",
+ width, subtitle_height, x, y, screen_width, screen_height);
+ ply_label_show (view->subtitle_label, view->display, x, y);
+ if( x == -1 || x < view->title_area.x ) {
+ view->title_area.x = x;
+ }
+ if( width > view->title_area.width ) {
+ view->title_area.width = width;
+ }
+ if (view->title_area.height != 0) {
+ view->title_area.height = title_height + subtitle_height + subtitle_height * 2;
+ } else {
+ view->title_area.height = subtitle_height * 2;
+ }
+ }
+ uint32_t title_color = 0xff00ff;
+ title_color = plugin->mode_settings[plugin->mode].title_color;
+
+ if(view->title_label) {
+ ply_label_set_color(view->title_label,
+ ((title_color >> 16) & 0xff) / 255.0f,
+ ((title_color >> 8) & 0xff) / 255.0f,
+ (title_color & 0xff) / 255.0f,
+ 1.0f);
+ ply_label_set_color(view->subtitle_label,
+ ((title_color >> 16) & 0xff) / 255.0f,
+ ((title_color >> 8) & 0xff) / 255.0f,
+ (title_color & 0xff) / 255.0f,
+ 1.0f);
+ }
+
+ return true;
+}
+
+static bool
+load_views (ply_boot_splash_plugin_t *plugin)
+{
+ ply_list_node_t *node;
+ bool view_loaded;
+ view_t *view;
+
+ view_loaded = false;
+ node = ply_list_get_first_node (plugin->views);
+
+ while (node != NULL) {
+ view = ply_list_node_get_data (node);
+
+ if (view_load (view))
+ view_loaded = true;
+
+ node = ply_list_get_next_node (plugin->views, node);
+ }
+
+ return view_loaded;
+}
+
+static void
+view_redraw (view_t *view)
+{
+ unsigned long screen_width, screen_height;
+
+ screen_width = ply_pixel_display_get_width (view->display);
+ screen_height = ply_pixel_display_get_height (view->display);
+
+ ply_pixel_display_draw_area (view->display, 0, 0,
+ screen_width, screen_height);
+}
+
+static void
+redraw_views (ply_boot_splash_plugin_t *plugin)
+{
+ ply_list_node_t *node;
+ view_t *view;
+
+ node = ply_list_get_first_node (plugin->views);
+ while (node != NULL) {
+ view = ply_list_node_get_data (node);
+ view_redraw (view);
+ node = ply_list_get_next_node (plugin->views, node);
+ }
+}
+
+static void
+pause_views (ply_boot_splash_plugin_t *plugin)
+{
+ ply_list_node_t *node;
+ view_t *view;
+
+ ply_trace ("pausing views");
+
+ node = ply_list_get_first_node (plugin->views);
+ while (node != NULL) {
+ view = ply_list_node_get_data (node);
+ ply_pixel_display_pause_updates (view->display);
+ node = ply_list_get_next_node (plugin->views, node);
+ }
+}
+
+static void
+unpause_views (ply_boot_splash_plugin_t *plugin)
+{
+ ply_list_node_t *node;
+ view_t *view;
+
+ ply_trace ("unpausing views");
+
+ node = ply_list_get_first_node (plugin->views);
+ while (node != NULL) {
+ view = ply_list_node_get_data (node);
+ ply_pixel_display_unpause_updates (view->display);
+ node = ply_list_get_next_node (plugin->views, node);
+ }
+}
+
+static void
+view_start_end_animation (view_t *view,
+ ply_trigger_t *trigger)
+{
+ ply_boot_splash_plugin_t *plugin = view->plugin;
+ unsigned long screen_width, screen_height;
+ long x, y, width, height;
+
+ ply_progress_bar_hide (view->progress_bar);
+ if (view->progress_animation != NULL)
+ ply_progress_animation_hide (view->progress_animation);
+
+ screen_width = ply_pixel_display_get_width (view->display);
+ screen_height = ply_pixel_display_get_height (view->display);
+ width = ply_animation_get_width (view->end_animation);
+ height = ply_animation_get_height (view->end_animation);
+ x = plugin->mode_settings[plugin->mode].animation_horizontal_alignment * screen_width - width / 2.0;
+ y = calculate_animation_y(view,
+ plugin->mode_settings[plugin->mode].animation_vertical_alignment,
+ plugin->mode_settings[plugin->mode].animation_vertical_alignment_type,
+ screen_height, height);
+
+ ply_trace ("starting end sequence animation for %ldx%ld view", width, height);
+ ply_animation_start (view->end_animation,
+ view->display,
+ trigger, x, y);
+ view->animation_bottom = y + height;
+}
+
+static void
+on_view_throbber_stopped (view_t *view)
+{
+ view_start_end_animation (view, view->end_trigger);
+ view->end_trigger = NULL;
+}
+
+static void
+view_start_progress_animation (view_t *view)
+{
+ ply_boot_splash_plugin_t *plugin;
+
+ long x, y;
+ long width, height;
+ unsigned long screen_width, screen_height;
+
+ assert (view != NULL);
+
+ plugin = view->plugin;
+
+ plugin->is_idle = false;
+
+ screen_width = ply_pixel_display_get_width (view->display);
+ screen_height = ply_pixel_display_get_height (view->display);
+
+ ply_pixel_display_draw_area (view->display, 0, 0,
+ screen_width, screen_height);
+
+ if (plugin->mode_settings[plugin->mode].use_progress_bar) {
+ if (plugin->progress_bar_width != -1)
+ width = plugin->progress_bar_width;
+ else
+ width = screen_width;
+ height = plugin->progress_bar_height;
+ x = plugin->progress_bar_horizontal_alignment * (screen_width - width);
+ //y = plugin->progress_bar_vertical_alignment * (screen_height - height);
+ y = calculate_animation_y(view,
+ plugin->progress_bar_vertical_alignment,
+ plugin->mode_settings[plugin->mode].animation_vertical_alignment_type,
+ screen_height, height);
+ ply_progress_bar_show (view->progress_bar, view->display,
+ x, y, width, height);
+ ply_pixel_display_draw_area (view->display, x, y, width, height);
+ view->animation_bottom = y + height;
+ }
+
+ if (plugin->mode_settings[plugin->mode].use_animation &&
+ view->throbber != NULL) {
+ width = ply_throbber_get_width (view->throbber);
+ height = ply_throbber_get_height (view->throbber);
+ x = plugin->mode_settings[plugin->mode].animation_horizontal_alignment * screen_width - width / 2.0;
+
+ y = calculate_animation_y(view,
+ plugin->mode_settings[plugin->mode].animation_vertical_alignment,
+ plugin->mode_settings[plugin->mode].animation_vertical_alignment_type,
+ screen_height, height);
+ ply_throbber_start (view->throbber,
+ plugin->loop,
+ view->display, x, y);
+ ply_pixel_display_draw_area (view->display, x, y, width, height);
+ view->animation_bottom = y + height;
+ }
+
+ /* We don't really know how long shutdown will so
+ * don't show the progress animation
+ */
+ if (plugin->mode == PLY_BOOT_SPLASH_MODE_SHUTDOWN ||
+ plugin->mode == PLY_BOOT_SPLASH_MODE_REBOOT)
+ return;
+
+ if (plugin->mode_settings[plugin->mode].use_animation &&
+ view->progress_animation != NULL) {
+ width = ply_progress_animation_get_width (view->progress_animation);
+ height = ply_progress_animation_get_height (view->progress_animation);
+ x = plugin->mode_settings[plugin->mode].animation_horizontal_alignment * screen_width - width / 2.0;
+ y = calculate_animation_y(view,
+ plugin->mode_settings[plugin->mode].animation_vertical_alignment,
+ plugin->mode_settings[plugin->mode].animation_vertical_alignment_type,
+ screen_height, height);
+ ply_progress_animation_show (view->progress_animation,
+ view->display, x, y);
+
+ ply_pixel_display_draw_area (view->display, x, y, width, height);
+ view->animation_bottom = y + height;
+ }
+}
+
+static void
+view_show_prompt (view_t *view,
+ const char *prompt,
+ const char *entry_text,
+ int number_of_bullets)
+{
+ ply_boot_splash_plugin_t *plugin;
+ unsigned long screen_width, screen_height, entry_width, entry_height;
+ unsigned long keyboard_indicator_width, keyboard_indicator_height;
+ bool show_keyboard_indicators = false;
+ long dialog_bottom;
+ int x, y;
+
+ assert (view != NULL);
+
+ plugin = view->plugin;
+
+ screen_width = ply_pixel_display_get_width (view->display);
+ screen_height = ply_pixel_display_get_height (view->display);
+
+ if (ply_entry_is_hidden (view->entry)) {
+ view->lock_area.width = ply_image_get_width (plugin->lock_image);
+ view->lock_area.height = ply_image_get_height (plugin->lock_image);
+
+ entry_width = ply_entry_get_width (view->entry);
+ entry_height = ply_entry_get_height (view->entry);
+
+ if (plugin->box_image) {
+ view->box_area.width = ply_image_get_width (plugin->box_image);
+ view->box_area.height = ply_image_get_height (plugin->box_image);
+ view->box_area.x = (screen_width - view->box_area.width) * plugin->dialog_horizontal_alignment;
+ view->box_area.y = (screen_height - view->box_area.height) * plugin->dialog_vertical_alignment;
+ view->dialog_area = view->box_area;
+ } else {
+ view->dialog_area.width = view->lock_area.width + entry_width;
+ view->dialog_area.height = MAX(view->lock_area.height, entry_height);
+ view->dialog_area.x = (screen_width - view->dialog_area.width) * plugin->dialog_horizontal_alignment;
+ view->dialog_area.y = (screen_height - view->dialog_area.height) * plugin->dialog_vertical_alignment;
+ }
+
+ view->lock_area.x =
+ view->dialog_area.x +
+ (view->dialog_area.width -
+ (view->lock_area.width + entry_width)) / 2.0;
+ view->lock_area.y =
+ view->dialog_area.y +
+ (view->dialog_area.height - view->lock_area.height) / 2.0;
+
+ x = view->lock_area.x + view->lock_area.width;
+ y = view->dialog_area.y +
+ (view->dialog_area.height - entry_height) / 2.0;
+
+ ply_entry_show (view->entry, plugin->loop, view->display, x, y);
+
+ show_keyboard_indicators = true;
+ }
+
+ if (entry_text != NULL)
+ ply_entry_set_text (view->entry, entry_text);
+
+ if (number_of_bullets != -1)
+ ply_entry_set_bullet_count (view->entry, number_of_bullets);
+
+ dialog_bottom = view->dialog_area.y + view->dialog_area.height;
+
+ if (prompt != NULL) {
+ ply_label_set_text (view->label, prompt);
+
+ /* We center the prompt in the middle and use 80% of the horizontal space */
+ int label_width = screen_width * 100 / 80;
+ ply_label_set_alignment (view->label, PLY_LABEL_ALIGN_CENTER);
+ ply_label_set_width (view->label, label_width);
+
+ x = (screen_width - label_width) / 2;
+ y = dialog_bottom;
+
+ ply_label_show (view->label, view->display, x, y);
+
+ dialog_bottom += ply_label_get_height (view->label);
+ }
+
+ if (show_keyboard_indicators) {
+ keyboard_indicator_width =
+ ply_keymap_icon_get_width (view->keymap_icon);
+ keyboard_indicator_height = MAX(
+ ply_capslock_icon_get_height (view->capslock_icon),
+ ply_keymap_icon_get_height (view->keymap_icon));
+
+ x = (screen_width - keyboard_indicator_width) * plugin->dialog_horizontal_alignment;
+ y = dialog_bottom + keyboard_indicator_height / 2 +
+ (keyboard_indicator_height - ply_keymap_icon_get_height (view->keymap_icon)) / 2.0;
+ ply_keymap_icon_show (view->keymap_icon, x, y);
+
+ x += ply_keymap_icon_get_width (view->keymap_icon);
+ y = dialog_bottom + keyboard_indicator_height / 2 +
+ (keyboard_indicator_height - ply_capslock_icon_get_height (view->capslock_icon)) / 2.0;
+ ply_capslock_icon_show (view->capslock_icon, plugin->loop, view->display, x, y);
+ }
+}
+
+static void
+view_hide_prompt (view_t *view)
+{
+ assert (view != NULL);
+
+ ply_entry_hide (view->entry);
+ ply_capslock_icon_hide (view->capslock_icon);
+ ply_keymap_icon_hide (view->keymap_icon);
+ ply_label_hide (view->label);
+}
+
+static void
+load_mode_settings (ply_boot_splash_plugin_t *plugin,
+ ply_key_file_t *key_file,
+ const char *group_name,
+ ply_boot_splash_mode_t mode)
+{
+ mode_settings_t *settings = &plugin->mode_settings[mode];
+
+ settings->suppress_messages =
+ ply_key_file_get_bool (key_file, group_name, "SuppressMessages");
+ settings->progress_bar_show_percent_complete =
+ ply_key_file_get_bool (key_file, group_name, "ProgressBarShowPercentComplete");
+ settings->use_progress_bar =
+ ply_key_file_get_bool (key_file, group_name, "UseProgressBar");
+ settings->use_firmware_background =
+ ply_key_file_get_bool (key_file, group_name, "UseFirmwareBackground");
+
+ /* This defaults to !use_progress_bar for compat. with older themes */
+ if (ply_key_file_has_key (key_file, group_name, "UseAnimation"))
+ settings->use_animation =
+ ply_key_file_get_bool (key_file, group_name, "UseAnimation");
+ else
+ settings->use_animation = !settings->use_progress_bar;
+
+ /* This defaults to true for compat. with older themes */
+ if (ply_key_file_has_key (key_file, group_name, "UseEndAnimation"))
+ settings->use_end_animation =
+ ply_key_file_get_bool (key_file, group_name, "UseEndAnimation");
+ else
+ settings->use_end_animation = true;
+
+ /* If any mode uses the firmware background, then we need to load it */
+ if (settings->use_firmware_background)
+ plugin->use_firmware_background = true;
+
+ settings->watermark_imagename = ply_key_file_get_value (key_file, group_name, "WatermarkImage");
+ if( settings->watermark_imagename == NULL &&
+ plugin->watermark_imagename != NULL )
+ settings->watermark_imagename = strdup(plugin->watermark_imagename);
+
+ settings->title = ply_key_file_get_value (key_file, group_name, "Title");
+ settings->subtitle = ply_key_file_get_value (key_file, group_name, "SubTitle");
+
+ settings->title_color = ply_key_file_get_long (key_file, group_name, "TitleColor",
+ plugin->title_color);
+
+ settings->background_start_color =
+ ply_key_file_get_long (key_file, group_name,
+ "BackgroundStartColor",
+ plugin->background_start_color);
+ settings->background_end_color =
+ ply_key_file_get_long (key_file, group_name,
+ "BackgroundEndColor",
+ plugin->background_end_color);
+
+ /* Throbber, progress- and end-animation alignment */
+ settings->animation_horizontal_alignment =
+ ply_key_file_get_double (key_file, group_name,
+ "HorizontalAlignment", plugin->animation_horizontal_alignment);
+ settings->animation_vertical_alignment =
+ ply_key_file_get_double (key_file, group_name,
+ "VerticalAlignment", plugin->animation_vertical_alignment);
+ settings->animation_vertical_alignment_type =
+ ply_key_file_get_value (key_file, group_name,
+ "VerticalAlignmentType");
+ if( settings->animation_vertical_alignment_type == NULL &&
+ plugin->animation_vertical_alignment_type != NULL )
+ settings->animation_vertical_alignment_type = strdup(plugin->animation_vertical_alignment_type);
+}
+
+static ply_boot_splash_plugin_t *
+create_plugin (ply_key_file_t *key_file)
+{
+ ply_boot_splash_plugin_t *plugin;
+ char *image_dir, *image_path;
+ char *transition;
+ char *progress_function;
+
+ srand ((int) ply_get_timestamp ());
+ plugin = calloc (1, sizeof(ply_boot_splash_plugin_t));
+
+ image_dir = ply_key_file_get_value (key_file, "calculate", "ImageDir");
+
+ ply_trace ("Using '%s' as working directory", image_dir);
+
+ asprintf (&image_path, "%s/lock.png", image_dir);
+ plugin->lock_image = ply_image_new (image_path);
+ free (image_path);
+
+ asprintf (&image_path, "%s/box.png", image_dir);
+ plugin->box_image = ply_image_new (image_path);
+ free (image_path);
+
+ asprintf (&image_path, "%s/corner-image.png", image_dir);
+ plugin->corner_image = ply_image_new (image_path);
+ free (image_path);
+
+ asprintf (&image_path, "%s/header-image.png", image_dir);
+ 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);
+
+ plugin->animation_dir = image_dir;
+
+ plugin->font = ply_key_file_get_value (key_file, "calculate", "Font");
+ plugin->title_font = ply_key_file_get_value (key_file, "calculate", "TitleFont");
+
+ /* Throbber, progress- and end-animation alignment */
+ plugin->animation_horizontal_alignment =
+ ply_key_file_get_double (key_file, "calculate",
+ "HorizontalAlignment", 0.5);
+ plugin->animation_vertical_alignment =
+ ply_key_file_get_double (key_file, "calculate",
+ "VerticalAlignment", 0.5);
+ plugin->animation_vertical_alignment_type =
+ ply_key_file_get_value (key_file, "calculate",
+ "VerticalAlignmentType");
+
+ /* Progressbar alignment, this defaults to the animation alignment
+ * for compatibility with older themes.
+ */
+ plugin->progress_bar_horizontal_alignment =
+ ply_key_file_get_double (key_file, "calculate",
+ "ProgressBarHorizontalAlignment",
+ plugin->animation_horizontal_alignment);
+ plugin->progress_bar_vertical_alignment =
+ ply_key_file_get_double (key_file, "calculate",
+ "ProgressBarVerticalAlignment",
+ plugin->animation_vertical_alignment);
+
+ /* Watermark alignment */
+ plugin->watermark_horizontal_alignment =
+ ply_key_file_get_double (key_file, "calculate",
+ "WatermarkHorizontalAlignment", 1.0);
+ plugin->watermark_vertical_alignment =
+ ply_key_file_get_double (key_file, "calculate",
+ "WatermarkVerticalAlignment", 0.5);
+
+ /* Password (or other) dialog alignment */
+ plugin->dialog_horizontal_alignment =
+ ply_key_file_get_double (key_file, "calculate",
+ "DialogHorizontalAlignment", 0.5);
+ plugin->dialog_vertical_alignment =
+ ply_key_file_get_double (key_file, "calculate",
+ "DialogVerticalAlignment", 0.5);
+
+ /* Title alignment */
+ plugin->title_horizontal_alignment =
+ ply_key_file_get_double (key_file, "calculate",
+ "TitleHorizontalAlignment", 0.5);
+ plugin->title_vertical_alignment =
+ ply_key_file_get_double (key_file, "calculate",
+ "TitleVerticalAlignment", 0.5);
+
+ plugin->transition = PLY_PROGRESS_ANIMATION_TRANSITION_NONE;
+ transition = ply_key_file_get_value (key_file, "calculate", "Transition");
+ if (transition != NULL) {
+ if (strcmp (transition, "fade-over") == 0)
+ plugin->transition = PLY_PROGRESS_ANIMATION_TRANSITION_FADE_OVER;
+ else if (strcmp (transition, "cross-fade") == 0)
+ plugin->transition = PLY_PROGRESS_ANIMATION_TRANSITION_CROSS_FADE;
+ else if (strcmp (transition, "merge-fade") == 0)
+ plugin->transition = PLY_PROGRESS_ANIMATION_TRANSITION_MERGE_FADE;
+ }
+ free (transition);
+
+ plugin->transition_duration =
+ ply_key_file_get_double (key_file, "calculate",
+ "TransitionDuration", 0.0);
+
+ plugin->background_start_color =
+ ply_key_file_get_long (key_file, "calculate",
+ "BackgroundStartColor",
+ PLYMOUTH_BACKGROUND_START_COLOR);
+ plugin->background_end_color =
+ ply_key_file_get_long (key_file, "calculate",
+ "BackgroundEndColor",
+ PLYMOUTH_BACKGROUND_END_COLOR);
+ plugin->title_color = ply_key_file_get_long (
+ key_file, "calculate", "TitleColor", 0xffffff);
+
+ plugin->progress_bar_bg_color =
+ ply_key_file_get_long (key_file, "calculate",
+ "ProgressBarBackgroundColor",
+ 0xffffff /* white */);
+ plugin->progress_bar_fg_color =
+ ply_key_file_get_long (key_file, "calculate",
+ "ProgressBarForegroundColor",
+ 0x000000 /* black */);
+ plugin->progress_bar_width =
+ ply_key_file_get_long (key_file, "calculate",
+ "ProgressBarWidth",
+ PROGRESS_BAR_WIDTH);
+ plugin->progress_bar_height =
+ ply_key_file_get_long (key_file, "calculate",
+ "ProgressBarHeight",
+ PROGRESS_BAR_HEIGHT);
+
+ plugin->watermark_imagename = ply_key_file_get_value (key_file, "calculate", "WatermarkImage");
+
+ load_mode_settings (plugin, key_file, "boot-up", PLY_BOOT_SPLASH_MODE_BOOT_UP);
+ load_mode_settings (plugin, key_file, "shutdown", PLY_BOOT_SPLASH_MODE_SHUTDOWN);
+ load_mode_settings (plugin, key_file, "reboot", PLY_BOOT_SPLASH_MODE_REBOOT);
+ load_mode_settings (plugin, key_file, "updates", PLY_BOOT_SPLASH_MODE_UPDATES);
+ load_mode_settings (plugin, key_file, "system-upgrade", PLY_BOOT_SPLASH_MODE_SYSTEM_UPGRADE);
+ load_mode_settings (plugin, key_file, "firmware-upgrade", PLY_BOOT_SPLASH_MODE_FIRMWARE_UPGRADE);
+
+ if (plugin->use_firmware_background)
+ plugin->background_bgrt_image = ply_image_new ("/sys/firmware/acpi/bgrt/image");
+
+ plugin->dialog_clears_firmware_background =
+ ply_key_file_get_bool (key_file, "calculate", "DialogClearsFirmwareBackground");
+
+ plugin->message_below_animation =
+ ply_key_file_get_bool (key_file, "calculate", "MessageBelowAnimation");
+
+ progress_function = ply_key_file_get_value (key_file, "calculate", "ProgressFunction");
+
+ if (progress_function != NULL) {
+ if (strcmp (progress_function, "wwoods") == 0) {
+ ply_trace ("Using wwoods progress function");
+ plugin->progress_function = PROGRESS_FUNCTION_TYPE_WWOODS;
+ } else if (strcmp (progress_function, "linear") == 0) {
+ ply_trace ("Using linear progress function");
+ plugin->progress_function = PROGRESS_FUNCTION_TYPE_LINEAR;
+ } else {
+ ply_trace ("unknown progress function %s, defaulting to linear", progress_function);
+ plugin->progress_function = PROGRESS_FUNCTION_TYPE_LINEAR;
+ }
+
+ free (progress_function);
+ }
+
+ plugin->views = ply_list_new ();
+
+ return plugin;
+}
+
+static void
+free_views (ply_boot_splash_plugin_t *plugin)
+{
+ ply_list_node_t *node;
+
+ ply_trace ("freeing views");
+
+ 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)
+{
+ int i;
+
+ if (plugin == NULL)
+ return;
+
+ ply_trace ("destroying plugin");
+
+ 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);
+ }
+
+ ply_image_free (plugin->lock_image);
+
+ if (plugin->box_image != NULL)
+ ply_image_free (plugin->box_image);
+
+ if (plugin->corner_image != NULL)
+ ply_image_free (plugin->corner_image);
+
+ 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->background_bgrt_image != NULL)
+ ply_image_free (plugin->background_bgrt_image);
+
+ for (i = 0; i < PLY_BOOT_SPLASH_MODE_COUNT; i++) {
+ free (plugin->mode_settings[i].title);
+ free (plugin->mode_settings[i].watermark_imagename);
+ free (plugin->mode_settings[i].subtitle);
+ free (plugin->mode_settings[i].animation_vertical_alignment_type);
+ }
+
+ free (plugin->font);
+ free (plugin->title_font);
+ free (plugin->animation_vertical_alignment_type);
+ free (plugin->animation_dir);
+ free (plugin->watermark_imagename);
+ free_views (plugin);
+ free (plugin);
+}
+
+static void
+start_end_animation (ply_boot_splash_plugin_t *plugin,
+ ply_trigger_t *trigger)
+{
+ ply_list_node_t *node;
+ view_t *view;
+
+ if (!plugin->mode_settings[plugin->mode].use_animation) {
+ ply_trigger_pull (trigger, NULL);
+ return;
+ }
+
+ if (!plugin->mode_settings[plugin->mode].use_end_animation) {
+ node = ply_list_get_first_node (plugin->views);
+ while (node != NULL) {
+ view = ply_list_node_get_data (node);
+
+ ply_progress_bar_hide (view->progress_bar);
+
+ if (view->throbber != NULL)
+ ply_throbber_stop (view->throbber, NULL);
+
+ if (view->progress_animation != NULL)
+ ply_progress_animation_hide (view->progress_animation);
+
+ node = ply_list_get_next_node (plugin->views, node);
+ }
+ ply_trigger_pull (trigger, NULL);
+ return;
+ }
+
+ ply_trace ("starting end animation");
+
+ node = ply_list_get_first_node (plugin->views);
+ while (node != NULL) {
+ view = ply_list_node_get_data (node);
+
+ ply_trigger_ignore_next_pull (trigger);
+
+ if (view->throbber != NULL) {
+ ply_trigger_t *throbber_trigger;
+ ply_trace ("stopping throbber");
+ view->end_trigger = trigger;
+ throbber_trigger = ply_trigger_new (NULL);
+ ply_trigger_add_handler (throbber_trigger,
+ (ply_trigger_handler_t)
+ on_view_throbber_stopped,
+ view);
+ ply_throbber_stop (view->throbber, throbber_trigger);
+ } else {
+ view_start_end_animation (view, trigger);
+ }
+
+ node = ply_list_get_next_node (plugin->views, node);
+ }
+ ply_trigger_pull (trigger, NULL);
+}
+
+static void
+start_progress_animation (ply_boot_splash_plugin_t *plugin)
+{
+ ply_list_node_t *node;
+ view_t *view;
+
+ if (plugin->is_animating)
+ return;
+
+ ply_trace ("starting animation");
+
+ node = ply_list_get_first_node (plugin->views);
+ while (node != NULL) {
+ view = ply_list_node_get_data (node);
+ view_start_progress_animation (view);
+ node = ply_list_get_next_node (plugin->views, node);
+ }
+
+ plugin->is_animating = true;
+
+ /* We don't really know how long shutdown will, take
+ * but it's normally really fast, so just jump to
+ * the end animation
+ */
+ if (plugin->mode_settings[plugin->mode].use_end_animation &&
+ (plugin->mode == PLY_BOOT_SPLASH_MODE_SHUTDOWN ||
+ plugin->mode == PLY_BOOT_SPLASH_MODE_REBOOT))
+ become_idle (plugin, NULL);
+}
+
+static void
+stop_animation (ply_boot_splash_plugin_t *plugin)
+{
+ ply_list_node_t *node;
+ view_t *view;
+
+ assert (plugin != NULL);
+ assert (plugin->loop != NULL);
+
+ if (!plugin->is_animating)
+ return;
+
+ ply_trace ("stopping animation");
+ plugin->is_animating = false;
+
+ node = ply_list_get_first_node (plugin->views);
+ while (node != NULL) {
+ view = ply_list_node_get_data (node);
+
+ ply_progress_bar_hide (view->progress_bar);
+ if (view->progress_animation != NULL)
+ ply_progress_animation_hide (view->progress_animation);
+ if (view->throbber != NULL)
+ ply_throbber_stop (view->throbber, NULL);
+ if (view->end_animation != NULL)
+ ply_animation_stop (view->end_animation);
+
+ node = ply_list_get_next_node (plugin->views, node);
+ }
+}
+
+static void
+detach_from_event_loop (ply_boot_splash_plugin_t *plugin)
+{
+ plugin->loop = NULL;
+}
+
+static void
+draw_background (view_t *view,
+ ply_pixel_buffer_t *pixel_buffer,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ ply_boot_splash_plugin_t *plugin;
+ ply_rectangle_t area;
+ bool use_black_background = false;
+
+ plugin = view->plugin;
+
+ area.x = x;
+ area.y = y;
+ area.width = width;
+ area.height = height;
+
+ /* When using the firmware logo as background and we should not use
+ * it for this mode, use solid black as background.
+ */
+ if (plugin->background_bgrt_image &&
+ !plugin->mode_settings[plugin->mode].use_firmware_background)
+ use_black_background = true;
+
+ /* When using the firmware logo as background, use solid black as
+ * background for dialogs.
+ */
+ if ((plugin->state == PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY ||
+ plugin->state == PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY) &&
+ plugin->background_bgrt_image && plugin->dialog_clears_firmware_background)
+ use_black_background = true;
+
+ if (use_black_background)
+ ply_pixel_buffer_fill_with_hex_color (pixel_buffer, &area, 0);
+ else if (view->background_buffer != NULL)
+ ply_pixel_buffer_fill_with_buffer (pixel_buffer, view->background_buffer, 0, 0);
+ else if (plugin->mode_settings[plugin->mode].background_start_color != plugin->mode_settings[plugin->mode].background_end_color)
+ ply_pixel_buffer_fill_with_gradient (pixel_buffer, &area,
+ plugin->mode_settings[plugin->mode].background_start_color,
+ plugin->mode_settings[plugin->mode].background_end_color);
+ else
+ ply_pixel_buffer_fill_with_hex_color (pixel_buffer, &area,
+ plugin->mode_settings[plugin->mode].background_start_color);
+
+ if (view->watermark_image != NULL) {
+ uint32_t *data;
+
+ data = ply_image_get_data (view->watermark_image);
+ ply_pixel_buffer_fill_with_argb32_data (pixel_buffer, &view->watermark_area, data);
+ }
+}
+
+static void
+on_draw (view_t *view,
+ ply_pixel_buffer_t *pixel_buffer,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ ply_boot_splash_plugin_t *plugin;
+ ply_rectangle_t screen_area;
+ ply_rectangle_t image_area;
+
+ plugin = view->plugin;
+
+ draw_background (view, pixel_buffer, x, y, width, height);
+
+ ply_pixel_buffer_get_size (pixel_buffer, &screen_area);
+
+ if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY ||
+ plugin->state == PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY) {
+ uint32_t *box_data, *lock_data;
+
+ if (plugin->box_image) {
+ box_data = ply_image_get_data (plugin->box_image);
+ ply_pixel_buffer_fill_with_argb32_data (pixel_buffer,
+ &view->box_area,
+ box_data);
+ }
+
+ ply_entry_draw_area (view->entry,
+ pixel_buffer,
+ x, y, width, height);
+ ply_keymap_icon_draw_area (view->keymap_icon,
+ pixel_buffer,
+ x, y, width, height);
+ ply_capslock_icon_draw_area (view->capslock_icon,
+ pixel_buffer,
+ x, y, width, height);
+ ply_label_draw_area (view->label,
+ pixel_buffer,
+ x, y, width, height);
+
+ lock_data = ply_image_get_data (plugin->lock_image);
+ ply_pixel_buffer_fill_with_argb32_data (pixel_buffer,
+ &view->lock_area,
+ lock_data);
+ } else {
+ if (plugin->mode_settings[plugin->mode].use_progress_bar)
+ ply_progress_bar_draw_area (view->progress_bar, pixel_buffer,
+ x, y, width, height);
+
+ if (plugin->mode_settings[plugin->mode].use_animation &&
+ view->throbber != NULL)
+ ply_throbber_draw_area (view->throbber, pixel_buffer,
+ x, y, width, height);
+
+ if (plugin->mode_settings[plugin->mode].use_animation &&
+ view->progress_animation != NULL)
+ ply_progress_animation_draw_area (view->progress_animation,
+ pixel_buffer,
+ x, y, width, height);
+
+ if (plugin->mode_settings[plugin->mode].use_animation &&
+ view->end_animation != NULL)
+ ply_animation_draw_area (view->end_animation,
+ pixel_buffer,
+ x, y, width, height);
+
+ if (plugin->corner_image != NULL) {
+ image_area.width = ply_image_get_width (plugin->corner_image);
+ image_area.height = ply_image_get_height (plugin->corner_image);
+ image_area.x = screen_area.width - image_area.width - 20;
+ image_area.y = screen_area.height - image_area.height - 20;
+
+ ply_pixel_buffer_fill_with_argb32_data (pixel_buffer, &image_area, ply_image_get_data (plugin->corner_image));
+ }
+
+ if (plugin->header_image != NULL) {
+ long sprite_height;
+
+
+ if (view->progress_animation != NULL)
+ sprite_height = ply_progress_animation_get_height (view->progress_animation);
+ else
+ sprite_height = 0;
+
+ if (view->throbber != NULL)
+ sprite_height = MAX (ply_throbber_get_height (view->throbber),
+ sprite_height);
+
+ image_area.width = ply_image_get_width (plugin->header_image);
+ image_area.height = ply_image_get_height (plugin->header_image);
+ image_area.x = screen_area.width / 2.0 - image_area.width / 2.0;
+ image_area.y = plugin->mode_settings[plugin->mode].animation_vertical_alignment * screen_area.height - sprite_height / 2.0 - image_area.height;
+
+
+ ply_pixel_buffer_fill_with_argb32_data (pixel_buffer, &image_area, ply_image_get_data (plugin->header_image));
+ }
+ ply_label_draw_area (view->title_label,
+ pixel_buffer,
+ x, y, width, height);
+ ply_label_draw_area (view->subtitle_label,
+ pixel_buffer,
+ x, y, width, height);
+ }
+ ply_label_draw_area (view->message_label,
+ pixel_buffer,
+ x, y, width, height);
+}
+
+static void
+add_pixel_display (ply_boot_splash_plugin_t *plugin,
+ ply_pixel_display_t *display)
+{
+ view_t *view;
+
+ ply_trace ("adding pixel display to plugin");
+ view = view_new (plugin, display);
+
+ ply_pixel_display_set_draw_handler (view->display,
+ (ply_pixel_display_draw_handler_t)
+ on_draw, view);
+ if (plugin->is_visible) {
+ if (view_load (view)) {
+ ply_list_append_data (plugin->views, view);
+ if (plugin->is_animating)
+ view_start_progress_animation (view);
+ } else {
+ view_free (view);
+ }
+ } else {
+ ply_list_append_data (plugin->views, view);
+ }
+}
+
+static void
+remove_pixel_display (ply_boot_splash_plugin_t *plugin,
+ ply_pixel_display_t *display)
+{
+ ply_list_node_t *node;
+
+ ply_trace ("removing pixel display from plugin");
+ node = ply_list_get_first_node (plugin->views);
+ while (node != NULL) {
+ view_t *view;
+ ply_list_node_t *next_node;
+
+ view = ply_list_node_get_data (node);
+ next_node = ply_list_get_next_node (plugin->views, node);
+
+ if (view->display == display) {
+ ply_pixel_display_set_draw_handler (view->display, NULL, NULL);
+ view_free (view);
+ ply_list_remove_node (plugin->views, node);
+ return;
+ }
+
+ node = next_node;
+ }
+}
+
+static bool
+show_splash_screen (ply_boot_splash_plugin_t *plugin,
+ ply_event_loop_t *loop,
+ ply_buffer_t *boot_buffer,
+ ply_boot_splash_mode_t mode)
+{
+ int i;
+
+ assert (plugin != NULL);
+
+ plugin->loop = loop;
+ plugin->mode = mode;
+
+ ply_trace ("loading lock image");
+ if (!ply_image_load (plugin->lock_image))
+ return false;
+
+ if (plugin->box_image != NULL) {
+ ply_trace ("loading box image");
+
+ if (!ply_image_load (plugin->box_image)) {
+ ply_image_free (plugin->box_image);
+ plugin->box_image = NULL;
+ }
+ }
+
+ if (plugin->corner_image != NULL) {
+ ply_trace ("loading corner image");
+
+ if (!ply_image_load (plugin->corner_image)) {
+ ply_image_free (plugin->corner_image);
+ plugin->corner_image = NULL;
+ }
+ }
+
+ if (plugin->header_image != NULL) {
+ ply_trace ("loading header image");
+
+ if (!ply_image_load (plugin->header_image)) {
+ ply_image_free (plugin->header_image);
+ plugin->header_image = NULL;
+ }
+ }
+
+ 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->background_bgrt_image != NULL) {
+ ply_trace ("loading background bgrt image");
+ if (ply_image_load (plugin->background_bgrt_image)) {
+ plugin->background_bgrt_raw_width = ply_image_get_width (plugin->background_bgrt_image);
+ plugin->background_bgrt_raw_height = ply_image_get_height (plugin->background_bgrt_image);
+ } else {
+ ply_image_free (plugin->background_bgrt_image);
+ plugin->background_bgrt_image = NULL;
+ for (i = 0; i < PLY_BOOT_SPLASH_MODE_COUNT; i++)
+ plugin->mode_settings[i].use_firmware_background = false;
+ plugin->use_firmware_background = false;
+ }
+ }
+
+ if (!load_views (plugin)) {
+ ply_trace ("couldn't load views");
+ return false;
+ }
+
+ ply_event_loop_watch_for_exit (loop, (ply_event_loop_exit_handler_t)
+ detach_from_event_loop,
+ plugin);
+
+ ply_trace ("starting boot animations");
+ start_progress_animation (plugin);
+
+ plugin->is_visible = true;
+
+ return true;
+}
+
+static void
+update_status (ply_boot_splash_plugin_t *plugin,
+ const char *status)
+{
+ assert (plugin != NULL);
+}
+
+static void
+on_animation_stopped (ply_boot_splash_plugin_t *plugin)
+{
+ if (plugin->idle_trigger != NULL) {
+ ply_trigger_pull (plugin->idle_trigger, NULL);
+ plugin->idle_trigger = NULL;
+ }
+ plugin->is_idle = true;
+}
+
+static void
+update_progress_animation (ply_boot_splash_plugin_t *plugin,
+ double fraction_done)
+{
+ ply_list_node_t *node;
+ view_t *view;
+ char buf[64];
+
+ node = ply_list_get_first_node (plugin->views);
+ while (node != NULL) {
+ view = ply_list_node_get_data (node);
+
+ if (view->progress_animation != NULL)
+ ply_progress_animation_set_fraction_done (view->progress_animation,
+ fraction_done);
+
+ ply_progress_bar_set_fraction_done (view->progress_bar, fraction_done);
+ if (!ply_progress_bar_is_hidden (view->progress_bar) &&
+ plugin->mode_settings[plugin->mode].progress_bar_show_percent_complete) {
+ snprintf (buf, sizeof(buf), _("%d%% complete"), (int)(fraction_done * 100));
+ view_show_message (view, buf);
+ }
+
+ node = ply_list_get_next_node (plugin->views, node);
+ }
+}
+
+static void
+on_boot_progress (ply_boot_splash_plugin_t *plugin,
+ double duration,
+ double fraction_done)
+{
+ if (plugin->mode == PLY_BOOT_SPLASH_MODE_UPDATES ||
+ plugin->mode == PLY_BOOT_SPLASH_MODE_SYSTEM_UPGRADE ||
+ plugin->mode == PLY_BOOT_SPLASH_MODE_FIRMWARE_UPGRADE)
+ return;
+
+ if (plugin->state != PLY_BOOT_SPLASH_DISPLAY_NORMAL)
+ return;
+
+ if (plugin->is_idle)
+ return;
+
+ /*
+ * If we do not have an end animation, we keep showing progress until
+ * become_idle gets called.
+ */
+ if (plugin->mode_settings[plugin->mode].use_end_animation &&
+ fraction_done >= SHOW_ANIMATION_FRACTION) {
+ if (plugin->stop_trigger == NULL) {
+ ply_trace ("boot progressed to end");
+
+ plugin->stop_trigger = ply_trigger_new (&plugin->stop_trigger);
+ ply_trigger_add_handler (plugin->stop_trigger,
+ (ply_trigger_handler_t)
+ on_animation_stopped,
+ plugin);
+ start_end_animation (plugin, plugin->stop_trigger);
+ }
+ } else {
+ double total_duration;
+
+ fraction_done *= (1 / SHOW_ANIMATION_FRACTION);
+
+ switch (plugin->progress_function) {
+ /* Fun made-up smoothing function to make the growth asymptotic:
+ * fraction(time,estimate)=1-2^(-(time^1.45)/estimate) */
+ case PROGRESS_FUNCTION_TYPE_WWOODS:
+ total_duration = duration / fraction_done;
+ fraction_done = 1.0 - pow (2.0, -pow (duration, 1.45) / total_duration) * (1.0 - fraction_done);
+ break;
+
+ case PROGRESS_FUNCTION_TYPE_LINEAR:
+ break;
+ }
+
+ update_progress_animation (plugin, fraction_done);
+ }
+}
+
+static void
+hide_splash_screen (ply_boot_splash_plugin_t *plugin,
+ ply_event_loop_t *loop)
+{
+ assert (plugin != NULL);
+
+ ply_trace ("hiding splash");
+ 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);
+ }
+
+ plugin->is_visible = false;
+}
+
+static void
+show_prompt (ply_boot_splash_plugin_t *plugin,
+ const char *prompt,
+ const char *entry_text,
+ int number_of_bullets)
+{
+ ply_list_node_t *node;
+ view_t *view;
+
+ ply_trace ("showing prompt");
+ node = ply_list_get_first_node (plugin->views);
+ while (node != NULL) {
+ view = ply_list_node_get_data (node);
+ view_show_prompt (view, prompt, entry_text, number_of_bullets);
+ node = ply_list_get_next_node (plugin->views, node);
+ }
+}
+
+static void
+on_root_mounted (ply_boot_splash_plugin_t *plugin)
+{
+ ply_trace ("root filesystem mounted");
+ plugin->root_is_mounted = true;
+}
+
+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;
+ }
+
+ plugin->idle_trigger = idle_trigger;
+
+ if (plugin->stop_trigger == NULL) {
+ ply_trace ("waiting for plugin to stop");
+ plugin->stop_trigger = ply_trigger_new (&plugin->stop_trigger);
+ ply_trigger_add_handler (plugin->stop_trigger,
+ (ply_trigger_handler_t)
+ on_animation_stopped,
+ plugin);
+ start_end_animation (plugin, plugin->stop_trigger);
+ } else {
+ ply_trace ("already waiting for plugin to stop");
+ }
+}
+
+static void
+hide_prompt (ply_boot_splash_plugin_t *plugin)
+{
+ ply_list_node_t *node;
+ view_t *view;
+
+ ply_trace ("hiding prompt");
+ node = ply_list_get_first_node (plugin->views);
+ while (node != NULL) {
+ view = ply_list_node_get_data (node);
+ view_hide_prompt (view);
+ node = ply_list_get_next_node (plugin->views, node);
+ }
+}
+
+static void
+view_show_message (view_t *view,
+ const char *message)
+{
+ ply_boot_splash_plugin_t *plugin = view->plugin;
+ int x, y, width, height;
+
+ if (plugin->message_below_animation)
+ ply_label_set_alignment (view->message_label, PLY_LABEL_ALIGN_CENTER);
+
+ ply_label_set_text (view->message_label, message);
+ width = ply_label_get_width (view->message_label);
+ height = ply_label_get_height (view->message_label);
+
+ if (plugin->message_below_animation) {
+ x = (ply_pixel_display_get_width (view->display) - width) * 0.5;
+ y = view->animation_bottom + 10;
+ } else {
+ x = 10;
+ y = 10;
+ }
+
+ ply_label_show (view->message_label, view->display, x, y);
+ ply_pixel_display_draw_area (view->display, x, y, width, height);
+}
+
+static void
+show_message (ply_boot_splash_plugin_t *plugin,
+ const char *message)
+{
+ ply_list_node_t *node;
+ view_t *view;
+
+ if (plugin->mode_settings[plugin->mode].suppress_messages) {
+ ply_trace ("Suppressing message '%s'", message);
+ return;
+ }
+ ply_trace ("Showing message '%s'", message);
+ node = ply_list_get_first_node (plugin->views);
+ while (node != NULL) {
+ view = ply_list_node_get_data (node);
+ view_show_message (view, message);
+ node = ply_list_get_next_node (plugin->views, node);
+ }
+}
+
+static void
+system_update (ply_boot_splash_plugin_t *plugin,
+ int progress)
+{
+ if (plugin->mode != PLY_BOOT_SPLASH_MODE_UPDATES &&
+ plugin->mode != PLY_BOOT_SPLASH_MODE_SYSTEM_UPGRADE &&
+ plugin->mode != PLY_BOOT_SPLASH_MODE_FIRMWARE_UPGRADE)
+ return;
+
+ update_progress_animation (plugin, progress / 100.0);
+}
+
+static void
+display_normal (ply_boot_splash_plugin_t *plugin)
+{
+ pause_views (plugin);
+ if (plugin->state != PLY_BOOT_SPLASH_DISPLAY_NORMAL)
+ hide_prompt (plugin);
+
+ plugin->state = PLY_BOOT_SPLASH_DISPLAY_NORMAL;
+ start_progress_animation (plugin);
+ redraw_views (plugin);
+ unpause_views (plugin);
+}
+
+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;
+ show_prompt (plugin, prompt, NULL, bullets);
+ redraw_views (plugin);
+ 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_QUESTION_ENTRY;
+ show_prompt (plugin, prompt, entry_text, -1);
+ redraw_views (plugin);
+ unpause_views (plugin);
+}
+
+static void
+display_message (ply_boot_splash_plugin_t *plugin,
+ const char *message)
+{
+ show_message (plugin, message);
+}
+
+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_pixel_display = add_pixel_display,
+ .remove_pixel_display = remove_pixel_display,
+ .show_splash_screen = show_splash_screen,
+ .update_status = update_status,
+ .on_boot_progress = on_boot_progress,
+ .hide_splash_screen = hide_splash_screen,
+ .on_root_mounted = on_root_mounted,
+ .become_idle = become_idle,
+ .display_normal = display_normal,
+ .display_password = display_password,
+ .display_question = display_question,
+ .display_message = display_message,
+ .system_update = system_update,
+ };
+
+ return &plugin_interface;
+}
+
+/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */
diff --git a/sys-boot/plymouth-calculate-plugin/plymouth-calculate-plugin-0.9.5.ebuild b/sys-boot/plymouth-calculate-plugin/plymouth-calculate-plugin-0.9.5.ebuild
new file mode 100644
index 000000000..5ac8a4c87
--- /dev/null
+++ b/sys-boot/plymouth-calculate-plugin/plymouth-calculate-plugin-0.9.5.ebuild
@@ -0,0 +1,98 @@
+# Copyright 1999-2018 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit flag-o-matic
+
+MY_P=plymouth-${PV}
+
+if [[ ${PV} == 9999 ]]; then
+ inherit git-r3
+ EGIT_REPO_URI="https://anongit.freedesktop.org/git/plymouth"
+else
+ SRC_URI="${SRC_URI} https://www.freedesktop.org/software/plymouth/releases/${MY_P}.tar.xz"
+ KEYWORDS="~alpha amd64 ~arm ~ia64 ~ppc ~ppc64 ~sparc x86"
+fi
+
+inherit autotools readme.gentoo-r1 systemd toolchain-funcs
+
+DESCRIPTION="Calculate plugin for plymouth"
+HOMEPAGE="https://www.calculate-linux.org"
+
+LICENSE="GPL-2"
+SLOT="0"
+IUSE="debug gdm +gtk +libkms +pango +split-usr static-libs +udev"
+
+CDEPEND="
+ ~sys-boot/${MY_P}[debug?,udev?,gtk?,libkms?,pango?,split-usr?,static-libs?]
+"
+DEPEND="${CDEPEND}
+ app-text/docbook-xsl-stylesheets
+ dev-libs/libxslt
+ virtual/pkgconfig
+"
+RDEPEND="${CDEPEND}
+ virtual/udev
+ !=net-libs/nodejs-10[npm] )"
-COMMON_DEPEND="
- acct? (
- acct-group/git
- acct-user/git[gitea] )
- pam? ( sys-libs/pam )"
-DEPEND="${COMMON_DEPEND}"
-RDEPEND="${COMMON_DEPEND}
- dev-vcs/git"
-
-DOCS=(
- custom/conf/app.ini.sample CONTRIBUTING.md README.md
-)
-FILECAPS=(
- cap_net_bind_service+ep usr/bin/gitea
-)
-PATCHES=(
- "${FILESDIR}/1.12-fix-vendoring.patch"
-)
-
-src_prepare() {
- default
-
- local sedcmds=(
- -e "s#^RUN_MODE = dev#RUN_MODE = prod#"
- -e "s#^ROOT =#ROOT = ${EPREFIX}/var/lib/gitea/gitea-repositories#"
- -e "s#^ROOT_PATH =#ROOT_PATH = ${EPREFIX}/var/log/gitea#"
- -e "s#^APP_DATA_PATH = data#APP_DATA_PATH = ${EPREFIX}/var/lib/gitea/data#"
- -e "s#^HTTP_ADDR = 0.0.0.0#HTTP_ADDR = 127.0.0.1#"
- -e "s#^MODE = console#MODE = file#"
- -e "s#^LEVEL = Trace#LEVEL = Info#"
- -e "s#^LOG_SQL = true#LOG_SQL = false#"
- -e "s#^DISABLE_ROUTER_LOG = false#DISABLE_ROUTER_LOG = true#"
- -e "s#^APP_ID =#;APP_ID =#"
- -e "s#^TRUSTED_FACETS =#;TRUSTED_FACETS =#"
- )
-
- sed -i "${sedcmds[@]}" custom/conf/app.ini.sample || die
- if use sqlite ; then
- sed -i -e "s#^DB_TYPE = .*#DB_TYPE = sqlite3#" custom/conf/app.ini.sample || die
- fi
-
- einfo "Remove tests which are known to fail with network-sandbox enabled."
- rm ./modules/migrations/github_test.go || die
-
- einfo "Remove tests which depend on gitea git-repo."
- rm ./modules/git/blob_test.go || die
- rm ./modules/git/repo_test.go || die
-
- # Remove already build assets (like frontend part)
- use build-client && emake clean-all
-}
-
-src_compile() {
- local gitea_tags=(
- bindata
- $(usev pam)
- $(usex sqlite 'sqlite sqlite_unlock_notify' '')
- )
- local gitea_settings=(
- "-X code.gitea.io/gitea/modules/setting.CustomConf=${EPREFIX}/etc/gitea/app.ini"
- "-X code.gitea.io/gitea/modules/setting.CustomPath=${EPREFIX}/var/lib/gitea/custom"
- "-X code.gitea.io/gitea/modules/setting.AppWorkPath=${EPREFIX}/var/lib/gitea"
- )
- local makeenv=(
- TAGS="${gitea_tags[@]}"
- LDFLAGS="-extldflags \"${LDFLAGS}\" ${gitea_settings[@]}"
- )
- [[ ${PV} != 9999* ]] && makeenv+=("DRONE_TAG=${MY_PV}")
-
- if use build-client; then
- # -j1 as Makefile doesn't handle dependancy correctly, and is not
- # useful as golang compiler don't use this info.
- env "${makeenv[@]}" emake -j1 build
- else
- env "${makeenv[@]}" emake backend
- fi
-}
-
-src_install() {
- dobin gitea
-
- einstalldocs
-
- newconfd "${FILESDIR}/gitea.confd-r1" gitea
- newinitd "${FILESDIR}/gitea.initd-r3" gitea
- newtmpfiles - gitea.conf <<-EOF
- d /run/gitea 0755 git git
- EOF
- systemd_newunit "${FILESDIR}"/gitea.service-r2 gitea.service
-
- insinto /etc/gitea
- newins custom/conf/app.ini.sample app.ini
- if use acct ; then
- fowners root:git /etc/gitea/{,app.ini}
- fperms g+w,o-rwx /etc/gitea/{,app.ini}
-
- diropts -m0750 -o git -g git
- keepdir /var/lib/gitea /var/lib/gitea/custom /var/lib/gitea/data
- keepdir /var/log/gitea
- fi
-}
diff --git a/www-apps/gitea/metadata.xml b/www-apps/gitea/metadata.xml
deleted file mode 100644
index 666bf0ff6..000000000
--- a/www-apps/gitea/metadata.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
- nemunaire@nemunai.re
- Pierre-Olivier Mercier
-
-
- proxy-maint@gentoo.org
- Proxy Maintainers
-
-
- go-gitea/gitea
-
-
-