Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package kmscon for openSUSE:Factory checked in at 2026-02-06 19:11:04 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/kmscon (Old) and /work/SRC/openSUSE:Factory/.kmscon.new.1670 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "kmscon" Fri Feb 6 19:11:04 2026 rev:9 rq:1331630 version:9.3.1 Changes: -------- --- /work/SRC/openSUSE:Factory/kmscon/kmscon.changes 2026-01-26 11:34:13.530102566 +0100 +++ /work/SRC/openSUSE:Factory/.kmscon.new.1670/kmscon.changes 2026-02-06 19:17:50.055024306 +0100 @@ -1,0 +2,21 @@ +Fri Feb 06 12:01:16 UTC 2026 - Fabian Vogt <[email protected]> + +- Update to version 9.3.1: + * Prepare v9.3.1 release + * drm: set master only if needed + * drm: Refactor dpms, to only set it if needed + * drm: Add device name, for easier multi-gpu debug + * Font: remove unused baseline field + * unifont: Add bold and underline support + * unifont: use sparse table, to be able to use codepoints after 0xFFFF + * drm: Fix black screen when switching back to kmscon + * feat: Read /proc/sys/kernel/ctrl-alt-del to decide reboot behavior + * agetty: Add -8 arguments to accept full 8-bits characters + * start script: get local from localectl too + * units: fill out [Install] section + * units: drop unnecessary templating of units + * man: Document --version/-V option + * conf: Add --version/-V command-line option + * conf: Fix help text formatting and typos + +------------------------------------------------------------------- Old: ---- kmscon-9.3.0+git1.obscpio New: ---- kmscon-9.3.1.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ kmscon.spec ++++++ --- /var/tmp/diff_new_pack.Vd2IIa/_old 2026-02-06 19:17:50.815056463 +0100 +++ /var/tmp/diff_new_pack.Vd2IIa/_new 2026-02-06 19:17:50.819056632 +0100 @@ -18,7 +18,7 @@ Name: kmscon -Version: 9.3.0+git1 +Version: 9.3.1 Release: 0 Summary: Linux KMS/DRM based virtual Console Emulator License: MIT ++++++ _service ++++++ --- /var/tmp/diff_new_pack.Vd2IIa/_old 2026-02-06 19:17:50.863058494 +0100 +++ /var/tmp/diff_new_pack.Vd2IIa/_new 2026-02-06 19:17:50.871058833 +0100 @@ -2,7 +2,7 @@ <service mode="manual" name="obs_scm"> <param name="url">https://github.com/kmscon/kmscon.git</param> <param name="scm">git</param> - <param name="revision">24a19ad91c18f0bb4ce95ddc533a116bc1bcad7a</param> + <param name="revision">v9.3.1</param> <param name="changesgenerate">enable</param> <param name="versionformat">@PARENT_TAG@+git@TAG_OFFSET@</param> <param name="versionrewrite-pattern">v(.*?)(\+git0)?$</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.Vd2IIa/_old 2026-02-06 19:17:50.903060186 +0100 +++ /var/tmp/diff_new_pack.Vd2IIa/_new 2026-02-06 19:17:50.915060694 +0100 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/kmscon/kmscon.git</param> - <param name="changesrevision">24a19ad91c18f0bb4ce95ddc533a116bc1bcad7a</param></service></servicedata> + <param name="changesrevision">e44ff728e51c5a38b56392abe9bc3e8306db86cc</param></service></servicedata> (No newline at EOF) ++++++ kmscon-9.3.0+git1.obscpio -> kmscon-9.3.1.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kmscon-9.3.0+git1/NEWS.md new/kmscon-9.3.1/NEWS.md --- old/kmscon-9.3.0+git1/NEWS.md 2026-01-23 09:07:07.000000000 +0100 +++ new/kmscon-9.3.1/NEWS.md 2026-02-02 15:44:22.000000000 +0100 @@ -1,5 +1,26 @@ = KMSCON Release News = +## CHANGES WITH 9.3.1 +* Bug fixes: + - Fix build on i686 by @kdj0c in https://github.com/kmscon/kmscon/pull/242 + - conf: Fix help text formatting and typos by @jtollet in https://github.com/kmscon/kmscon/pull/247 + - conf: Add --version/-V command-line option by @jtollet in https://github.com/kmscon/kmscon/pull/243 + - units: drop unnecessary templating of units by @keszybz in https://github.com/kmscon/kmscon/pull/246 + - units: fill out [Install] section by @keszybz in https://github.com/kmscon/kmscon/pull/245 + - start script: get local from localectl too by @kdj0c in https://github.com/kmscon/kmscon/pull/252 + - agetty: Add -8 arguments to accept full 8-bits characters by @kdj0c in https://github.com/kmscon/kmscon/pull/261 + - Read /proc/sys/kernel/ctrl-alt-del for reboot behavior by @jtollet in https://github.com/kmscon/kmscon/pull/264 + - drm: Fix black screen when switching back to kmscon by @kdj0c in https://github.com/kmscon/kmscon/pull/266 + - unifont: use sparse table, to be able to use codepoints after 0xFFFF by @kdj0c in https://github.com/kmscon/kmscon/pull/265 + - unifont: Add bold and underline support by @kdj0c in https://github.com/kmscon/kmscon/pull/267 + - Only take drm master if needed by @kdj0c in https://github.com/kmscon/kmscon/pull/269 + +## New Contributors +* @keszybz made their first contribution in https://github.com/kmscon/kmscon/pull/246 + +**Full Changelog**: https://github.com/kmscon/kmscon/compare/v9.3.0...v9.3.1 + + ## CHANGES WITH 9.3.0 * New features: - Enable mouse support by default by @kdj0c in https://github.com/kmscon/kmscon/pull/175 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kmscon-9.3.0+git1/docs/man/kmscon.1.xml.in new/kmscon-9.3.1/docs/man/kmscon.1.xml.in --- old/kmscon-9.3.0+git1/docs/man/kmscon.1.xml.in 2026-01-23 09:07:07.000000000 +0100 +++ new/kmscon-9.3.1/docs/man/kmscon.1.xml.in 2026-02-02 15:44:22.000000000 +0100 @@ -85,6 +85,17 @@ <para>Print a short help text and exit.</para> </listitem> </varlistentry> + <varlistentry> + <term><option>-V</option></term> + <term><option>--version</option></term> + <listitem> + <para>Print version information and exit. When combined with + <option>--verbose</option>, additional build information is shown + including compilation date and time, and enabled build options + (DRM 2D/3D support, FBDEV support, Pango font support).</para> + </listitem> + </varlistentry> + <varlistentry> <term><option>-v</option></term> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kmscon-9.3.0+git1/docs/man/kmscon.conf.1.xml.in new/kmscon-9.3.1/docs/man/kmscon.conf.1.xml.in --- old/kmscon-9.3.0+git1/docs/man/kmscon.conf.1.xml.in 2026-01-23 09:07:07.000000000 +0100 +++ new/kmscon-9.3.1/docs/man/kmscon.conf.1.xml.in 2026-02-02 15:44:22.000000000 +0100 @@ -392,7 +392,11 @@ <listitem> <para>Reboot the system when this keyboard shortcut is pressed. This option is disabled by default. - Use with caution as the reboot is immediate. + The reboot behavior follows the system-wide setting in + /proc/sys/kernel/ctrl-alt-del: when set to 0 (default), + a graceful reboot is performed by sending SIGINT to init (PID 1); + when set to a value greater than 0, an immediate hard reboot + is performed after syncing disk buffers. Example: grab-reboot=<Ctrl><Alt>Delete (default: disabled)</para> </listitem> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kmscon-9.3.0+git1/meson.build new/kmscon-9.3.1/meson.build --- old/kmscon-9.3.0+git1/meson.build 2026-01-23 09:07:07.000000000 +0100 +++ new/kmscon-9.3.1/meson.build 2026-02-02 15:44:22.000000000 +0100 @@ -3,7 +3,7 @@ # SPDX-License-Identifier: MIT project('kmscon', 'c', - version: '9.3.0', + version: '9.3.1', license: 'MIT', # meson 0.58: f-string # meson 0.62: dependency libdl @@ -190,14 +190,6 @@ 'install_dir': bindir, 'install_mode': 'rwxr-xr-x', }, - 'scripts/systemd/kmscon.service.in': { - 'install_dir': systemdsystemunitdir, - 'install_mode': 'rw-r--r--', - }, - 'scripts/systemd/[email protected]': { - 'install_dir': systemdsystemunitdir, - 'install_mode': 'rw-r--r--', - }, } install_data(configure_file(input: filename, output: '@BASENAME@', configuration: dirs_info), kwargs: kwargs, @@ -209,3 +201,11 @@ 'scripts/etc/kmscon.conf.example', install_dir: join_paths(get_option('sysconfdir'), 'kmscon') ) +install_data( + 'scripts/systemd/kmscon.service', + install_dir: systemdsystemunitdir, +) +install_data( + 'scripts/systemd/[email protected]', + install_dir: systemdsystemunitdir, +) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kmscon-9.3.0+git1/scripts/etc/kmscon.conf.example new/kmscon-9.3.1/scripts/etc/kmscon.conf.example --- old/kmscon-9.3.0+git1/scripts/etc/kmscon.conf.example 2026-01-23 09:07:07.000000000 +0100 +++ new/kmscon-9.3.1/scripts/etc/kmscon.conf.example 2026-02-02 15:44:22.000000000 +0100 @@ -67,7 +67,10 @@ #grab-terminal-new=<Ctrl><Logo>Return #grab-rotate-cw=<Logo>Plus #grab-rotate-ccw=<Logo>Minus -## Reboot system (disabled by default, use with caution - immediate reboot without confirmation) +## Reboot system (disabled by default) +## Reboot behavior follows /proc/sys/kernel/ctrl-alt-del: +## 0 (default): graceful reboot (sends SIGINT to init) +## >0: immediate hard reboot after syncing disk buffers #grab-reboot=<Ctrl><Alt>Delete ## Enable mouse diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kmscon-9.3.0+git1/scripts/kmscon.in new/kmscon-9.3.1/scripts/kmscon.in --- old/kmscon-9.3.0+git1/scripts/kmscon.in 2026-01-23 09:07:07.000000000 +0100 +++ new/kmscon-9.3.1/scripts/kmscon.in 2026-02-02 15:44:22.000000000 +0100 @@ -25,27 +25,34 @@ helperdir=@libexecdir@ # Get a property from org.freedesktop.locale1 -queryLocale1() { - dbus-send --system --print-reply=literal --dest=org.freedesktop.locale1 /org/freedesktop/locale1 org.freedesktop.DBus.Properties.Get "string:org.freedesktop.locale1" "string:$1" 2>/dev/null | awk '{print $2}' +queryLocaledbus() { + dbus-send --system --print-reply=literal --dest=org.freedesktop.locale1 /org/freedesktop/locale1 org.freedesktop.DBus.Properties.Get "string:org.freedesktop.locale1" "string:X11$1" 2>/dev/null | awk '{print $2}' +} + +queryLocalectl() { + localectl status | awk "/X11 $1/ {print \$3}" } # Query and setup system locale settings before start kmscon setupLocale() { - # Fallback to do nothing if we don't have the command - if ! command -v dbus-send >/dev/null 2>/dev/null; then - return - fi - # Don't override existing values. Also there is no point in setting only some of them # as then they would not match anymore. if test -n "${XKB_DEFAULT_MODEL}" -o -n "${XKB_DEFAULT_LAYOUT}" -o -n "${XKB_DEFAULT_VARIANT}" -o -n "${XKB_DEFAULT_OPTIONS}"; then return fi - X11MODEL="$(queryLocale1 X11Model)" - X11LAYOUT="$(queryLocale1 X11Layout)" - X11VARIANT="$(queryLocale1 X11Variant)" - X11OPTIONS="$(queryLocale1 X11Options)" + if command -v dbus-send >/dev/null 2>/dev/null; then + querycmd="queryLocaledbus" + elif command -v localectl >/dev/null 2>/dev/null; then + querycmd="queryLocalectl" + else + return + fi + + X11MODEL="$(${querycmd} Model)" + X11LAYOUT="$(${querycmd} Layout)" + X11VARIANT="$(${querycmd} Variant)" + X11OPTIONS="$(${querycmd} Options)" [ -n "${X11MODEL}" ] && export XKB_DEFAULT_MODEL="${X11MODEL}" [ -n "${X11LAYOUT}" ] && export XKB_DEFAULT_LAYOUT="${X11LAYOUT}" [ -n "${X11VARIANT}" ] && export XKB_DEFAULT_VARIANT="${X11VARIANT}" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kmscon-9.3.0+git1/scripts/systemd/kmscon.service new/kmscon-9.3.1/scripts/systemd/kmscon.service --- old/kmscon-9.3.0+git1/scripts/systemd/kmscon.service 1970-01-01 01:00:00.000000000 +0100 +++ new/kmscon-9.3.1/scripts/systemd/kmscon.service 2026-02-02 15:44:22.000000000 +0100 @@ -0,0 +1,12 @@ +[Unit] +Description=KMS System Console +Documentation=man:kmscon(1) +After=plymouth-quit-wait.service +After=systemd-user-sessions.service +After=rc-local.service + +[Service] +ExecStart=kmscon --login -- /sbin/agetty -o '-p -- \\u' --noclear -- - $$TERM + +[Install] +WantedBy=multi-user.target diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kmscon-9.3.0+git1/scripts/systemd/kmscon.service.in new/kmscon-9.3.1/scripts/systemd/kmscon.service.in --- old/kmscon-9.3.0+git1/scripts/systemd/kmscon.service.in 2026-01-23 09:07:07.000000000 +0100 +++ new/kmscon-9.3.1/scripts/systemd/kmscon.service.in 1970-01-01 01:00:00.000000000 +0100 @@ -1,12 +0,0 @@ -[Unit] -Description=KMS System Console -Documentation=man:kmscon(1) -After=plymouth-quit-wait.service -After=systemd-user-sessions.service -After=rc-local.service - -[Service] -ExecStart=@bindir@/kmscon --login -- /sbin/agetty -o '-p -- \\u' --noclear -- - $$TERM - -[Install] -WantedBy=multi-user.target diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kmscon-9.3.0+git1/scripts/systemd/[email protected] new/kmscon-9.3.1/scripts/systemd/[email protected] --- old/kmscon-9.3.0+git1/scripts/systemd/[email protected] 1970-01-01 01:00:00.000000000 +0100 +++ new/kmscon-9.3.1/scripts/systemd/[email protected] 2026-02-02 15:44:22.000000000 +0100 @@ -0,0 +1,52 @@ +# +# KMSCON system console on VTs on seat0 +# This unit takes as template argument a VT name (same as [email protected]) and +# spawns KMSCON on this VT. Note that this does automatically limit KMSCON to +# seat0. You cannot spawn KMSCON on other seats with this unit. +# +# You can replace the default [email protected] that is shipped with systemd by +# enabling this unit: +# systemctl enable kmsconvt@ +# This will make systemd start KMSCON instead of agetty on each VT. Or more +# precisely, this will make systemd-logind use [email protected] instead of +# [email protected] for new VTs. Other units that use [email protected] will not +# be affected by this change. +# +# Note that by default [email protected] installs itself as [email protected]. +# This unit does the same and overrules [email protected] via the "Conflict" +# line below. +# +# If KMSCON cannot start for whatever reason, this unit will cause +# [email protected] to be started instead. So you will always have a safe fallback. +# Furthermore, if no VTs are available, this unit will not start anything. +# +# You can still use [email protected] and [email protected] simultaneously on +# different VTs, but you cannot use both on the same VT (and this wouldn't make +# any sense). +# + +[Unit] +Description=KMS System Console on %I +Documentation=man:kmscon(1) +After=systemd-user-sessions.service +After=plymouth-quit-wait.service +After=rc-local.service +Before=getty.target +Conflicts=getty@%i.service +OnFailure=getty@%i.service +IgnoreOnIsolate=yes +ConditionPathExists=/dev/tty0 + +[Service] +ExecStart=kmscon --vt=%I --seats=seat0 --no-switchvt --login -- /sbin/agetty -8 -o '-p -- \\u' --noclear -- - $$TERM +UtmpIdentifier=%I +TTYPath=/dev/%I +TTYReset=yes +TTYVHangup=yes +TTYVTDisallocate=yes + +[Install] [email protected] + +WantedBy=getty.target +DefaultInstance=tty1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kmscon-9.3.0+git1/scripts/systemd/[email protected] new/kmscon-9.3.1/scripts/systemd/[email protected] --- old/kmscon-9.3.0+git1/scripts/systemd/[email protected] 2026-01-23 09:07:07.000000000 +0100 +++ new/kmscon-9.3.1/scripts/systemd/[email protected] 1970-01-01 01:00:00.000000000 +0100 @@ -1,49 +0,0 @@ -# -# KMSCON system console on VTs on seat0 -# This unit takes as template argument a VT name (same as [email protected]) and -# spawns KMSCON on this VT. Note that this does automatically limit KMSCON to -# seat0. You cannot spawn KMSCON on other seats with this unit. -# -# You can replace the default [email protected] that is shipped with systemd by -# linking it with: -# ln -s /usr/lib/systemd/system/[email protected] /etc/systemd/system/[email protected] -# This will make systemd start KMSCON instead of agetty on each VT. Or more -# precisely, this will make systemd-logind use [email protected] instead of -# [email protected] for new VTs. In fact, all other units/scripts/... that use -# [email protected] will not be affected by this change. -# -# Note that by default [email protected] installs itself as [email protected]. -# This unit does the same and overrules [email protected] via the "Conflict" -# line below. -# -# If KMSCON cannot start for whatever reason, this unit will cause -# [email protected] to be started instead. So you will always have a safe fallback. -# Furthermore, if no VTs are available, this unit will not start anything. -# -# You can still use [email protected] and [email protected] simultaneously on -# different VTs, but you cannot use both on the same VT (and this wouldn't make -# any sense). -# - -[Unit] -Description=KMS System Console on %I -Documentation=man:kmscon(1) -After=systemd-user-sessions.service -After=plymouth-quit-wait.service -After=rc-local.service -Before=getty.target -Conflicts=getty@%i.service -OnFailure=getty@%i.service -IgnoreOnIsolate=yes -ConditionPathExists=/dev/tty0 - -[Service] -ExecStart=@bindir@/kmscon --vt=%I --seats=seat0 --no-switchvt --login -- /sbin/agetty -o '-p -- \\u' --noclear -- - $$TERM -UtmpIdentifier=%I -TTYPath=/dev/%I -TTYReset=yes -TTYVHangup=yes -TTYVTDisallocate=yes - -[Install] -WantedBy=getty.target diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kmscon-9.3.0+git1/src/font.h new/kmscon-9.3.1/src/font.h --- old/kmscon-9.3.0+git1/src/font.h 2026-01-23 09:07:07.000000000 +0100 +++ new/kmscon-9.3.1/src/font.h 2026-02-02 15:44:22.000000000 +0100 @@ -70,7 +70,6 @@ struct shl_register_record *record; const struct kmscon_font_ops *ops; struct kmscon_font_attr attr; - unsigned int baseline; void *data; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kmscon-9.3.0+git1/src/font_8x16.c new/kmscon-9.3.1/src/font_8x16.c --- old/kmscon-9.3.0+git1/src/font_8x16.c 2026-01-23 09:07:07.000000000 +0100 +++ new/kmscon-9.3.1/src/font_8x16.c 2026-02-02 15:44:22.000000000 +0100 @@ -69,7 +69,6 @@ out->attr.width = 8; out->attr.height = 16; kmscon_font_attr_normalize(&out->attr); - out->baseline = 4; return 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kmscon-9.3.0+git1/src/font_pango.c new/kmscon-9.3.1/src/font_pango.c --- old/kmscon-9.3.0+git1/src/font_pango.c 2026-01-23 09:07:07.000000000 +0100 +++ new/kmscon-9.3.1/src/font_pango.c 2026-02-02 15:44:22.000000000 +0100 @@ -418,7 +418,6 @@ if (ret) return ret; memcpy(&out->attr, &face->real_attr, sizeof(out->attr)); - out->baseline = face->baseline; out->data = face; return 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kmscon-9.3.0+git1/src/font_unifont.c new/kmscon-9.3.1/src/font_unifont.c --- old/kmscon-9.3.0+git1/src/font_unifont.c 2026-01-23 09:07:07.000000000 +0100 +++ new/kmscon-9.3.1/src/font_unifont.c 2026-02-02 15:44:22.000000000 +0100 @@ -52,15 +52,15 @@ #define LOG_SUBSYSTEM "font_unifont" /* - * Glyph data is linked to the binary externally as binary data. The data layout - * is a size-byte followed by 32 data bytes. The data bytes are padded with 0 if - * the size is smaller than 32. - * Sizes bigger than 32 are not used. + * We regroup all glyphs into blocks, of contiguous codepoints, and same width. + * This allows to better pack the data, and handle some codepoints that are + * not in the 0xffff range */ - -struct unifont_data { - uint8_t len; - uint8_t data[32]; +struct unifont_glyph_block { + uint32_t codepoint; // First codepoint of the block + uint32_t offset; // offset of the data + uint16_t len; // number of glyph in this block + uint8_t width; // glyph width (1 or 2 for double-width glyph) } __attribute__((__packed__)); /* @@ -99,18 +99,68 @@ free(g); } -static void unfold(uint8_t *dst, uint8_t val) +static uint8_t apply_attr(uint8_t c, const struct kmscon_font_attr *attr, bool last_line) +{ + if (attr->bold) + c |= c >> 1; + if (attr->underline && last_line) + c = 0xff; + return c; +} + +static uint8_t unfold(uint8_t val) +{ + return 0xff * !!val; +} + +static bool is_in_block(const struct unifont_glyph_block *idx, uint32_t ch) { - *dst = 0xff * !!val; + return (ch >= idx->codepoint && ch < idx->codepoint + idx->len); } -static int find_glyph(uint32_t ch, const struct kmscon_glyph **out) +static int lookup_block(const struct unifont_glyph_block *blocks, uint32_t len, uint32_t ch) +{ + int look = 1 + ((ch * len) / 0xffff); /* opportunist first look*/ + int min = 0; + int max = len - 1; + + if (look > max) + look = max; + + while (min != max) { + log_debug("lookup %d codep %d, look %d min %d max %d", ch, blocks[look].codepoint, + look, min, max); + + if (is_in_block(&blocks[look], ch)) + return look; + if (ch < blocks[look].codepoint) { + max = look; + look -= look - min > 2 ? (look - min) / 2 : 1; + + } else { + min = look; + look += max - look > 2 ? (max - look) / 2 : 1; + } + } + if (is_in_block(&blocks[look], ch)) + return look; + return -1; +} + +static int find_glyph(uint64_t id, const struct kmscon_glyph **out, + const struct kmscon_font_attr *attr) { struct kmscon_glyph *g; + uint32_t ch = id & TSM_UCS4_MAX; + const void *start = _binary_font_unifont_data_start; + const uint8_t *end = (uint8_t *)_binary_font_unifont_data_end; + const uint8_t *data; + uint8_t c; + uint32_t len; + const struct unifont_glyph_block *blocks; + unsigned int i, k; int ret; bool res; - const struct unifont_data *start, *end, *d; - unsigned int i, w; pthread_mutex_lock(&cache_mutex); @@ -121,49 +171,48 @@ goto out_unlock; } } else { - res = shl_hashtable_find(cache, (void **)out, ch); + res = shl_hashtable_find(cache, (void **)out, id); if (res) { ret = 0; goto out_unlock; } } - - if (ch > 0xffff) { - ret = -ERANGE; - goto out_unlock; + /* First the length of the block index */ + len = *((uint32_t *)start); + /* Then the block index */ + blocks = (struct unifont_glyph_block *)(start + 4); + /* Then the glyph data */ + data = (uint8_t *)start + 4 + len * sizeof(struct unifont_glyph_block); + + int idx = lookup_block(blocks, len, ch); + if (idx < 0) { + log_debug("codepoint %08x not found, using replacement glyph", ch); + ch = 0xfffd; + idx = lookup_block(blocks, len, ch); + if (idx < 0) { + log_warning("Replacement glyph not found"); + ret = -1; + goto out_unlock; + } } - start = (const struct unifont_data *)_binary_font_unifont_data_start; - end = (const struct unifont_data *)_binary_font_unifont_data_end; - d = &start[ch]; - - if (d >= end) { + data += blocks[idx].offset + (ch - blocks[idx].codepoint) * blocks[idx].width * 16; + if (data + 16 * blocks[idx].width > end) { + log_warning("glyph out of range %p %p", data, end); ret = -ERANGE; goto out_unlock; } - switch (d->len) { - case 16: - w = 1; - break; - case 32: - w = 2; - break; - default: - ret = -EFAULT; - goto out_unlock; - } - g = malloc(sizeof(*g)); if (!g) { ret = -ENOMEM; goto out_unlock; } memset(g, 0, sizeof(*g)); - g->width = w; - g->buf.width = w * 8; + g->width = blocks[idx].width; + g->buf.width = g->width * 8; g->buf.height = 16; - g->buf.stride = w * 8; + g->buf.stride = g->width * 8; g->buf.format = UTERM_FORMAT_GREY; g->buf.data = malloc(g->buf.stride * g->buf.height); @@ -172,18 +221,13 @@ goto err_free; } - for (i = 0; i < d->len; ++i) { - unfold(&g->buf.data[i * 8 + 0], d->data[i] & 0x80); - unfold(&g->buf.data[i * 8 + 1], d->data[i] & 0x40); - unfold(&g->buf.data[i * 8 + 2], d->data[i] & 0x20); - unfold(&g->buf.data[i * 8 + 3], d->data[i] & 0x10); - unfold(&g->buf.data[i * 8 + 4], d->data[i] & 0x08); - unfold(&g->buf.data[i * 8 + 5], d->data[i] & 0x04); - unfold(&g->buf.data[i * 8 + 6], d->data[i] & 0x02); - unfold(&g->buf.data[i * 8 + 7], d->data[i] & 0x01); + for (i = 0; i < g->width * 16; ++i) { + c = apply_attr(data[i], attr, i >= g->width * 15); + for (k = 0; k < 8; k++) + g->buf.data[i * 8 + k] = unfold(c & (1 << (7 - k))); } - ret = shl_hashtable_insert(cache, ch, g); + ret = shl_hashtable_insert(cache, id, g); if (ret) { log_error("cannot insert glyph into glyph-cache: %d", ret); goto err_data; @@ -215,12 +259,11 @@ memset(&out->attr, 0, sizeof(out->attr)); memcpy(out->attr.name, name, sizeof(name)); - out->attr.bold = false; + out->attr.bold = attr->bold; out->attr.italic = false; out->attr.width = 8; out->attr.height = 16; kmscon_font_attr_normalize(&out->attr); - out->baseline = 4; cache_ref(); return 0; @@ -238,19 +281,19 @@ if (len > 1) return -ERANGE; - return find_glyph(id & TSM_UCS4_MAX, out); + return find_glyph(id, out, &font->attr); } static int kmscon_font_unifont_render_inval(struct kmscon_font *font, const struct kmscon_glyph **out) { - return find_glyph(0xfffd, out); + return find_glyph(0xfffd, out, &font->attr); } static int kmscon_font_unifont_render_empty(struct kmscon_font *font, const struct kmscon_glyph **out) { - return find_glyph(' ', out); + return find_glyph(' ', out, &font->attr); } struct kmscon_font_ops kmscon_font_unifont_ops = { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kmscon-9.3.0+git1/src/genunifont.c new/kmscon-9.3.1/src/genunifont.c --- old/kmscon-9.3.0+git1/src/genunifont.c 2026-01-23 09:07:07.000000000 +0100 +++ new/kmscon-9.3.1/src/genunifont.c 2026-02-02 15:44:22.000000000 +0100 @@ -45,6 +45,18 @@ char data[MAX_DATA_SIZE]; }; +/* + * We regroup all glyphs into blocks, of contiguous codepoints, and same width. + * This allows to better pack the data, and handle some codepoints that are + * not in the 0xffff range + */ +struct unifont_glyph_block { + uint32_t codepoint; // First codepoint of the block + uint32_t offset; // offset of the data + uint16_t len; // number of glyph in this block + uint8_t width; // glyph width (1 or 2 for double-width glyph) +} __attribute__((__packed__)); + static uint8_t hex_val(char c) { if (c >= '0' && c <= '9') @@ -63,23 +75,11 @@ size_t i; uint8_t val; - switch (g->len) { - case 32: - case 64: - break; - default: - fprintf(stderr, "genunifont: invalid data size %d for %x", g->len, g->codepoint); - return; - } - - fprintf(out, "%c", g->len / 2); for (i = 0; i < g->len; i += 2) { val = hex_val(g->data[i]) << 4; val |= hex_val(g->data[i + 1]); fprintf(out, "%c", val); } - for (; i < 64; i += 2) - fprintf(out, "%c", 0); } static int build_unifont_glyph(struct unifont_glyph *g, const char *buf) @@ -108,13 +108,74 @@ return 0; } +static uint8_t get_width(int len) +{ + if (len == 64) + return 2; + if (len == 32) + return 1; + fprintf(stderr, "genuifont: invalid length %d\n", len); + return 0; +} + +static void pack_glyph(struct unifont_glyph *list, FILE *out) +{ + struct unifont_glyph *g = list; + struct unifont_glyph_block *blocks; + uint32_t i = 0; + int table_size = 256; + uint32_t offset = 0; + + blocks = malloc(table_size * sizeof(*blocks)); + if (!blocks) { + fprintf(stderr, "genunifont: out of memory\n"); + return; + } + + blocks[i].len = 0; + blocks[i].offset = 0; + blocks[i].codepoint = g->codepoint; + blocks[i].width = get_width(g->len); + while (g) { + if (blocks[i].width == get_width(g->len) && + g->codepoint == blocks[i].codepoint + blocks[i].len) { + /* This glyph can fit in current block */ + blocks[i].len++; + } else { + /* Start a new block with this glyph as first glyph */ + offset += blocks[i].len * 16 * blocks[i].width; + i++; + if (i >= table_size) { + table_size *= 2; + blocks = realloc(blocks, table_size * sizeof(*blocks)); + if (!blocks) + return; + } + blocks[i].len = 1; + blocks[i].codepoint = g->codepoint; + blocks[i].width = get_width(g->len); + blocks[i].offset = offset; + } + g = g->next; + } + i++; + + // first the length of the blocks table + fwrite(&i, sizeof(i), 1, out); + + // Write the block table + fwrite(blocks, sizeof(*blocks), i, out); + + // Write the glyph data + for (g = list; g; g = g->next) + print_unifont_glyph(out, g); +} + static int parse_single_file(FILE *out, FILE *in) { - static const struct unifont_glyph replacement = { - .codepoint = 0, .len = 32, .data = "0000007E665A5A7A76767E76767E0000"}; char buf[MAX_DATA_SIZE]; struct unifont_glyph *g, **iter, *list, *last; - int ret, num; + int ret; long status_max, status_cur; unsigned long perc_prev, perc_now; @@ -196,19 +257,8 @@ fprintf(stderr, "\b\b\b\b%3d%%\n", 100); - /* print all glyph-data to output file */ - num = 0; - while (list) { - g = list; - list = g->next; - - /* print replacements if glyphs are missing */ - while (num++ < g->codepoint) - print_unifont_glyph(out, &replacement); - - print_unifont_glyph(out, g); - free(g); - } + /* pack into table */ + pack_glyph(list, out); return 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kmscon-9.3.0+git1/src/kmscon_conf.c new/kmscon-9.3.1/src/kmscon_conf.c --- old/kmscon-9.3.0+git1/src/kmscon_conf.c 2026-01-23 09:07:07.000000000 +0100 +++ new/kmscon-9.3.1/src/kmscon_conf.c 2026-02-02 15:44:22.000000000 +0100 @@ -34,6 +34,7 @@ #include <xkbcommon/xkbcommon-keysyms.h> #include "conf.h" #include "kmscon_conf.h" +#include "shl_githead.h" #include "shl_log.h" #include "shl_misc.h" #include "uterm_video.h" @@ -61,7 +62,8 @@ "given multiple times, only the last argument matters if not otherwise stated.\n" "\n" "General Options:\n" - "\t-h, --help [off] Print this help and exit\n" + "\t-h, --help Print this help and exit\n" + "\t-V, --version Print version information and exit\n" "\t-v, --verbose [off] Print verbose messages\n" "\t --debug [off] Enable debug mode\n" "\t --silent [off] Suppress notices and warnings\n" @@ -156,7 +158,7 @@ "\t --use-original-mode [on] Use original KMS video mode\n" "\t --mode <width>x<height> [0x0] Set the desired mode for the\n" "\t output. If the specified mode is\n" - "\t not available or encounterns an\n" + "\t not available or encounters an\n" "\t error, a default mode will be used.\n" "\t This option is incompatible with\n" "\t --use-original-mode.\n" @@ -206,7 +208,7 @@ "\t --palette-light-magenta <color> [255, 0, 255]\n" "\t Light magenta in custom palette\n" "\t --palette-light-cyan <color> [ 0, 255, 255]\n" - "\t Lighty cyan in custom palette\n" + "\t Light cyan in custom palette\n" "\t --palette-white <color> [255, 255, 255]\n" "\t White in custom palette\n" "\t --palette-foreground <color> [229, 229, 229]\n" @@ -561,6 +563,44 @@ print_help(); conf->exit = true; } + return 0; +} +static int aftercheck_version(struct conf_option *opt, int argc, char **argv, int idx) +{ + struct kmscon_conf_t *conf = KMSCON_CONF_FROM_FIELD(opt->mem, version); + + /* exit after printing --version information */ + if (conf->version) { + fprintf(stdout, "kmscon version %s\n", shl_git_head); + + /* print detailed info if verbose mode is enabled */ + if (conf->verbose) { + fprintf(stdout, "Compiled: %s %s\n", __DATE__, __TIME__); + fprintf(stdout, "Build options:\n"); +#ifdef BUILD_ENABLE_VIDEO_DRM2D + fprintf(stdout, " - DRM 2D support: enabled\n"); +#else + fprintf(stdout, " - DRM 2D support: disabled\n"); +#endif +#ifdef BUILD_ENABLE_VIDEO_DRM3D + fprintf(stdout, " - DRM 3D support: enabled\n"); +#else + fprintf(stdout, " - DRM 3D support: disabled\n"); +#endif +#ifdef BUILD_ENABLE_VIDEO_FBDEV + fprintf(stdout, " - FBDEV support: enabled\n"); +#else + fprintf(stdout, " - FBDEV support: disabled\n"); +#endif +#ifdef BUILD_ENABLE_FONT_PANGO + fprintf(stdout, " - Pango font support: enabled\n"); +#else + fprintf(stdout, " - Pango font support: disabled\n"); +#endif + } + + conf->exit = true; + } return 0; } @@ -691,6 +731,8 @@ struct conf_option options[] = { /* Global Options */ CONF_OPTION_BOOL_FULL('h', "help", aftercheck_help, NULL, NULL, &conf->help, false), + CONF_OPTION_BOOL_FULL('V', "version", aftercheck_version, NULL, NULL, + &conf->version, false), CONF_OPTION_BOOL('v', "verbose", &conf->verbose, false), CONF_OPTION_BOOL_FULL(0, "debug", aftercheck_debug, NULL, NULL, &conf->debug, false), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kmscon-9.3.0+git1/src/kmscon_conf.h new/kmscon-9.3.1/src/kmscon_conf.h --- old/kmscon-9.3.0+git1/src/kmscon_conf.h 2026-01-23 09:07:07.000000000 +0100 +++ new/kmscon-9.3.1/src/kmscon_conf.h 2026-02-02 15:44:22.000000000 +0100 @@ -53,6 +53,8 @@ /* General Options */ /* show help/usage information */ bool help; + /* show version information */ + bool version; /* exit application after parsing options */ bool exit; /* enable verbose info messages */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kmscon-9.3.0+git1/src/kmscon_seat.c new/kmscon-9.3.1/src/kmscon_seat.c --- old/kmscon-9.3.0+git1/src/kmscon_seat.c 2026-01-23 09:07:07.000000000 +0100 +++ new/kmscon-9.3.1/src/kmscon_seat.c 2026-02-02 15:44:22.000000000 +0100 @@ -30,6 +30,8 @@ */ #include <errno.h> +#include <signal.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/reboot.h> @@ -567,10 +569,35 @@ static void seat_trigger_reboot(struct kmscon_seat *seat) { - log_warning("reboot triggered by keyboard shortcut on seat %s", seat->name); + FILE *fp; + int ctrl_alt_del = 0; /* Default to soft reboot */ - sync(); /* Synchronize disk buffers */ + /* Read system's ctrl-alt-del behavior setting */ + fp = fopen("/proc/sys/kernel/ctrl-alt-del", "r"); + if (fp) { + if (fscanf(fp, "%d", &ctrl_alt_del) != 1) { + log_warning( + "failed to read ctrl-alt-del setting, defaulting to soft reboot"); + ctrl_alt_del = 0; + } + fclose(fp); + } else { + log_warning("failed to open /proc/sys/kernel/ctrl-alt-del: %m, defaulting to soft " + "reboot"); + } + + /* Soft reboot: signal init to handle graceful restart */ + if (ctrl_alt_del == 0) { + log_warning("soft reboot triggered by keyboard shortcut on seat %s", seat->name); + if (kill(1, SIGINT) < 0) { + log_error("failed to signal PID 1 for reboot: %m"); + } + return; + } + /* Hard reboot: immediate reboot */ + log_warning("hard reboot triggered by keyboard shortcut on seat %s", seat->name); + sync(); /* Synchronize disk buffers */ if (reboot(RB_AUTOBOOT) < 0) { log_error("failed to reboot system: %m"); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kmscon-9.3.0+git1/src/meson.build new/kmscon-9.3.1/src/meson.build --- old/kmscon-9.3.0+git1/src/meson.build 2026-01-23 09:07:07.000000000 +0100 +++ new/kmscon-9.3.1/src/meson.build 2026-02-02 15:44:22.000000000 +0100 @@ -8,7 +8,7 @@ githead = vcs_tag( input: 'shl_githead.c.in', output: 'shl_githead.c', - command: ['git', 'describe'], + command: ['git', 'describe', '--tags'], fallback: 'v' + meson.project_version(), ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kmscon-9.3.0+git1/src/uterm_drm_shared.c new/kmscon-9.3.1/src/uterm_drm_shared.c --- old/kmscon-9.3.0+git1/src/uterm_drm_shared.c 2026-01-23 09:07:07.000000000 +0100 +++ new/kmscon-9.3.1/src/uterm_drm_shared.c 2026-02-02 15:44:22.000000000 +0100 @@ -427,28 +427,47 @@ ddrm->damage_blob_id = 0; } -int uterm_drm_set_dpms(int fd, uint32_t conn_id, int state) +static int uterm_to_drm_dpms(int state) { - int i, ret, set; - drmModeConnector *conn; - drmModePropertyRes *prop; - switch (state) { case UTERM_DPMS_ON: - set = DRM_MODE_DPMS_ON; - break; + return DRM_MODE_DPMS_ON; case UTERM_DPMS_STANDBY: - set = DRM_MODE_DPMS_STANDBY; - break; + return DRM_MODE_DPMS_STANDBY; case UTERM_DPMS_SUSPEND: - set = DRM_MODE_DPMS_SUSPEND; - break; + return DRM_MODE_DPMS_SUSPEND; case UTERM_DPMS_OFF: - set = DRM_MODE_DPMS_OFF; - break; + return DRM_MODE_DPMS_OFF; default: + log_err("Wrong UTERM DPMS value %d", state); return -EINVAL; } +} + +static int drm_to_uterm_dpms(int state) +{ + switch (state) { + case DRM_MODE_DPMS_ON: + return UTERM_DPMS_ON; + case DRM_MODE_DPMS_STANDBY: + return UTERM_DPMS_STANDBY; + case DRM_MODE_DPMS_SUSPEND: + return UTERM_DPMS_SUSPEND; + case DRM_MODE_DPMS_OFF: + default: + return UTERM_DPMS_OFF; + } +} + +static int uterm_drm_set_dpms(int fd, uint32_t conn_id, int state) +{ + int i, ret, set; + drmModeConnector *conn; + drmModePropertyRes *prop; + + set = uterm_to_drm_dpms(state); + if (set < 0) + return set; conn = drmModeGetConnector(fd, conn_id); if (!conn) { @@ -485,7 +504,7 @@ return ret; } -int uterm_drm_get_dpms(int fd, drmModeConnector *conn) +static int uterm_drm_get_dpms(int fd, drmModeConnector *conn) { int i, ret; drmModePropertyRes *prop; @@ -498,45 +517,34 @@ } if (!strcmp(prop->name, "DPMS")) { - switch (conn->prop_values[i]) { - case DRM_MODE_DPMS_ON: - ret = UTERM_DPMS_ON; - break; - case DRM_MODE_DPMS_STANDBY: - ret = UTERM_DPMS_STANDBY; - break; - case DRM_MODE_DPMS_SUSPEND: - ret = UTERM_DPMS_SUSPEND; - break; - case DRM_MODE_DPMS_OFF: - default: - ret = UTERM_DPMS_OFF; - } - + ret = drm_to_uterm_dpms(conn->prop_values[i]); drmModeFreeProperty(prop); return ret; } drmModeFreeProperty(prop); } - - if (i == conn->count_props) - log_warn("display does not support DPMS"); + log_warn("display does not support DPMS"); + /* For drm, UTERM_DPMS_UNKNOWN means unsupported */ return UTERM_DPMS_UNKNOWN; } int uterm_drm_display_set_dpms(struct uterm_display *disp, int state) { - int ret; + int set; struct uterm_drm_display *ddrm = disp->data; struct uterm_drm_video *vdrm = disp->video->data; + set = uterm_to_drm_dpms(state); + + if (disp->dpms == set || disp->dpms == UTERM_DPMS_UNKNOWN) + return 0; + log_info("setting DPMS of display %s to %s\n", disp->name, uterm_dpms_to_name(state)); - ret = uterm_drm_set_dpms(vdrm->fd, ddrm->connector.id, state); - if (ret < 0) - return ret; + if (uterm_drm_set_dpms(vdrm->fd, ddrm->connector.id, state)) + return -EFAULT; - disp->dpms = ret; + disp->dpms = set; return 0; } @@ -673,7 +681,7 @@ disp->flags &= ~DISPLAY_ONLINE; uterm_display_unref(disp); } else - disp->flags |= DISPLAY_ONLINE; + disp->flags |= DISPLAY_ONLINE | DISPLAY_VSYNC; } return ret; } @@ -961,6 +969,27 @@ ev_timer_update(vdrm->vt_timer, &spec); } +static int set_drm_master(struct uterm_drm_video *vdrm) +{ + int ret; + + if (vdrm->master) + return 0; + + ret = drmSetMaster(vdrm->fd); + if (ret) + log_err("Cannot set drm master for %s", vdrm->name); + else + vdrm->master = true; + return ret; +} + +static void drop_drm_master(struct uterm_drm_video *vdrm) +{ + drmDropMaster(vdrm->fd); + vdrm->master = false; +} + int uterm_drm_video_init(struct uterm_video *video, const char *node, const struct display_ops *display_ops, uterm_drm_page_flip_t pflip, void *data) @@ -979,14 +1008,19 @@ vdrm->page_flip = pflip; vdrm->display_ops = display_ops; + vdrm->name = strdup(node); + if (!vdrm->name) { + ret = -ENOMEM; + goto err_free; + } vdrm->fd = open(node, O_RDWR | O_CLOEXEC | O_NONBLOCK); if (vdrm->fd < 0) { log_err("cannot open drm device %s (%d): %m", node, errno); ret = -EFAULT; - goto err_free; + goto err_free_name; } /* TODO: fix the race-condition with DRM-Master-on-open */ - drmDropMaster(vdrm->fd); + drop_drm_master(vdrm); ret = drmSetClientCap(vdrm->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); if (ret) { @@ -1021,6 +1055,8 @@ ev_eloop_rm_fd(vdrm->efd); err_close: close(vdrm->fd); +err_free_name: + free(vdrm->name); err_free: free(vdrm); return ret; @@ -1035,6 +1071,7 @@ shl_timer_free(vdrm->timer); ev_eloop_rm_fd(vdrm->efd); close(vdrm->fd); + free(vdrm->name); free(video->data); } @@ -1117,9 +1154,7 @@ init_modes(disp, conn); ddrm->connector.id = conn->connector_id; - disp->dpms = UTERM_DPMS_ON; - uterm_drm_display_set_dpms(disp, disp->dpms); - + disp->dpms = uterm_drm_get_dpms(vdrm->fd, conn); log_info("display %s DPMS is %s", disp->name, uterm_dpms_to_name(disp->dpms)); /* find a crtc for this connector */ @@ -1178,7 +1213,7 @@ if (!video_is_awake(video) || !video_need_hotplug(video)) return 0; - log_debug("testing DRM hotplug status"); + log_debug("DRM hotplug for device %s", vdrm->name); res = drmModeGetResources(vdrm->fd); if (!res) { @@ -1242,6 +1277,10 @@ if (shl_dlist_empty(&video->displays)) goto finish_hotplug; + ret = set_drm_master(vdrm); + if (ret) + return ret; + if (modeset || new_display) { ret = try_modeset(video); if (ret) @@ -1263,27 +1302,19 @@ int ret; struct uterm_drm_video *vdrm = video->data; - ret = drmSetMaster(vdrm->fd); - if (ret) { - log_err("cannot set DRM-master"); - return -EACCES; - } - video->flags |= VIDEO_AWAKE | VIDEO_HOTPLUG; ret = uterm_drm_video_hotplug(video, true, true); - if (ret) { - drmDropMaster(vdrm->fd); - return ret; - } + if (ret) + drop_drm_master(vdrm); - return 0; + return ret; } void uterm_drm_video_sleep(struct uterm_video *video) { struct uterm_drm_video *vdrm = video->data; - drmDropMaster(vdrm->fd); + drop_drm_master(vdrm); ev_timer_drain(vdrm->vt_timer, NULL); ev_timer_update(vdrm->vt_timer, NULL); } @@ -1310,17 +1341,17 @@ pfd.fd = vdrm->fd; pfd.events = POLLIN; - log_debug("waiting for pageflip on %p", video); + log_debug("waiting for pageflip on %s", vdrm->name); ret = poll(&pfd, 1, *mtimeout); elapsed = shl_timer_stop(vdrm->timer); *mtimeout = *mtimeout - (elapsed / 1000 + 1); if (ret < 0) { - log_error("poll() failed on DRM fd (%d): %m", errno); + log_error("poll() failed on DRM %s fd (%d): %m", vdrm->name, errno); return -EFAULT; } else if (!ret) { - log_warning("timeout waiting for page-flip on %p", video); + log_warning("timeout waiting for page-flip on %s", vdrm->name); return 0; } else if ((pfd.revents & POLLIN)) { ret = uterm_drm_video_read_events(video); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kmscon-9.3.0+git1/src/uterm_drm_shared_internal.h new/kmscon-9.3.1/src/uterm_drm_shared_internal.h --- old/kmscon-9.3.0+git1/src/uterm_drm_shared_internal.h 2026-01-23 09:07:07.000000000 +0100 +++ new/kmscon-9.3.1/src/uterm_drm_shared_internal.h 2026-02-02 15:44:22.000000000 +0100 @@ -44,11 +44,6 @@ uint32_t id; }; -/* drm dpms */ - -int uterm_drm_set_dpms(int fd, uint32_t conn_id, int state); -int uterm_drm_get_dpms(int fd, drmModeConnector *conn); - /* drm display */ struct uterm_drm_display { @@ -91,6 +86,7 @@ typedef void (*uterm_drm_page_flip_t)(struct uterm_display *disp); struct uterm_drm_video { + char *name; int fd; struct ev_fd *efd; uterm_drm_page_flip_t page_flip; @@ -98,6 +94,7 @@ struct shl_timer *timer; struct ev_timer *vt_timer; bool legacy; + bool master; const struct display_ops *display_ops; }; ++++++ kmscon.obsinfo ++++++ --- /var/tmp/diff_new_pack.Vd2IIa/_old 2026-02-06 19:17:51.491085065 +0100 +++ /var/tmp/diff_new_pack.Vd2IIa/_new 2026-02-06 19:17:51.511085912 +0100 @@ -1,5 +1,5 @@ name: kmscon -version: 9.3.0+git1 -mtime: 1769155627 -commit: 24a19ad91c18f0bb4ce95ddc533a116bc1bcad7a +version: 9.3.1 +mtime: 1770043462 +commit: e44ff728e51c5a38b56392abe9bc3e8306db86cc
