On hidpi screens, label-freetype will trigger a use-after-free in
set_font_for_control() via the call in update_scale_factor_from_pixel_buffer().
That call passes label->font as the font parameter to set_font_for_control().
set_font_for_control() then calls strdup() on its font argument, and
frees label->font. In this case this causes font to point into freed
memory, causing a read use-after-free in the following strstr() and
strrchr() calls.
Fix the issue by only using the freshly strdup()'d new_font variable
after freeing label->font.
When multiple displays of different resolutions are attached, the Plymouth script
plugin uses a virtual "max canvas" (defined by max_width and max_height) for
rendering. Individual displays calculate their offsets (display->x, display->y)
relative to this max canvas for mirroring/centering.
The script-level centering formula, as seen in example themes:
logo.sprite.SetX (Window.GetX() + Window.GetWidth() / 2 - logo.image.GetWidth() / 2);
Issue:
For the script to correctly calculate the absolute center position on the max canvas,
Window.GetX() must conceptually return the origin of the max canvas, which is 0.
However, the non-indexed implementation of sprite_window_get_x (and GetY) currently
returns the maximum calculated display offset (MAX(display->x)), which corresponds to
the offset of the smallest display. This incorrect, non-zero return value introduces
an unintended shift, pushing sprites (like the logo) off-center, and breaking the
centering logic.
Solution:
Update sprite_window_get_x and sprite_window_get_y to return the minimum calculated
display offset (MIN(display->x)). Since the largest display always has an offset of 0,
this guarantees that Window.GetX() and Window.GetY() return 0 when called without
parameters, correctly anchoring the script-calculated center position to the absolute
max canvas origin.
Signed-off-by: xinpeng.wang <wangxinpeng@uniontech.com>
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.
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2375854
Signed-off-by: Hans de Goede <hansg@kernel.org>
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.
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2370979
Signed-off-by: Hans de Goede <hansg@kernel.org>
Two-step's disk unlock screen shows the prompt text directly below
the text entry field without any padding which looks bad.
Add some padding to make things look better.
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2356893
Signed-off-by: Hans de Goede <hansg@kernel.org>
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.
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2356893
Signed-off-by: Hans de Goede <hansg@kernel.org>
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").
Signed-off-by: Janne Grunau <j@jannau.net>
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
Sometimes the EFI firmware initializes the framebuffer at a very low
resolution rather then at the panel's native resolution.
In this case it is better to wait for the native GPU driver to load
rather then rendering a not-so-pretty splash at this very low resolution.
Reject these low resolutions for simpledrm devices except when
query_device () is called with force=true.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
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>
Change ply_key_file_get_long () into ply_key_file_get_ulong () and add
error checking.
All callers of ply_key_file_get_long () expect a positive / unsigned number.
Rename it to ply_key_file_get_ulong ().
Also add error checkig for non valid numbers and return the default value
for these instead of 0.
Note this also fixes the return value of ply_key_file_get_long () being
a double (this is now changed to an unsigned long).
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
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.
The new font loading functions introduced in
544e62ac41 assume that popen() returns
NULL when fc-match is unavailable or fails. This is incorrect, since
popen() will always start a shell to run the passed command and return a
stream to that shell's stdin and stdout.
This results in an non-null but empty font name being passed to
FT_New_Face(), which fails.
This commit fixes this by also using the fallback font when the font
path read from the popen() stream is empty.
Fixes#239
Fixes regression caused by 544e62ac41
The freetype plugin correctly doubles the DPI on hidpi displays,
but fails to account for the doubled pixels in display's pixel buffer.
This commit adds a factor of 2 to the size and positioncomputations,
to hopefully fix a row stride and a positioning bug.
There's currently this function, set_font_with_fallback, that
almost always gets called with a NULL first argument in the
initramfs, forcing the _with_fallback part of the function to
run.
It's a little strange to have a function with a chunk of code that
hardly ever runs. Furthermore there's a bug where the error variable
is left uninitialized in this case leading to the freetype plugin
sporadically failing to load the fallback font.
This commit reworks things to drop set_font_with_fallback, and just
call FT_New_Face directly in the caller. Fallbacks are handled
at the point where the font path is determined
(previously called query_fc_match, now called find_default_font_path.
There are a few issues with the remove_hexboxes_from_pango_layout
function, where it's getting offsets wrong and things like that.
This commit changes the approach entirely. Rather than modifying
the text to remove characters without font converage, it just
changes out the glyphs for those characters to be white boxes.
We don't need to flush the terminal input buffer on key events from
the renderers, because the terminal does that itself.
Also, we should disable the terminal input when a /dev/input
device is added instead of relying on it happening the next flush
period.
Finally, we should make sure the terminal gets reenabled on close,
just so we clean up after ourselves.
If code calls ply_label_get_width without ply_label_show or some other
call that forces the dimensions to be computed first, then the returned
width will be wrong.
This commit makes the freetype plugin look more like the pango plugin
where the size will computed on demand when querying the width, if
necessary.
pango will give a height that's several orders of magnitude too
big sometimes when the width is -1.
This commit checks for -1, explicitly measures the width first, and
remeasures with that width passed in to compute the height.