[PATCH 1/5] vt: Add cursor-size helpers
From: Thomas Zimmermann <tzimmermann@suse.de>
Date: 2026-09-11 09:45:37
Also in:
dri-devel, linux-serial, sashiko-reviews
Subsystem:
console subsystem, the rest, tty layer and serial drivers · Maintainers:
Greg Kroah-Hartman, Linus Torvalds, Jiri Slaby
Cursors in the VT subsystem are blocks within a character cell that are filled with the foreground color. The new helpers vc_font_cursor_start() and vc_font_cursor_end() return the scanlines in which the cursor block starts rsp. ends. This is compatible with VGA hardware In terms of cursor design, the new cursor-size helpers follow established styles in fbcon. The only exception is in underline cursors for fonts with a size larger than 10. The underlining dash is now one pixel closer to the font-glyph data, so that the cursor looks less detached. This follows the style used by vgacon. Similar code in vgacon and fbcon ignores the cursor's default size stored in vt.cur_default. The consoles default to full-block cursors, while vt defaults to underline cursors. The new helper fall back to cur_default and then underline cursors; in this order. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> --- drivers/tty/vt/vt.c | 90 ++++++++++++++++++++++++++++++++++ include/linux/console_struct.h | 2 + 2 files changed, 92 insertions(+)
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 8f467b22b799..87c4bc2ef495 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c@@ -264,6 +264,96 @@ unsigned int vc_font_size(const struct vc_font *font) } EXPORT_SYMBOL_GPL(vc_font_size); +static unsigned int vc_cursor_start(unsigned int height, unsigned int cursor_size) +{ +retry: + switch (cursor_size) { + case CUR_NONE: + return height; + case CUR_UNDERLINE: + if (height < 10) + return height - 1; + else + return height - 3; + case CUR_LOWER_THIRD: + return height - height / 3; + case CUR_LOWER_HALF: + return height - height / 2; + case CUR_TWO_THIRDS: + return height - (height * 2) / 3; + case CUR_BLOCK: + return 0; + default: + pr_warn_once("Unknown cursor %u\n", cursor_size); + if (cursor_size != CUR_SIZE(cur_default)) + cursor_size = CUR_SIZE(cur_default); + else + cursor_size = CUR_UNDERLINE; + goto retry; + } +} + +/** + * vc_font_cursor_start - Calculates the cursor's first scanline within a glyph + * @font: The VC font + * @cursor_type: The type of cursor pattern + * + * The parameter @font is an initialized font. The argument in @cursor_type + * is one of the CUR_ constants, as stored in struct @vc_data.vc_cursor_type. For + * unknown values, the helper draws an underline dash. + * + * Returns: + * The index of the cursor's first scanline within the glyph + */ +unsigned int vc_font_cursor_start(const struct vc_font *font, unsigned int cursor_type) +{ + return vc_cursor_start(font->height, CUR_SIZE(cursor_type)); +} +EXPORT_SYMBOL_GPL(vc_font_cursor_start); + +static unsigned int vc_cursor_end(unsigned int height, unsigned int cursor_size) +{ +retry: + switch (cursor_size) { + case CUR_UNDERLINE: + if (height < 10) + return height; + else + return height - 1; + case CUR_NONE: + case CUR_LOWER_THIRD: + case CUR_LOWER_HALF: + case CUR_TWO_THIRDS: + case CUR_BLOCK: + return height; + default: + pr_warn_once("Unknown cursor %u\n", cursor_size); + if (cursor_size != CUR_SIZE(cur_default)) + cursor_size = CUR_SIZE(cur_default); + else + cursor_size = CUR_UNDERLINE; + goto retry; + } +} + +/** + * vc_font_cursor_end - Calculates the first scanline after the cursor within a glyph + * @font: The VC font + * @cursor_type: The type of cursor pattern + * + * The parameter @font is an initialized font. The argument in @cursor_type + * is one of the CUR_ constants, as stored in struct @vc_data.vc_cursor_type. For + * unknown values, the helper draws an underline dash. + * + * Returns: + * The index of the first scanline after the cursor within the glyph + */ +unsigned int vc_font_cursor_end(const struct vc_font *font, unsigned int cursor_type) +{ + return vc_cursor_end(font->height, CUR_SIZE(cursor_type)); +} +EXPORT_SYMBOL_GPL(vc_font_cursor_end); + /* * /sys/class/tty/tty0/ *
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index fe915afdece5..6f30f209e1b0 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h@@ -84,6 +84,8 @@ struct vc_font { unsigned int vc_font_pitch(const struct vc_font *font); unsigned int vc_font_size(const struct vc_font *font); +unsigned int vc_font_cursor_start(const struct vc_font *font, unsigned int cursor_type); +unsigned int vc_font_cursor_end(const struct vc_font *font, unsigned int cursor_type); /* * Example: vc_data of a console that was scrolled 3 lines down.
--
2.55.0