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=&lt;Ctrl&gt;&lt;Alt&gt;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
 

Reply via email to