vconsole: allow to control font scaling

This adds FONT_SCALE= setting in vconsole.conf,
vconsole.font_scale= kernel command line option and credential support.
When 2 or 200% is specified, the console font size will be doubled.

Closes #43273.
This commit is contained in:
Yu Watanabe
2026-08-25 06:58:06 +09:00
parent 471e34d5cb
commit 2d31e784f1
5 changed files with 104 additions and 14 deletions
+2
View File
@@ -315,11 +315,13 @@
<term><varname>vconsole.font=</varname></term>
<term><varname>vconsole.font_map=</varname></term>
<term><varname>vconsole.font_unimap=</varname></term>
<term><varname>vconsole.font_scale=</varname></term>
<listitem>
<para>Parameters understood by the virtual console setup logic. For details, see
<citerefentry><refentrytitle>vconsole.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
<para><varname>vconsole.font_scale=</varname> was added in version 262.</para>
<xi:include href="version-info.xml" xpointer="v186"/>
</listitem>
</varlistentry>
+2
View File
@@ -85,11 +85,13 @@
<term><varname>vconsole.font</varname></term>
<term><varname>vconsole.font_map</varname></term>
<term><varname>vconsole.font_unimap</varname></term>
<term><varname>vconsole.font_scale</varname></term>
<listitem><para>The console font settings to apply. The matching options in
<filename>vconsole.conf</filename> and on the kernel command line take precedence over these
credentials.</para>
<para><varname>vconsole.font_scale</varname> was added in version 262.</para>
<xi:include href="version-info.xml" xpointer="v253"/></listitem>
</varlistentry>
</variablelist>
+2
View File
@@ -340,10 +340,12 @@
<term><varname>vconsole.font</varname></term>
<term><varname>vconsole.font_map</varname></term>
<term><varname>vconsole.font_unimap</varname></term>
<term><varname>vconsole.font_scale</varname></term>
<listitem>
<para>Console settings to apply, see
<citerefentry><refentrytitle>systemd-vconsole-setup.service</refentrytitle><manvolnum>8</manvolnum></citerefentry> for details.</para>
<para><varname>vconsole.font_scale</varname> was added in version 262.</para>
<xi:include href="version-info.xml" xpointer="v253"/>
</listitem>
</varlistentry>
+21 -5
View File
@@ -49,7 +49,8 @@
<varname>vconsole.keymap_toggle=</varname>,
<varname>vconsole.font=</varname>,
<varname>vconsole.font_map=</varname>,
<varname>vconsole.font_unimap=</varname> may be used
<varname>vconsole.font_unimap=</varname>, and
<varname>vconsole.font_scale=</varname> may be used
to override the console settings at boot.</para>
<para>Depending on the operating system other configuration files
@@ -98,6 +99,18 @@
and the unicode font map.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>FONT_SCALE=</varname></term>
<listitem>
<para>Specifies a font scaling factor. Takes an unsigned value, optionally suffixed with
<literal>%</literal>. Specifying <literal>2</literal> or <literal>200%</literal> doubles the font
size. Currently, only the scaling factors <literal>100%</literal> and <literal>200%</literal> are
supported; other values are clamped to the nearest supported value.</para>
<xi:include href="version-info.xml" xpointer="v262"/>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
@@ -118,15 +131,18 @@
<xi:include href="version-info.xml" xpointer="v232"/></listitem>
</varlistentry>
<varlistentry>
<term><varname>vconsole.font=</varname></term>
<term><varname>vconsole.font_map=</varname></term>
<term><varname>vconsole.font_unimap=</varname></term>
<term><varname>vconsole.font_scale=</varname></term>
<listitem><para>Overrides <varname>FONT=</varname>, <varname>FONT_MAP=</varname>, and
<varname>FONT_UNIMAP=</varname>.</para>
<listitem>
<para>Overrides <varname>FONT=</varname>, <varname>FONT_MAP=</varname>,
<varname>FONT_UNIMAP=</varname>, and <varname>FONT_SCALE=</varname>.</para>
<xi:include href="version-info.xml" xpointer="v232"/></listitem>
<para><varname>vconsole.font_scale=</varname> was added in version 262.</para>
<xi:include href="version-info.xml" xpointer="v232"/>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
+77 -9
View File
@@ -23,6 +23,8 @@
#include "locale-util.h"
#include "log.h"
#include "main-func.h"
#include "parse-util.h"
#include "percent-util.h"
#include "pidref.h"
#include "proc-cmdline.h"
#include "process-util.h"
@@ -38,8 +40,14 @@ typedef struct Context {
char *font;
char *font_map;
char *font_unimap;
int font_scale; /* in percent, negative values mean unset. */
} Context;
#define CONTEXT_NULL \
(Context) { \
.font_scale = -1, \
}
static void context_done(Context *c) {
assert(c);
@@ -71,10 +79,30 @@ static void context_merge_config(
context_merge(dst, src, src_compat, font);
context_merge(dst, src, src_compat, font_map);
context_merge(dst, src, src_compat, font_unimap);
if (src->font_scale >= 0)
dst->font_scale = src->font_scale;
}
static int parse_font_scale(const char *s) {
assert(s);
/* This returns the font scaling in percent. */
unsigned u;
if (safe_atou(s, &u) >= 0) {
/* Here, we use INT_MAX, as parse_percent_unbounded() is bounded by INT_MAX. */
if (u > INT_MAX / 100)
return -ERANGE;
return u * 100;
}
return parse_percent_unbounded(s);
}
static int context_read_efi(Context *c) {
_cleanup_(context_done) Context v = {};
_cleanup_(context_done) Context v = CONTEXT_NULL;
int r;
assert(c);
@@ -92,7 +120,8 @@ static int context_read_efi(Context *c) {
}
static int context_read_creds(Context *c) {
_cleanup_(context_done) Context v = {};
_cleanup_(context_done) Context v = CONTEXT_NULL;
_cleanup_free_ char *font_scale = NULL;
int r;
assert(c);
@@ -102,16 +131,26 @@ static int context_read_creds(Context *c) {
"vconsole.keymap_toggle", &v.keymap_toggle,
"vconsole.font", &v.font,
"vconsole.font_map", &v.font_map,
"vconsole.font_unimap", &v.font_unimap);
"vconsole.font_unimap", &v.font_unimap,
"vconsole.font_scale", &font_scale);
if (r < 0)
log_warning_errno(r, "Failed to import credentials, ignoring: %m");
if (font_scale) {
r = parse_font_scale(font_scale);
if (r < 0)
log_warning_errno(r, "Failed to parse vconsole.font_scale credential, ignoring: %m");
else
v.font_scale = r;
}
context_merge_config(c, &v, NULL);
return 0;
}
static int context_read_env(Context *c) {
_cleanup_(context_done) Context v = {};
_cleanup_(context_done) Context v = CONTEXT_NULL;
_cleanup_free_ char *font_scale = NULL;
int r;
assert(c);
@@ -122,19 +161,29 @@ static int context_read_env(Context *c) {
"KEYMAP_TOGGLE", &v.keymap_toggle,
"FONT", &v.font,
"FONT_MAP", &v.font_map,
"FONT_UNIMAP", &v.font_unimap);
"FONT_UNIMAP", &v.font_unimap,
"FONT_SCALE", &font_scale);
if (r < 0) {
if (r != -ENOENT)
log_warning_errno(r, "Failed to read /etc/vconsole.conf, ignoring: %m");
return r;
}
if (font_scale) {
r = parse_font_scale(font_scale);
if (r < 0)
log_warning_errno(r, "Failed to parse FONT_SCALE= in /etc/vconsole.conf, ignoring: %m");
else
v.font_scale = r;
}
context_merge_config(c, &v, NULL);
return 0;
}
static int context_read_proc_cmdline(Context *c) {
_cleanup_(context_done) Context v = {}, w = {};
_cleanup_(context_done) Context v = CONTEXT_NULL, w = CONTEXT_NULL;
_cleanup_free_ char *font_scale = NULL;
int r;
assert(c);
@@ -146,6 +195,7 @@ static int context_read_proc_cmdline(Context *c) {
"vconsole.font", &v.font,
"vconsole.font_map", &v.font_map,
"vconsole.font_unimap", &v.font_unimap,
"vconsole.font_scale", &font_scale,
/* compatibility with obsolete multiple-dot scheme */
"vconsole.keymap.toggle", &w.keymap_toggle,
"vconsole.font.map", &w.font_map,
@@ -156,6 +206,14 @@ static int context_read_proc_cmdline(Context *c) {
return r;
}
if (font_scale) {
r = parse_font_scale(font_scale);
if (r < 0)
log_warning_errno(r, "Failed to parse vconsole.font_scale from /proc/cmdline, ignoring: %m");
else
v.font_scale = r;
}
context_merge_config(c, &v, &w);
return 0;
}
@@ -354,7 +412,7 @@ static int keyboard_load_and_wait(const char *vc, Context *c, bool utf8) {
}
static int font_load_and_wait(int fd, const char *vc, Context *c) {
const char* args[9];
const char* args[10];
unsigned i = 0;
int r;
@@ -366,8 +424,16 @@ static int font_load_and_wait(int fd, const char *vc, Context *c) {
*font_map = empty_to_null(c->font_map),
*font_unimap = empty_to_null(c->font_unimap);
int font_scale = 100; /* Defaults to 100%, no scaling. */
if (c->font_scale >= 0) {
/* Clamp to the closest value that setfont supports, Currently, only 100% and 200% are supported. */
font_scale = c->font_scale < 150 ? 100 : 200;
if (font_scale != c->font_scale)
log_debug("Font scale %i%% is requested, clamped to %i%%", c->font_scale, font_scale);
}
/* Any part can be set independently */
if (!font && !font_map && !font_unimap)
if (!font && !font_map && !font_unimap && font_scale != 200)
return 0;
if (access(KBD_SETFONT, X_OK) < 0) {
@@ -391,6 +457,8 @@ static int font_load_and_wait(int fd, const char *vc, Context *c) {
args[i++] = KBD_SETFONT;
args[i++] = "-C";
args[i++] = vc;
if (font_scale == 200)
args[i++] = "-d";
if (font_map) {
args[i++] = "-m";
args[i++] = font_map;
@@ -653,7 +721,7 @@ static int verify_source_vc(char **ret_path, const char *src_vc) {
}
static int run(int argc, char **argv) {
_cleanup_(context_done) Context c = {};
_cleanup_(context_done) Context c = CONTEXT_NULL;
_cleanup_free_ char *vc = NULL;
_cleanup_close_ int fd = -EBADF, lock_fd = -EBADF;
bool utf8;