Hans de Goede [Wed, 2 Jul 2025 07:31:21 +0000 (09:31 +0200)]
Fix keymap and capslock icon on displays on second GPU
The keymap and capslock code in src/plugins/renderers/drm/plugin.c relies
on the terminal passed to backend_create() to get the keymap and current
capslock state (when not using evdev input because of e.g. no XKBLAYOUT
in /etc/vconsole.conf which is the default in at least Fedora).
When 2 GPUs which both have displays attached are used only the first
one gets passed the local_console_terminal as terminal (it is considered
the terminal owner and e.g. listens for keypresses). This leads to keymap
and capslock icons not being shown on displays attached to the second GPU.
To fix this add a second ply_terminal_t argument to backend_create() called
local_console_terminal, which will pass the local_console_terminal to both
drm plugin instances. And modify the drm plugin capslock and keymap code to
use this instead of the normal terminal argument which will be NULL on
the second GPU.
Hans de Goede [Tue, 1 Jul 2025 18:41:24 +0000 (20:41 +0200)]
Add UseSimpledrmNoLuks config file keyword
Add a UseSimpledrmNoLuks config file keyword this enables simpledrm use,
like the existing "UseSimpledrm" config file keyword. Except when using
LUKS. Showing the LUKS unlock screen using simpledrm has 2 problems:
1. If the GPU drivers are built into the initrd then typically the
unlock screen will briefly show and then the screen goes black
2. The i915 driver uses the firmware framebuffer as fallback when
userspace has not installed a fb to scan out from. This happens
e.g. on logout between the user-session and the display-manager.
Drawing the unlock screen on the simpledrm fb results in it briefly
showing when logging out, which looks quite ugly.
This allows distributions to chose to only enable simpledrm when
LUKS is not used.
Hans de Goede [Tue, 1 Jul 2025 12:37:03 +0000 (14:37 +0200)]
drm: Fix crash when terminal fd is still -1 after reconnect
The drm plugin code installs a fd disconnect handler for the terminal fd
which simply calls open_input_source () again.
This assumes that the ply-terminal code's disconnect handler has run first
(which it should) and that ply_terminal_reopen_device () has successfully
re-opened the terminal. This last condition is not always true, resulting
in open_input_source () calling ply_event_loop_watch_fd () with a -1 fd
triggerig an assert in ply_event_loop_watch_fd ():
5 0x00007f62d39a1c6f in __assert_fail (assertion=<optimized out>, file=<optimized out>, line=<optimized out>, function=<optimized out>) at assert.c:127
6 0x00007f62d3bc22c7 in ply_event_loop_watch_fd (loop=<optimized out>, fd=-1, status=status@entry=PLY_EVENT_LOOP_FD_STATUS_HAS_DATA,
status_met_handler=status_met_handler@entry=0x7f62d3790870 <on_terminal_key_event>,
disconnected_handler=disconnected_handler@entry=0x7f62d3790c70 <on_input_source_disconnected>, user_data=user_data@entry=0x5647f7dd9fb8)
at ../src/libply/ply-event-loop.c:732
7 0x00007f62d3790bf6 in open_input_source (backend=0x5647f7dd9f90, input_source=0x5647f7dd9fb8) at ../src/plugins/renderers/drm/plugin.c:1930
8 0x00007f62d3bcbd53 in ply_event_loop_handle_disconnect_for_source (loop=<optimized out>, source=0x5647f7dd69f0) at ../src/libply/ply-event-loop.c:1065
9 ply_event_loop_disconnect_source (loop=<optimized out>, source=0x5647f7dd69f0) at ../src/libply/ply-event-loop.c:1157
10 ply_event_loop_process_pending_events (loop=0x5647f7dd13e0) at ../src/libply/ply-event-loop.c:1277
11 0x00007f62d3bcc068 in ply_event_loop_run (loop=0x5647f7dd13e0) at ../src/libply/ply-event-loop.c:1311
12 0x00005647c99bba48 in main (argc=<optimized out>, argv=<optimized out>) at ../src/main.c:2572
Fix this by checking that the fd >= 0 before calling
ply_event_loop_watch_fd ().
The above backtrace is from the drm plugin, but the same problem exists
in the frame-buffer plugin. So this fix is applied to both.
Hans de Goede [Thu, 3 Jul 2025 10:23:57 +0000 (12:23 +0200)]
two-step: Remove ':' at the end of (passphrase) prompt below text entry field
When asked for e.g. a disk unlock passphrase, plymouth will be passed
a prompt like: "Please enter passphrase for disk $DISK:" the ':' in
the end makes sense when asking for this a text console, but this makes
less sense in the two-step disk unlock screen where the text is below
the passphrase entry field.
Strip any ':' char at the prompt's end on two-step's disk unlock screen.
Hans de Goede [Thu, 3 Jul 2025 11:05:13 +0000 (13:05 +0200)]
ply-keymap-icon: Fix falling back to label-plugin when there is no pre-rendered text
In order for the fallback path (keymap_icon->has_prerendered_text == false)
to work properly keymap_icon->keymap_name must be set when no pre-rendered
text is found.
Tested by temporarily removing the "us" entry from ply-keymap-metadata.h.
Janne Grunau [Sat, 17 May 2025 06:57:06 +0000 (08:57 +0200)]
drm: Add simpledrm HiDPI display support
For devicetree based systems simpledrm might know the actual physical
display dimensions. Test if the reported connector width and height
result in a pixel density larger than 96 DPI. If that's the case
calculate the device scale instead of guessing it based on the
resolution.
This restores HiDPI scaling on 13-inch Apple silicon Macbooks with a
resolution of 2560x1600 (224 - 227 DPI) after commit 1421a9f6
("ply-utils: Increase threshold for guessed hiDPI scaling
to >= 2880x1620").
Janne Grunau [Sat, 17 May 2025 16:20:30 +0000 (18:20 +0200)]
ply-utils: Adjust HiDPI cut-off value to 1.625f
This matches mutter's behaviour before
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3616 was merged.
It first rounded to the newest fractional scale factor (in 0.25 steps)
and then rounded N.25 and N.5 down to N and N.75 up to N+1.
Commit 3b8e9184 ("ply-utils: Only choose scale 2 when the perfect scale
would be >= 1.75") interprets the mentioned difference of at most 0.25
for rounding up very literal. A differnt ionterpretation of
https://github.com/GNOME/mutter/commit/d03dce43786ddfaca86a0ec006264c1b0dfd74d9
intend is that it's desireable to round N.5 down.
This change has unexpected side effect of using a device scale of 1 for
most of Apple's Retina displays in Macbooks (221 - 227 DPI). Raised as
https://gitlab.gnome.org/GNOME/mutter/-/issues/4110 in mutter.
Using 1.75f cut-off value requires a pixel density of 236.25 for HiDPI
while 1.625f requires only 219.375 DPI.
Mutter use the same calculation with
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4490 merged.
According to ECMA-48 [1], Select Graphic Rendition (SGR) attribute 21
is for "doubly underlined", not "disabling bold" in current plymouth
implementation.
Additionally, SGR 22 is for "normal colour or normal intensity (neither
bold nor faint)", both bold and dim should be disabled with it.
Tomita Moeko [Wed, 7 May 2025 13:59:28 +0000 (21:59 +0800)]
ply-kmsg-reader: Fix doubly underlined text output
Currently plymouth applies Select Graphic Rendition (SGR) attribute 21
to disable bold text. However, per ECMA-48 [1], this attribute is for
doubly underlined text, not for disabling bold, resulting unintended
doubly underlined output on boot. Fix it by conditionally applying
standard bold attribute (SGR 1) on bold text.
handle_ksmg_message wrongly assumed that all messages are terminated
with a trailing line feed: kernel messages emitted by pr_cont() may
not. At any rate, the return value of the strchr() call ought to be
checked to avoid crashing when parsing incoming messages.
Adrian Vovk [Fri, 9 May 2025 19:35:38 +0000 (15:35 -0400)]
kmsg-reader: Seek to the end of the ringbuffer
Otherwise, whenever plymouth starts we'd replay all previous kmsg
entries, even if they've already been logged to the console. This leads
to duplicated log entires, and makes it hard to debug things.
With /dev/console, we only log what we capture while Plymouth is
running. Let's do the same with /dev/kmsg
Adrian Vovk [Fri, 9 May 2025 19:17:48 +0000 (15:17 -0400)]
details: Suppress kernel's own kmsg console output
Plymouth forwards /dev/console and /dev/kmsg to all consoles (and to the
graphical splash). With the details plugin, we would do this without
suppressing the kernel's own output first. This would lead to duplicate
log entries
Adrian Vovk [Fri, 9 May 2025 18:44:24 +0000 (14:44 -0400)]
utils: Don't lose log level when silencing kmsg
Once we disable kmsg logging to the console, the kernel will set the
console log level to the minimum log level (i.e. only logging kernel
panics). However the unintended side effect is that our own kmsg-reader
will start filtering out all kernel log messages, since we also respect
the kernel's console log level.
This change make it so that we keep using the original console log level
whenever we disable the kernel's output. This lets us keep forwarding
the kernel's kmsg output
Hans de Goede [Thu, 6 Mar 2025 16:53:43 +0000 (17:53 +0100)]
ply-utils: Increase threshold for guessed hiDPI scaling to >= 2880x1620
1440 is only 33% more then FHD, so using 2x there is a bit too much and
leads to the spinner being much too large on e.g 27" monitors.
And on e.g. Dell ultrawide 34" 3440x1440 which are only 110 DPI this effect
is even worse.
Change the threshold to >= 2880x1620 to avoid using 2x scaling on 1440p
monitors. 2880x1620 is ~240DPI when used in a 14" laptop at which point
using 2x scaling is really necessary.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
The comment about why SimpleDRM devices should be skipped is no longer
accurate, the kernel does provide rotation info now; and plymouth now
has heuristics to guess the device-scale.
If SimpleDRM devices should be used or not now mostly is a user
preference.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Hans de Goede [Tue, 4 Mar 2025 14:22:45 +0000 (15:22 +0100)]
libply-splash-core: Add a force argument to ply_renderer_open ()
Sometimes a renderer plugin may want to refuse to open a device
because it has suboptimal settings, like e.g. an EFI framebuffer
based simpledrm when the EFI firmware has set the resolution to
800x600 instead of the native panel resolution.
In such a case it might be better to wait for another better
/dev/dri/card# device to show up.
This skipping of devices by renderer plugins needs to be configurable
in case the timeout hits, or the user wishes to override things.
Add a force argument to ply_renderer_open () to allow overriding
this behavior. User can force using simpledrm by passing
plymouth.use-simpledrm=2 on the kernel commandline or by setting
UseSimpledrm=2 in the config-file.
This flag is passed to the renderer plugin's query_device () method
as that is the best place for the renderer plugin to determine
a device's usability.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Hans de Goede [Mon, 17 Feb 2025 14:47:11 +0000 (15:47 +0100)]
Make simpledrm selection configurable from config file
Move the handling of the "plymouth.use-simpledrm" commandline argument from
ply-device-manager to main.c, and allow specifying its default value in
the "[Daemon]" section of the config-file using a new UseSimpledrm keyword.
Extend the "plymouth.use-simpledrm" handling to also accept a value e.g.
"plymouth.use-simpledrm=0" to allow overriding a "UseSimpledrm=1" in
the configfile.
And pass the use-simpledrm value to ply_device_manager_new () through a new
PLY_DEVICE_MANAGER_FLAGS_USE_SIMPLEDRM flag.
This also moves the kernel commandline handling to src/main.c grouping
it together with most of the other commandline handling.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
To avoid the later parsed config files *with lower priorities* overriding
earlier settings the code initializes the config variables to NAN and only
sets them if they are still set to NAN.
Except for the device_scale handling, where load_settings () always calls
ply_set_device_scale () overriding earlier values, the commandline
handling for "plymouth.force-scale=..." is done separately later so that
the commandline does take priority over the config files, but since
/usr/share/plymouth/plymouthd.defaults is parsed last any DeviceScale
setting there will override /etc/plymouth/plymouthd.conf settings.
Fix this by following the pattern used by start_time/splash_delay/
device_timeout, add a device_scale variable initialized to -1 and
only override that variable if it is at -1.
This also allows removing find_force_scale () moving the commandline
parsing to find_override_splash () together with the other commandline
handling.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Hans de Goede [Mon, 10 Feb 2025 10:47:57 +0000 (11:47 +0100)]
ply-keymap-icon: Make Dvorak check case-insensitive
When using evdev support the XKB keymap name (with variant) for Dvorak
users will be e.g. "US (Dvorak)". The Dvorak layouts are not described
in /usr/share/X11/xkb/rules/evdev.xml, so these are not added to
ply-keymap-metadata.h / keymap-render.png .
For the console-keymap case dvorak is handled specially in:
mapping all keymap-names with a lowercase dvorak in there to "dvorak",
change this special handling to be case-insensitive so that it also works
for the xkb-keymap case.
Note the keymap-render.py change really is a no-op since keymap-render.py
only calls normalize_keymaps() on console-keymaps which are always
lower-case. normalize_keymaps() should still be updated though to keep
the 2 functions in sync.
Bold monospace fonts are prominently used in the console output printed
by systemd. Without them, the output looks incorrect compared to pango.
This still is far from a complete implementation of rich text, but
brings label-freetype much closer to what label-pango does for the
default theme.
This commit introduces a glyph_face variable in load_glyphs() that holds
the correct face for the current glyph (label->face or
label->bold_face). This face is then passed on to load_glyph() and
finish_measuring_line() to ensure correct font measurements.
Ray Strode [Wed, 1 May 2024 12:23:00 +0000 (08:23 -0400)]
main: Go back to text mode when quitting (if appropriate)
Since commit 48881ba2ef3d25fd27fd150d4d5957d4df9868e0 plymouth
goes into GRAPHICS mode early on. Unfortunately, there are cases
where it neglects to go back to TEXT mode when quitting. That can
happen if boot finishes before the splash screen is created.
nerdopolis [Fri, 2 Aug 2024 11:56:28 +0000 (07:56 -0400)]
ply-device-manager: Don't log an error when /sys/class/tty/console/active is empty
This is possible on some kernels that were built with CONFIG_NULL_TTY enabled, and were booted with console=ttynull
/sys/class/tty/console/active is empty in this case, so the file being empty is not always an error worth logging
Hans de Goede [Wed, 5 Jun 2024 20:07:32 +0000 (22:07 +0200)]
ply-device-manager: Make create_devices_for_subsystem () return void
Make create_devices_for_subsystem () return void. Its callers do not care
about the return value and currently the return value is not always correct
since if a device is found, found may later become false again if
a subsequent create_devices_for_udev_device () call fails.
Hans de Goede [Tue, 4 Jun 2024 21:07:19 +0000 (23:07 +0200)]
ply-device-manager: Create renderer for simpledrm devices right away
Often when plymouth starts and enumerates udev devices which are already
present at start (coldplug detection), udev is still initializing all
the devices and it reports 0 for udev_device_get_is_initialized ().
It may take a long time for the state of the simpledrm udev device
to change to initialized and for a udev add event to be send.
Especially when the amdgpu kernel module is involved which is very
large for a kernel module and can take op to 7 seconds to load.
In this case it is even possible for plymouth's default DeviceTimeout
of 8 seconds to trigger before the simpledrm device is considered
initialized. See for example these lines extracted from the plymouth-debug
log attached to: https://bugzilla.redhat.com/show_bug.cgi?id=2183743
00:00:02.909 ../src/libply-splash-core/ply-device-manager.c:498:create_devi: found device /sys/devices/pci0000:00/0000:00:01.0/simple-framebuffer.0/drm/card0
00:00:02.910 ../src/libply-splash-core/ply-device-manager.c:513:create_devi: it's not initialized
00:00:10.917 ../src/libply-splash-core/ply-device-manager.c:1237:create_dev: Timeout elapsed, looking for devices from udev
00:00:10.918 ../src/libply-splash-core/ply-device-manager.c:498:create_devi: found device /sys/devices/pci0000:00/0000:00:01.0/simple-framebuffer.0/drm/card0
00:00:10.918 ../src/libply-splash-core/ply-device-manager.c:513:create_devi: it's not initialized
This leads to plymouth falling back to the text splash even when
plymouth.use-simpledrm is passed on the kernel commandline.
Add a special case for simpledrm devices and add these during coldboot
even if they are not initialized yet.
Hans de Goede [Wed, 5 Jun 2024 19:52:19 +0000 (21:52 +0200)]
ply-device-manager: Remove simpledrm renderers before adding normal drm renderers
udev remove events for simpledrm udev devices may arrive after the udev add
event for a normal drm udev device which is replacing the simpledrm device.
When the local_console is managed by a simpledrm renderer and the remove
event for the simpledrm renderer is received after the add event of
the normal drm device, the local_console is left unmanaged breaking legacy
input support.
When this scenario gets hit it breaks entering disk unlock passwords.
Add code to remove simpledrm renderers before adding normal drm renderers
to avoid this.
Hans de Goede [Wed, 5 Jun 2024 19:38:43 +0000 (21:38 +0200)]
ply-device-manager: Move local_console_terminal handling for DRM/FB renderers
create_devices_for_terminal_and_renderer_type () only ever gets called with
a NULL terminal parameter when create_devices_for_udev_device () is calling
it to create a DRM or FB renderer.
Move the use of local_console_terminal as terminal for the first DRM / FB
renderer created from create_devices_for_udev_device () to
create_devices_for_terminal_and_renderer_type () with an extra !terminal
check.
This is a preparation patch for fixing an issue where the local_console
is managed by a simpledrm renderer and the remove event for that gets
processed after the add event of the normal drm device which leaves
the local_console unmanaged breaking legacy input support.