kbd 2.6.2 Release Notes ------------------------- The kbd-2.6.2 is available at https://mirrors.edge.kernel.org/pub/linux/utils/kbd/kbd-2.6.2.tar.gz https://mirrors.edge.kernel.org/pub/linux/utils/kbd/kbd-2.6.2.tar.xz https://mirrors.edge.kernel.org/pub/linux/utils/kbd/kbd-2.6.2.tar.sign Changes ------- loadkeys: * Don't look for keymap in the current directory. keymaps: * Add colemak mod-dh keymaps. Git repository -------------- git://git.kernel.org/pub/scm/linux/kernel/git/legion/kbd.git Feedback and bug reports, as always, are welcomed. -- Rgrds, legion
kbd 2.6.1 Release Notes ------------------------- The kbd-2.6.1 is available at https://mirrors.edge.kernel.org/pub/linux/utils/kbd/kbd-2.6.1.tar.gz https://mirrors.edge.kernel.org/pub/linux/utils/kbd/kbd-2.6.1.tar.xz https://mirrors.edge.kernel.org/pub/linux/utils/kbd/kbd-2.6.1.tar.sign Changes ------- libkfont: * Fix font saving from linux kernel if KD_FONT_OP_GET_TALL is available. * Respect font height when writing psf2 header. keymaps: * Create new 'mac-fr' layout for contemporary French Macs. Git repository -------------- git://git.kernel.org/pub/scm/linux/kernel/git/legion/kbd.git Feedback and bug reports, as always, are welcomed. -- Rgrds, legion
On Tue, Jun 20, 2023 at 05:10:56AM +0200, stratus@tuta.io wrote: > Further details here: > https://forum.artixlinux.org/index.php/topic,5585.msg35174 > > It seems to originate from this commit: > https://github.com/legionus/kbd/commit/179c45f191b2d1db934ff7f9ea0df202411a78c1 Indeed, this is very similar to the problem that I have already reported: https://github.com/legionus/kbd/issues/94 As far as I understand, when adding support for tall fonts, a regression was made in saving the font to a file. -- Rgrds, legion
Further details here: https://forum.artixlinux.org/index.php/topic,5585.msg35174 It seems to originate from this commit: https://github.com/legionus/kbd/commit/179c45f191b2d1db934ff7f9ea0df202411a78c1
kbd 2.6.0 Release Notes ------------------------- The kbd-2.6.0 is available at https://mirrors.edge.kernel.org/pub/linux/utils/kbd/kbd-2.6.0.tar.gz https://mirrors.edge.kernel.org/pub/linux/utils/kbd/kbd-2.6.0.tar.xz https://mirrors.edge.kernel.org/pub/linux/utils/kbd/kbd-2.6.0.tar.sign Changes ------- libkfont: * Leverage KD_FONT_OP_GET/SET_TALL font operations. The new KD_FONT_OP_GET/SET_TALL font operations allow to load fonts taller than 32 pixels by dropping the VGA-specific vertical pitch limitation (requires kernel 6.2 or later). * Use threadsafe strtok_r. * Increase soname version. setvtrgb: * Fix read from pipe. The pipe is not rewindable, but we don't really need to rewind() but we need to unread one character. keymaps: * i386/dvorak/dvorak-de.map: Add dvorak-de.map from console-data. * i386/qwerty/is-latin1.map: the circumflex should also be available in its original level-3 position. * i386/qwerty/la-latin1.map: Convert the characters expressed in Latin-1 to the named constants, to ease up transition to Unicode. * pine/en.map: New version of pinephone keyboard map file. unimaps: * Add mapping for U+25CF. The unicode maps in font files like eurlatgr.psfu and cp850-8x16.psfu have an entry for U+25CF, but the plaintext unimap files do not. tests: * Use strace to track syscalls. Now strace is powerful enough to show ioctls specific to console configuration. po: * Update translations (from translationproject.org). Git repository -------------- git://git.kernel.org/pub/scm/linux/kernel/git/legion/kbd.git Feedback and bug reports, as always, are welcomed. -- Rgrds, legion
kbd 2.6-rc1 Release Notes ------------------------- The kbd-2.6-rc1 is available at https://mirrors.edge.kernel.org/pub/linux/utils/kbd/kbd-2.6-rc1.tar.gz https://mirrors.edge.kernel.org/pub/linux/utils/kbd/kbd-2.6-rc1.tar.xz https://mirrors.edge.kernel.org/pub/linux/utils/kbd/kbd-2.6-rc1.tar.sign Changes ------- libkfont: * Leverage KD_FONT_OP_GET/SET_TALL font operations. The new KD_FONT_OP_GET/SET_TALL font operations allow to load fonts taller than 32 pixels by dropping the VGA-specific vertical pitch limitation (requires kernel 6.2 or later). * Use threadsafe strtok_r. * Increase soname version. setvtrgb: * Fix read from pipe. The pipe is not rewindable, but we don't really need to rewind() but we need to unread one character. keymaps: * i386/dvorak/dvorak-de.map: Add dvorak-de.map from console-data. * i386/qwerty/is-latin1.map: the circumflex should also be available in its original level-3 position. * i386/qwerty/la-latin1.map: Convert the characters expressed in Latin-1 to the named constants, to ease up transition to Unicode. * pine/en.map: New version of pinephone keyboard map file. unimaps: * Add mapping for U+25CF. The unicode maps in font files like eurlatgr.psfu and cp850-8x16.psfu have an entry for U+25CF, but the plaintext unimap files do not. tests: * Use strace to track syscalls. Now strace is powerful enough to show ioctls specific to console configuration. Git repository -------------- git://git.kernel.org/pub/scm/linux/kernel/git/legion/kbd.git Feedback and bug reports, as always, are welcomed. -- Rgrds, legion
On Thu, Jan 19, 2023 at 04:19:14PM +0100, Samuel Thibault wrote:
> Hello,
>
> This patch series adds to Linux and kbd the support for fonts larger than 32x32
> by dropping the oldish VGA constraints that don't apply to fb-based consoles.
>
> The change from v2 is only to completely drop the sisusb part, so that it
> applies cleanly e.g. on latest Linus' tree.
That was fast, thanks!!! I'll go queue this up now.
Greg KH, le jeu. 19 janv. 2023 16:09:10 +0100, a ecrit:
> On Sun, Dec 18, 2022 at 01:32:10AM +0100, Samuel Thibault wrote:
> > Index: linux-6.0/drivers/tty/vt/vt.c
>
> 6.0 was really old when you sent this, and because of that:
>
> > Index: linux-6.0/drivers/usb/misc/sisusbvga/sisusb_con.c
> > ===================================================================
>
> This file is not even in the tree anymore.
>
> Can you rebase this against 6.2-rc4 and resubmit it so that I can apply
> it? As-is, it will not apply at all :(
Right, I have rebased on top of Linus' tree, v3 should now apply fine.
Thanks,
Samuel
This moves 32x32 font size limitation checking down to drivers, so that fbcon can allow large fonts. We still keep a limitation to 64x128 pixels so as to have a simple bounded allocation for con_font_get and in the userland kbd tool. That glyph size will however be enough to have 128x36 characters on a "16/9 8K display". Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org> --- V1 -> V2: Switch con_font_get to kvmalloc/kvfree instead of kmalloc/kfree V1 -> V3: Drop sisusb_con.c change, it was phased out Index: linux-6.0/drivers/tty/vt/vt.c =================================================================== --- linux-6.0.orig/drivers/tty/vt/vt.c +++ linux-6.0/drivers/tty/vt/vt.c @@ -4575,17 +4575,20 @@ void reset_palette(struct vc_data *vc) /* * Font switching * - * Currently we only support fonts up to 32 pixels wide, at a maximum height - * of 32 pixels. Userspace fontdata is stored with 32 bytes (shorts/ints, - * depending on width) reserved for each character which is kinda wasty, but - * this is done in order to maintain compatibility with the EGA/VGA fonts. It - * is up to the actual low-level console-driver convert data into its favorite - * format (maybe we should add a `fontoffset' field to the `display' - * structure so we won't have to convert the fontdata all the time. + * Currently we only support fonts up to 128 pixels wide, at a maximum height + * of 128 pixels. Userspace fontdata may have to be stored with 32 bytes + * (shorts/ints, depending on width) reserved for each character which is + * kinda wasty, but this is done in order to maintain compatibility with the + * EGA/VGA fonts. It is up to the actual low-level console-driver convert data + * into its favorite format (maybe we should add a `fontoffset' field to the + * `display' structure so we won't have to convert the fontdata all the time. * /Jes */ -#define max_font_size 65536 +#define max_font_width 64 +#define max_font_height 128 +#define max_font_glyphs 512 +#define max_font_size (max_font_glyphs*max_font_width*max_font_height) static int con_font_get(struct vc_data *vc, struct console_font_op *op) { @@ -4595,7 +4598,7 @@ static int con_font_get(struct vc_data * unsigned int vpitch = op->op == KD_FONT_OP_GET_TALL ? op->height : 32; if (op->data) { - font.data = kmalloc(max_font_size, GFP_KERNEL); + font.data = kvmalloc(max_font_size, GFP_KERNEL); if (!font.data) return -ENOMEM; } else @@ -4630,7 +4633,7 @@ static int con_font_get(struct vc_data * rc = -EFAULT; out: - kfree(font.data); + kvfree(font.data); return rc; } @@ -4645,9 +4648,10 @@ static int con_font_set(struct vc_data * return -EINVAL; if (!op->data) return -EINVAL; - if (op->charcount > 512) + if (op->charcount > max_font_glyphs) return -EINVAL; - if (op->width <= 0 || op->width > 32 || !op->height || op->height > 32) + if (op->width <= 0 || op->width > max_font_width || !op->height || + op->height > max_font_height) return -EINVAL; if (vpitch < op->height) return -EINVAL; Index: linux-6.0/drivers/video/console/vgacon.c =================================================================== --- linux-6.0.orig/drivers/video/console/vgacon.c +++ linux-6.0/drivers/video/console/vgacon.c @@ -1037,7 +1037,7 @@ static int vgacon_font_set(struct vc_dat if (vga_video_type < VIDEO_TYPE_EGAM) return -EINVAL; - if (font->width != VGA_FONTWIDTH || vpitch != 32 || + if (font->width != VGA_FONTWIDTH || font->height > 32 || vpitch != 32 || (charcount != 256 && charcount != 512)) return -EINVAL; Index: linux-6.0/drivers/video/fbdev/core/fbcon.c =================================================================== --- linux-6.0.orig/drivers/video/fbdev/core/fbcon.c +++ linux-6.0/drivers/video/fbdev/core/fbcon.c @@ -2279,6 +2279,8 @@ static int fbcon_get_font(struct vc_data font->width = vc->vc_font.width; font->height = vc->vc_font.height; + if (font->height > vpitch) + return -ENOSPC; font->charcount = vc->vc_hi_font_mask ? 512 : 256; if (!font->data) return 0;
The KD_FONT_OP_SET/GET operations hardcode vpitch to be 32 pixels, which only dates from the old VGA hardware which as asserting this. Drivers such as fbcon however do not have such limitation, so this introduces KD_FONT_OP_SET/GET_TALL operations, which userland can try to use to avoid this limitation, thus opening the patch to >32 pixels font height. Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org> Index: linux-6.0/drivers/tty/vt/vt.c =================================================================== --- linux-6.0.orig/drivers/tty/vt/vt.c +++ linux-6.0/drivers/tty/vt/vt.c @@ -4592,6 +4592,7 @@ static int con_font_get(struct vc_data * struct console_font font; int rc = -EINVAL; int c; + unsigned int vpitch = op->op == KD_FONT_OP_GET_TALL ? op->height : 32; if (op->data) { font.data = kmalloc(max_font_size, GFP_KERNEL); @@ -4604,7 +4605,7 @@ static int con_font_get(struct vc_data * if (vc->vc_mode != KD_TEXT) rc = -EINVAL; else if (vc->vc_sw->con_font_get) - rc = vc->vc_sw->con_font_get(vc, &font, 32); + rc = vc->vc_sw->con_font_get(vc, &font, vpitch); else rc = -ENOSYS; console_unlock(); @@ -4612,7 +4613,7 @@ static int con_font_get(struct vc_data * if (rc) goto out; - c = (font.width+7)/8 * 32 * font.charcount; + c = (font.width+7)/8 * vpitch * font.charcount; if (op->data && font.charcount > op->charcount) rc = -ENOSPC; @@ -4638,6 +4639,7 @@ static int con_font_set(struct vc_data * struct console_font font; int rc = -EINVAL; int size; + unsigned int vpitch = op->op == KD_FONT_OP_SET_TALL ? op->height : 32; if (vc->vc_mode != KD_TEXT) return -EINVAL; @@ -4647,7 +4649,9 @@ static int con_font_set(struct vc_data * return -EINVAL; if (op->width <= 0 || op->width > 32 || !op->height || op->height > 32) return -EINVAL; - size = (op->width+7)/8 * 32 * op->charcount; + if (vpitch < op->height) + return -EINVAL; + size = (op->width+7)/8 * vpitch * op->charcount; if (size > max_font_size) return -ENOSPC; @@ -4665,7 +4669,7 @@ static int con_font_set(struct vc_data * else if (vc->vc_sw->con_font_set) { if (vc_is_sel(vc)) clear_selection(); - rc = vc->vc_sw->con_font_set(vc, &font, 32, op->flags); + rc = vc->vc_sw->con_font_set(vc, &font, vpitch, op->flags); } else rc = -ENOSYS; console_unlock(); @@ -4711,8 +4715,10 @@ int con_font_op(struct vc_data *vc, stru { switch (op->op) { case KD_FONT_OP_SET: + case KD_FONT_OP_SET_TALL: return con_font_set(vc, op); case KD_FONT_OP_GET: + case KD_FONT_OP_GET_TALL: return con_font_get(vc, op); case KD_FONT_OP_SET_DEFAULT: return con_font_default(vc, op); Index: linux-6.0/include/uapi/linux/kd.h =================================================================== --- linux-6.0.orig/include/uapi/linux/kd.h +++ linux-6.0/include/uapi/linux/kd.h @@ -161,19 +161,25 @@ struct console_font_op { unsigned int flags; /* KD_FONT_FLAG_* */ unsigned int width, height; /* font size */ unsigned int charcount; - unsigned char __user *data; /* font data with height fixed to 32 */ + unsigned char __user *data; /* font data with vpitch fixed to 32 for + * KD_FONT_OP_SET/GET + */ }; struct console_font { unsigned int width, height; /* font size */ unsigned int charcount; - unsigned char *data; /* font data with height fixed to 32 */ + unsigned char *data; /* font data with vpitch fixed to 32 for + * KD_FONT_OP_SET/GET + */ }; #define KD_FONT_OP_SET 0 /* Set font */ #define KD_FONT_OP_GET 1 /* Get font */ #define KD_FONT_OP_SET_DEFAULT 2 /* Set font to default, data points to name / NULL */ #define KD_FONT_OP_COPY 3 /* Obsolete, do not use */ +#define KD_FONT_OP_SET_TALL 4 /* Set font with vpitch = height */ +#define KD_FONT_OP_GET_TALL 5 /* Get font with vpitch = height */ #define KD_FONT_FLAG_DONT_RECALC 1 /* Don't recalculate hw charcell size [compat] */
The current con_font_get/set API currently hardcodes a 32-pixel-tall limitation, which only dates from the old VGA hardware which could not handle taller fonts than that. This change just adds a vpitch parameter to release this constraint. Drivers which do not support vpitch != 32 can just return EINVAL when it is not 32, font loading tools will revert to trying 32 and succeed. This change makes the fbcon driver consider vpitch appropriately, thus making it able to load large fonts. Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org> --- V1 -> V3: Drop (bogus) sisusb_con.c change, it was phased out Index: linux-6.0/drivers/tty/vt/vt.c =================================================================== --- linux-6.0.orig/drivers/tty/vt/vt.c +++ linux-6.0/drivers/tty/vt/vt.c @@ -4604,7 +4604,7 @@ static int con_font_get(struct vc_data * if (vc->vc_mode != KD_TEXT) rc = -EINVAL; else if (vc->vc_sw->con_font_get) - rc = vc->vc_sw->con_font_get(vc, &font); + rc = vc->vc_sw->con_font_get(vc, &font, 32); else rc = -ENOSYS; console_unlock(); @@ -4665,7 +4665,7 @@ static int con_font_set(struct vc_data * else if (vc->vc_sw->con_font_set) { if (vc_is_sel(vc)) clear_selection(); - rc = vc->vc_sw->con_font_set(vc, &font, op->flags); + rc = vc->vc_sw->con_font_set(vc, &font, 32, op->flags); } else rc = -ENOSYS; console_unlock(); Index: linux-6.0/drivers/video/console/vgacon.c =================================================================== --- linux-6.0.orig/drivers/video/console/vgacon.c +++ linux-6.0/drivers/video/console/vgacon.c @@ -1029,7 +1029,7 @@ static int vgacon_adjust_height(struct v } static int vgacon_font_set(struct vc_data *c, struct console_font *font, - unsigned int flags) + unsigned int vpitch, unsigned int flags) { unsigned charcount = font->charcount; int rc; @@ -1037,7 +1037,7 @@ static int vgacon_font_set(struct vc_dat if (vga_video_type < VIDEO_TYPE_EGAM) return -EINVAL; - if (font->width != VGA_FONTWIDTH || + if (font->width != VGA_FONTWIDTH || vpitch != 32 || (charcount != 256 && charcount != 512)) return -EINVAL; @@ -1050,9 +1050,9 @@ static int vgacon_font_set(struct vc_dat return rc; } -static int vgacon_font_get(struct vc_data *c, struct console_font *font) +static int vgacon_font_get(struct vc_data *c, struct console_font *font, unsigned int vpitch) { - if (vga_video_type < VIDEO_TYPE_EGAM) + if (vga_video_type < VIDEO_TYPE_EGAM || vpitch != 32) return -EINVAL; font->width = VGA_FONTWIDTH; Index: linux-6.0/drivers/video/fbdev/core/fbcon.c =================================================================== --- linux-6.0.orig/drivers/video/fbdev/core/fbcon.c +++ linux-6.0/drivers/video/fbdev/core/fbcon.c @@ -2271,7 +2271,7 @@ static int fbcon_debug_leave(struct vc_d return 0; } -static int fbcon_get_font(struct vc_data *vc, struct console_font *font) +static int fbcon_get_font(struct vc_data *vc, struct console_font *font, unsigned int vpitch) { u8 *fontdata = vc->vc_font.data; u8 *data = font->data; @@ -2290,8 +2290,8 @@ static int fbcon_get_font(struct vc_data for (i = 0; i < font->charcount; i++) { memcpy(data, fontdata, j); - memset(data + j, 0, 32 - j); - data += 32; + memset(data + j, 0, vpitch - j); + data += vpitch; fontdata += j; } } else if (font->width <= 16) { @@ -2301,8 +2301,8 @@ static int fbcon_get_font(struct vc_data for (i = 0; i < font->charcount; i++) { memcpy(data, fontdata, j); - memset(data + j, 0, 64 - j); - data += 64; + memset(data + j, 0, 2*vpitch - j); + data += 2*vpitch; fontdata += j; } } else if (font->width <= 24) { @@ -2316,8 +2316,8 @@ static int fbcon_get_font(struct vc_data *data++ = fontdata[2]; fontdata += sizeof(u32); } - memset(data, 0, 3 * (32 - j)); - data += 3 * (32 - j); + memset(data, 0, 3 * (vpitch - j)); + data += 3 * (vpitch - j); } } else { j = vc->vc_font.height * 4; @@ -2326,8 +2326,8 @@ static int fbcon_get_font(struct vc_data for (i = 0; i < font->charcount; i++) { memcpy(data, fontdata, j); - memset(data + j, 0, 128 - j); - data += 128; + memset(data + j, 0, 4 * vpitch - j); + data += 4 * vpitch; fontdata += j; } } @@ -2461,19 +2461,12 @@ err_out: } /* - * User asked to set font; we are guaranteed that - * a) width and height are in range 1..32 - * b) charcount does not exceed 512 - * but lets not assume that, since someone might someday want to use larger - * fonts. And charcount of 512 is small for unicode support. - * - * However, user space gives the font in 32 rows , regardless of - * actual font height. So a new API is needed if support for larger fonts - * is ever implemented. + * User asked to set font; we are guaranteed that charcount does not exceed 512 + * but lets not assume that, since charcount of 512 is small for unicode support. */ static int fbcon_set_font(struct vc_data *vc, struct console_font *font, - unsigned int flags) + unsigned int vpitch, unsigned int flags) { struct fb_info *info = fbcon_info_from_console(vc->vc_num); unsigned charcount = font->charcount; @@ -2516,7 +2509,7 @@ static int fbcon_set_font(struct vc_data FNTSIZE(new_data) = size; REFCOUNT(new_data) = 0; /* usage counter */ for (i=0; i< charcount; i++) { - memcpy(new_data + i*h*pitch, data + i*32*pitch, h*pitch); + memcpy(new_data + i*h*pitch, data + i*vpitch*pitch, h*pitch); } /* Since linux has a nice crc32 function use it for counting font Index: linux-6.0/include/linux/console.h =================================================================== --- linux-6.0.orig/include/linux/console.h +++ linux-6.0/include/linux/console.h @@ -58,8 +58,9 @@ struct consw { int (*con_switch)(struct vc_data *vc); int (*con_blank)(struct vc_data *vc, int blank, int mode_switch); int (*con_font_set)(struct vc_data *vc, struct console_font *font, - unsigned int flags); - int (*con_font_get)(struct vc_data *vc, struct console_font *font); + unsigned int vpitch, unsigned int flags); + int (*con_font_get)(struct vc_data *vc, struct console_font *font, + unsigned int vpitch); int (*con_font_default)(struct vc_data *vc, struct console_font *font, char *name); int (*con_resize)(struct vc_data *vc, unsigned int width, Index: linux-6.0/drivers/video/console/newport_con.c =================================================================== --- linux-6.0.orig/drivers/video/console/newport_con.c +++ linux-6.0/drivers/video/console/newport_con.c @@ -497,7 +497,7 @@ static int newport_blank(struct vc_data return 1; } -static int newport_set_font(int unit, struct console_font *op) +static int newport_set_font(int unit, struct console_font *op, unsigned int vpitch) { int w = op->width; int h = op->height; @@ -507,7 +507,7 @@ static int newport_set_font(int unit, st /* ladis: when I grow up, there will be a day... and more sizes will * be supported ;-) */ - if ((w != 8) || (h != 16) + if ((w != 8) || (h != 16) || (vpitch != 32) || (op->charcount != 256 && op->charcount != 512)) return -EINVAL; @@ -569,9 +569,10 @@ static int newport_font_default(struct v return newport_set_def_font(vc->vc_num, op); } -static int newport_font_set(struct vc_data *vc, struct console_font *font, unsigned flags) +static int newport_font_set(struct vc_data *vc, struct console_font *font, + unsigned int vpitch, unsigned int flags) { - return newport_set_font(vc->vc_num, font); + return newport_set_font(vc->vc_num, font, vpitch); } static bool newport_scroll(struct vc_data *vc, unsigned int t, unsigned int b, Index: linux-6.0/drivers/video/console/sticon.c =================================================================== --- linux-6.0.orig/drivers/video/console/sticon.c +++ linux-6.0/drivers/video/console/sticon.c @@ -169,7 +169,8 @@ static int sticon_set_def_font(int unit, return 0; } -static int sticon_set_font(struct vc_data *vc, struct console_font *op) +static int sticon_set_font(struct vc_data *vc, struct console_font *op, + unsigned int vpitch) { struct sti_struct *sti = sticon_sti; int vc_cols, vc_rows, vc_old_cols, vc_old_rows; @@ -181,7 +182,7 @@ static int sticon_set_font(struct vc_dat struct sti_cooked_font *cooked_font; unsigned char *data = op->data, *p; - if ((w < 6) || (h < 6) || (w > 32) || (h > 32) + if ((w < 6) || (h < 6) || (w > 32) || (h > 32) || (vpitch != 32) || (op->charcount != 256 && op->charcount != 512)) return -EINVAL; pitch = ALIGN(w, 8) / 8; @@ -267,9 +268,9 @@ static int sticon_font_default(struct vc } static int sticon_font_set(struct vc_data *vc, struct console_font *font, - unsigned int flags) + unsigned int vpitch, unsigned int flags) { - return sticon_set_font(vc, font); + return sticon_set_font(vc, font, vpitch); } static void sticon_init(struct vc_data *c, int init)
Hello, This patch series adds to Linux and kbd the support for fonts larger than 32x32 by dropping the oldish VGA constraints that don't apply to fb-based consoles. The change from v2 is only to completely drop the sisusb part, so that it applies cleanly e.g. on latest Linus' tree. Samuel
On Sun, Dec 18, 2022 at 01:32:10AM +0100, Samuel Thibault wrote: > The current con_font_get/set API currently hardcodes a 32-pixel-tall > limitation, which only dates from the old VGA hardware which could not > handle taller fonts than that. > > This change just adds a vpitch parameter to release this > constraint. Drivers which do not support vpitch != 32 can just return > EINVAL when it is not 32, font loading tools will revert to trying 32 > and succeed. > > This change makes the fbcon driver consider vpitch appropriately, thus > making it able to load large fonts. > > Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org> > > --- > V1 -> V2: Drop (bogus) sisusb_con.c change, it is being phased out > > Index: linux-6.0/drivers/tty/vt/vt.c 6.0 was really old when you sent this, and because of that: > Index: linux-6.0/drivers/usb/misc/sisusbvga/sisusb_con.c > =================================================================== This file is not even in the tree anymore. Can you rebase this against 6.2-rc4 and resubmit it so that I can apply it? As-is, it will not apply at all :( thanks, greg k-h
On Sun, Dec 18, 2022 at 04:38:33PM +0100, Alexey Gladkov wrote:
> On Sun, Dec 18, 2022 at 04:28:57PM +0100, Samuel Thibault wrote:
> > Alexey Gladkov, le dim. 18 déc. 2022 16:25:01 +0100, a ecrit:
> > > On Sun, Dec 18, 2022 at 03:55:32PM +0100, Samuel Thibault wrote:
> > > > Alexey Gladkov, le dim. 18 déc. 2022 15:39:38 +0100, a ecrit:
> > > > > On Sun, Dec 18, 2022 at 01:32:12AM +0100, Samuel Thibault wrote:
> > > > > > -#define max_font_size 65536
> > > > > > +#define max_font_width 64
> > > > > > +#define max_font_height 128
> > > > > > +#define max_font_glyphs 512
> > > > > > +#define max_font_size (max_font_glyphs*max_font_width*max_font_height)
> > > > >
> > > > > As a suggestion that you can safely ignore. Maybe make max_font_glyphs a
> > > > > sysctl parameter to be able to use larger fonts ?
> > > > >
> > > > > I get requests from time to time in kbd that it is not possible to load a
> > > > > larger font.
> > > >
> > > > 64KiB was really low, while the theoretically possible max was
> > > > 32*32*512 = 512KB, so I understand there used to be such requests :)
> > > >
> > > > Here, by setting the max to 64x128*512, I don't think we'll need more.
> > >
> > > I was not talking about the size of one glyph, but about the number of
> > > glyphs in the font. Right now the font cannot have more than 512 glyphs.
> >
> > That one is unfortunately *very* hardcoded in the VT code, since it's
> > the very representation of the console text in vc_screenbuf which is set
> > to the VGA-based 16bits per glyph, with a 8+8 or 9+7 separation between
> > glyph number and color number. Lifting that would be way more involved.
>
> Yeah, but I thought that since someone decided to touch this old code,
> then this someone will improve this old limit :)
That's fine, but it would be a separate change, not this one.
thanks,
greg k-h
On Tue, Jan 10, 2023 at 09:55:36PM +0100, Samuel Thibault wrote: > Hello, > > Ping, is there anything to be done on this? The patches look good to me. I will apply a userspace patch once the kernel part is applied. > Samuel > > Samuel Thibault, le dim. 18 déc. 2022 01:32:09 +0100, a ecrit: > > Hello, > > > > This patch series adds to Linux and kbd the support for fonts larger than 32x32 > > by dropping the oldish VGA constraints that don't apply to fb-based consoles. > > > > Samuel > _______________________________________________ > kbd mailing list > kbd@lists.altlinux.org > https://lists.altlinux.org/mailman/listinfo/kbd -- Rgrds, legion
The new KD_FONT_OP_GET/SET_TALL font operations allow to load fonts taller than 32 pixels by dropping the VGA-specific vertical pitch limitation. The new maximum font size has thus been raised to 64x128. We however continue using the older font operations for smaller fonts, to continue supporting older kernels. Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org> Index: kbd-2.5.1/src/compat/linux-kd.h =================================================================== --- kbd-2.5.1.orig/src/compat/linux-kd.h +++ kbd-2.5.1/src/compat/linux-kd.h @@ -90,7 +90,8 @@ struct console_font_op { unsigned int flags; /* KD_FONT_FLAG_* */ unsigned int width, height; unsigned int charcount; - unsigned char *data; /* font data with height fixed to 32 */ + unsigned char *data; /* font data with vpitch fixed to 32 for + * KD_FONT_OP_SET/GET */ }; #define KD_FONT_OP_SET 0 /* Set font */ @@ -98,6 +99,8 @@ struct console_font_op { #define KD_FONT_OP_SET_DEFAULT 2 /* Set font to default, \ data points to name / NULL */ #define KD_FONT_OP_COPY 3 /* Copy from another console */ +#define KD_FONT_OP_SET_TALL 4 /* Set font with arbitrary vpitch */ +#define KD_FONT_OP_GET_TALL 5 /* Get font with arbitrary vpitch */ #define KD_FONT_FLAG_OLD 0x80000000 /* Invoked via old interface */ #define KD_FONT_FLAG_DONT_RECALC 1 /* Don't call adjust_height() */ Index: kbd-2.5.1/src/libkfont/kdfontop.c =================================================================== --- kbd-2.5.1.orig/src/libkfont/kdfontop.c +++ kbd-2.5.1/src/libkfont/kdfontop.c @@ -51,19 +51,33 @@ get_font_kdfontop(struct kfont_context * unsigned char *buf, unsigned int *count, unsigned int *width, - unsigned int *height) + unsigned int *height, + unsigned int *vpitch) { struct console_font_op cfo; +#ifdef KD_FONT_OP_GET_TALL + cfo.op = KD_FONT_OP_GET_TALL; +#else cfo.op = KD_FONT_OP_GET; +#endif cfo.flags = 0; - cfo.width = cfo.height = 32; + cfo.width = 64; + cfo.height = 128; cfo.charcount = *count; cfo.data = buf; +retry: errno = 0; if (ioctl(consolefd, KDFONTOP, &cfo)) { +#ifdef KD_FONT_OP_GET_TALL + if (errno == ENOSYS && cfo.op == KD_FONT_OP_GET_TALL) { + /* Kernel before 6.2. */ + cfo.op = KD_FONT_OP_GET; + goto retry; + } +#endif if (errno != ENOSYS && errno != EINVAL) { KFONT_ERR(ctx, "ioctl(KDFONTOP): %m"); return -1; @@ -76,6 +90,14 @@ get_font_kdfontop(struct kfont_context * *height = cfo.height; if (width) *width = cfo.width; + if (vpitch) { +#ifdef KD_FONT_OP_GET_TALL + if (cfo.op == KD_FONT_OP_GET_TALL) + *vpitch = cfo.height; + else +#endif + *vpitch = 32; + } return 0; } @@ -88,16 +110,17 @@ int kfont_get_font(struct kfont_context *ctx, int fd, unsigned char *buf, unsigned int *count, unsigned int *width, - unsigned int *height) + unsigned int *height, + unsigned int *vpitch) { - return get_font_kdfontop(ctx, fd, buf, count, width, height); + return get_font_kdfontop(ctx, fd, buf, count, width, height, vpitch); } int unsigned kfont_get_fontsize(struct kfont_context *ctx, int fd) { unsigned int count = 0; - if (!kfont_get_font(ctx, fd, NULL, &count, NULL, NULL)) + if (!kfont_get_font(ctx, fd, NULL, &count, NULL, NULL, NULL)) return count; return 256; } @@ -106,11 +129,20 @@ static int put_font_kdfontop(struct kfont_context *ctx, int consolefd, unsigned char *buf, unsigned int count, unsigned int width, - unsigned int height) + unsigned int height, + unsigned int vpitch) { struct console_font_op cfo; - cfo.op = KD_FONT_OP_SET; + if (vpitch == 32 && width <= 32) + cfo.op = KD_FONT_OP_SET; + else { +#ifdef KD_FONT_OP_SET_TALL + cfo.op = KD_FONT_OP_SET_TALL; +#else + return 0; +#endif + } cfo.flags = 0; cfo.width = width; cfo.height = height; @@ -122,8 +154,14 @@ put_font_kdfontop(struct kfont_context * if (!ioctl(consolefd, KDFONTOP, &cfo)) return 0; - if (errno == ENOSYS) + if (errno == ENOSYS) { +#ifdef KD_FONT_OP_SET_TALL + if (cfo.op == KD_FONT_OP_SET_TALL) + /* Let user know that we can't load such font with such kernel version */ + return 0; +#endif return 1; + } int ret = -1; @@ -154,7 +192,7 @@ put_font_kdfontop(struct kfont_context * int kfont_put_font(struct kfont_context *ctx, int fd, unsigned char *buf, unsigned int count, - unsigned int width, unsigned int height) + unsigned int width, unsigned int height, unsigned int vpitch) { if (!width) width = 8; @@ -162,5 +200,5 @@ kfont_put_font(struct kfont_context *ctx if (!height) height = font_charheight(buf, count, width); - return put_font_kdfontop(ctx, fd, buf, count, width, height); + return put_font_kdfontop(ctx, fd, buf, count, width, height, vpitch); } Index: kbd-2.5.1/src/libkfont/kfont.h =================================================================== --- kbd-2.5.1.orig/src/libkfont/kfont.h +++ kbd-2.5.1/src/libkfont/kfont.h @@ -171,7 +171,8 @@ int kfont_load_unicodemap(struct kfont_c * Sets number of glyphs in COUNT, glyph size in WIDTH and HEIGHT. */ int kfont_get_font(struct kfont_context *ctx, int consolefd, unsigned char *buf, - unsigned int *count, unsigned int *width, unsigned int *height) + unsigned int *count, unsigned int *width, unsigned int *height, + unsigned int *vpitch) __attribute__((nonnull(1))); /* @@ -180,7 +181,8 @@ int kfont_get_font(struct kfont_context * Return 0 on success, -1 on failure. */ int kfont_put_font(struct kfont_context *ctx, int consolefd, unsigned char *buf, - unsigned int count, unsigned int width, unsigned int height) + unsigned int count, unsigned int width, unsigned int height, + unsigned int vpitch) __attribute__((nonnull(1))); /* @@ -239,7 +241,7 @@ void kfont_disactivatemap(int fd); #include <stdio.h> /* Maximum font size that we try to handle */ -#define MAXFONTSIZE 65536 +#define MAXFONTSIZE (512*64*128) /** * readpsffont reads a PSF font. Index: kbd-2.5.1/src/libkfont/setfont.c =================================================================== --- kbd-2.5.1.orig/src/libkfont/setfont.c +++ kbd-2.5.1/src/libkfont/setfont.c @@ -45,8 +45,9 @@ findpartialfont(struct kfont_context *ct static int erase_mode = 1; static int -do_loadfont(struct kfont_context *ctx, int fd, const unsigned char *inbuf, - unsigned int width, unsigned int height, unsigned int hwunit, +try_loadfont(struct kfont_context *ctx, int fd, const unsigned char *inbuf, + unsigned int width, unsigned int height, unsigned int vpitch, + unsigned int hwunit, unsigned int fontsize, const char *filename) { unsigned char *buf = NULL; @@ -54,13 +55,13 @@ do_loadfont(struct kfont_context *ctx, i int bad_video_erase_char = 0; int ret; - if (height < 1 || height > 32) { - KFONT_ERR(ctx, _("Bad character height %d"), height); + if (height < 1 || height > 128) { + KFONT_ERR(ctx, _("Bad character height %d (limit is 128)"), height); return -EX_DATAERR; } - if (width < 1 || width > 32) { - KFONT_ERR(ctx, _("Bad character width %d"), width); + if (width < 1 || width > 64) { + KFONT_ERR(ctx, _("Bad character width %d (limit is 64)"), width); return -EX_DATAERR; } @@ -68,8 +69,8 @@ do_loadfont(struct kfont_context *ctx, i hwunit = height; if ((ctx->options & (1 << kfont_double_size)) && - (height > 16 || width > 16)) { - KFONT_ERR(ctx, _("Cannot double %dx%d font (limit is 16x16)"), width, height); + (height > 64 || width > 32)) { + KFONT_ERR(ctx, _("Cannot double %dx%d font (limit is 32x64)"), width, height); kfont_unset_option(ctx, kfont_double_size); } @@ -78,7 +79,7 @@ do_loadfont(struct kfont_context *ctx, i unsigned int kbytewidth = (2 * width + 7) / 8; unsigned int charsize = height * bytewidth; - kcharsize = 32 * kbytewidth; + kcharsize = vpitch * kbytewidth; buflen = kcharsize * ((fontsize < 128) ? 128 : fontsize); buf = calloc(1, buflen); @@ -112,7 +113,7 @@ do_loadfont(struct kfont_context *ctx, i unsigned int bytewidth = (width + 7) / 8; unsigned int charsize = height * bytewidth; - kcharsize = 32 * bytewidth; + kcharsize = vpitch * bytewidth; buflen = kcharsize * ((fontsize < 128) ? 128 : fontsize); buf = calloc(1, buflen); @@ -169,7 +170,7 @@ do_loadfont(struct kfont_context *ctx, i KFONT_INFO(ctx, _("Loading %d-char %dx%d (%d) font"), fontsize, width, height, hwunit); - if (kfont_put_font(ctx, fd, buf, fontsize, width, hwunit) < 0) { + if (kfont_put_font(ctx, fd, buf, fontsize, width, hwunit, vpitch) < 1) { ret = -EX_OSERR; goto err; } @@ -181,6 +182,20 @@ err: } static int +do_loadfont(struct kfont_context *ctx, int fd, const unsigned char *inbuf, + unsigned int width, unsigned int height, unsigned int hwunit, + unsigned int fontsize, const char *filename) +{ + int ret; + + if (height <= 32 && width <= 32) + /* This can work with pre-6.2 kernels and its size and vpitch limitations */ + return try_loadfont(ctx, fd, inbuf, width, height, 32, hwunit, fontsize, filename); + else + return try_loadfont(ctx, fd, inbuf, width, height, height, hwunit, fontsize, filename); +} + +static int do_loadtable(struct kfont_context *ctx, int fd, struct unicode_list *uclistheads, unsigned int fontsize) { @@ -585,19 +600,19 @@ save_font(struct kfont_context *ctx, int /* this is the max font size the kernel is willing to handle */ unsigned char buf[MAXFONTSIZE]; - unsigned int i, ct, width, height, bytewidth, charsize, kcharsize; + unsigned int i, ct, width, height, bytewidth, charsize, kcharsize, vpitch; int ret; - ct = sizeof(buf) / (32 * 32 / 8); /* max size 32x32, 8 bits/byte */ + ct = sizeof(buf) / (64 * 128 / 8); /* max size 64x128, 8 bits/byte */ - if (kfont_get_font(ctx, consolefd, buf, &ct, &width, &height) < 0) + if (kfont_get_font(ctx, consolefd, buf, &ct, &width, &height, &vpitch) < 0) return -EX_OSERR; /* save as efficiently as possible */ bytewidth = (width + 7) / 8; height = font_charheight(buf, ct, width); charsize = height * bytewidth; - kcharsize = 32 * bytewidth; + kcharsize = vpitch * bytewidth; /* Do we need a psf header? */ /* Yes if ct==512 - otherwise we cannot distinguish Index: kbd-2.5.1/src/showconsolefont.c =================================================================== --- kbd-2.5.1.orig/src/showconsolefont.c +++ kbd-2.5.1/src/showconsolefont.c @@ -205,7 +205,7 @@ int main(int argc, char **argv) if (info) { nr = rows = cols = 0; - ret = kfont_get_font(kfont, fd, NULL, &nr, &rows, &cols); + ret = kfont_get_font(kfont, fd, NULL, &nr, &rows, &cols, NULL); if (ret != 0) leave(kfont, EXIT_FAILURE); Index: kbd-2.5.1/tests/libtswrap/ioctl.c =================================================================== --- kbd-2.5.1.orig/tests/libtswrap/ioctl.c +++ kbd-2.5.1/tests/libtswrap/ioctl.c @@ -93,6 +93,12 @@ static struct translate_names kd_font_op { KD_FONT_OP_GET, "KD_FONT_OP_GET" }, { KD_FONT_OP_SET_DEFAULT, "KD_FONT_OP_SET_DEFAULT" }, { KD_FONT_OP_COPY, "KD_FONT_OP_COPY" }, +#ifdef KD_FONT_OP_SET_TALL + { KD_FONT_OP_SET_TALL, "KD_FONT_OP_SET_TALL" }, +#endif +#ifdef KD_FONT_OP_GET_TALL + { KD_FONT_OP_GET_TALL, "KD_FONT_OP_GET_TALL" }, +#endif { 0, NULL } };
Alexey Gladkov, le mer. 11 janv. 2023 21:00:05 +0100, a ecrit:
> > @@ -54,13 +55,13 @@ do_loadfont(struct kfont_context *ctx, i
> > int bad_video_erase_char = 0;
> > int ret;
> >
> > - if (height < 1 || height > 32) {
> > - KFONT_ERR(ctx, _("Bad character height %d"), height);
> > + if (height < 1 || height > 64) {
> > + KFONT_ERR(ctx, _("Bad character height %d (limit is 64)"), height);
>
> Hm. But max_font_height is 128. Shouldn't it be height > 128 ?
>
> > return -EX_DATAERR;
> > }
> >
> > - if (width < 1 || width > 32) {
> > - KFONT_ERR(ctx, _("Bad character width %d"), width);
> > + if (width < 1 || width > 128) {
> > + KFONT_ERR(ctx, _("Bad character width %d (limit is 128)"), width);
>
> Same here. max_font_width is 64.
Oops, sure, fixed it, will send an updated kbd patch for that.
Samuel
On Sun, Dec 18, 2022 at 01:33:25AM +0100, Samuel Thibault wrote: > The new KD_FONT_OP_GET/SET_TALL font operations allow to load fonts taller > than 32 pixels by dropping the VGA-specific vertical pitch limitation. > > The new maximum font size has thus been raised to 64x128. > > We however continue using the older font operations for smaller fonts, to > continue supporting older kernels. > > Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org> > > Index: kbd-2.5.1/src/compat/linux-kd.h > =================================================================== > --- kbd-2.5.1.orig/src/compat/linux-kd.h > +++ kbd-2.5.1/src/compat/linux-kd.h > @@ -90,7 +90,8 @@ struct console_font_op { > unsigned int flags; /* KD_FONT_FLAG_* */ > unsigned int width, height; > unsigned int charcount; > - unsigned char *data; /* font data with height fixed to 32 */ > + unsigned char *data; /* font data with vpitch fixed to 32 for > + * KD_FONT_OP_SET/GET */ > }; > > #define KD_FONT_OP_SET 0 /* Set font */ > @@ -98,6 +99,8 @@ struct console_font_op { > #define KD_FONT_OP_SET_DEFAULT 2 /* Set font to default, \ > data points to name / NULL */ > #define KD_FONT_OP_COPY 3 /* Copy from another console */ > +#define KD_FONT_OP_SET_TALL 4 /* Set font with arbitrary vpitch */ > +#define KD_FONT_OP_GET_TALL 5 /* Get font with arbitrary vpitch */ > > #define KD_FONT_FLAG_OLD 0x80000000 /* Invoked via old interface */ > #define KD_FONT_FLAG_DONT_RECALC 1 /* Don't call adjust_height() */ > Index: kbd-2.5.1/src/libkfont/kdfontop.c > =================================================================== > --- kbd-2.5.1.orig/src/libkfont/kdfontop.c > +++ kbd-2.5.1/src/libkfont/kdfontop.c > @@ -51,19 +51,33 @@ get_font_kdfontop(struct kfont_context * > unsigned char *buf, > unsigned int *count, > unsigned int *width, > - unsigned int *height) > + unsigned int *height, > + unsigned int *vpitch) > { > struct console_font_op cfo; > > +#ifdef KD_FONT_OP_GET_TALL > + cfo.op = KD_FONT_OP_GET_TALL; > +#else > cfo.op = KD_FONT_OP_GET; > +#endif > cfo.flags = 0; > - cfo.width = cfo.height = 32; > + cfo.width = 64; > + cfo.height = 128; > cfo.charcount = *count; > cfo.data = buf; > > +retry: > errno = 0; > > if (ioctl(consolefd, KDFONTOP, &cfo)) { > +#ifdef KD_FONT_OP_GET_TALL > + if (errno == ENOSYS && cfo.op == KD_FONT_OP_GET_TALL) { > + /* Kernel before 6.2. */ > + cfo.op = KD_FONT_OP_GET; > + goto retry; > + } > +#endif > if (errno != ENOSYS && errno != EINVAL) { > KFONT_ERR(ctx, "ioctl(KDFONTOP): %m"); > return -1; > @@ -76,6 +90,14 @@ get_font_kdfontop(struct kfont_context * > *height = cfo.height; > if (width) > *width = cfo.width; > + if (vpitch) { > +#ifdef KD_FONT_OP_GET_TALL > + if (cfo.op == KD_FONT_OP_GET_TALL) > + *vpitch = cfo.height; > + else > +#endif > + *vpitch = 32; > + } > return 0; > } > > @@ -88,16 +110,17 @@ int > kfont_get_font(struct kfont_context *ctx, int fd, unsigned char *buf, > unsigned int *count, > unsigned int *width, > - unsigned int *height) > + unsigned int *height, > + unsigned int *vpitch) > { > - return get_font_kdfontop(ctx, fd, buf, count, width, height); > + return get_font_kdfontop(ctx, fd, buf, count, width, height, vpitch); > } > > int unsigned > kfont_get_fontsize(struct kfont_context *ctx, int fd) > { > unsigned int count = 0; > - if (!kfont_get_font(ctx, fd, NULL, &count, NULL, NULL)) > + if (!kfont_get_font(ctx, fd, NULL, &count, NULL, NULL, NULL)) > return count; > return 256; > } > @@ -106,11 +129,20 @@ static int > put_font_kdfontop(struct kfont_context *ctx, int consolefd, unsigned char *buf, > unsigned int count, > unsigned int width, > - unsigned int height) > + unsigned int height, > + unsigned int vpitch) > { > struct console_font_op cfo; > > - cfo.op = KD_FONT_OP_SET; > + if (vpitch == 32 && width <= 32) > + cfo.op = KD_FONT_OP_SET; > + else { > +#ifdef KD_FONT_OP_SET_TALL > + cfo.op = KD_FONT_OP_SET_TALL; > +#else > + return 1; > +#endif > + } > cfo.flags = 0; > cfo.width = width; > cfo.height = height; > @@ -154,7 +186,7 @@ put_font_kdfontop(struct kfont_context * > > int > kfont_put_font(struct kfont_context *ctx, int fd, unsigned char *buf, unsigned int count, > - unsigned int width, unsigned int height) > + unsigned int width, unsigned int height, unsigned int vpitch) > { > if (!width) > width = 8; > @@ -162,5 +194,5 @@ kfont_put_font(struct kfont_context *ctx > if (!height) > height = font_charheight(buf, count, width); > > - return put_font_kdfontop(ctx, fd, buf, count, width, height); > + return put_font_kdfontop(ctx, fd, buf, count, width, height, vpitch); > } > Index: kbd-2.5.1/src/libkfont/kfont.h > =================================================================== > --- kbd-2.5.1.orig/src/libkfont/kfont.h > +++ kbd-2.5.1/src/libkfont/kfont.h > @@ -171,7 +171,8 @@ int kfont_load_unicodemap(struct kfont_c > * Sets number of glyphs in COUNT, glyph size in WIDTH and HEIGHT. > */ > int kfont_get_font(struct kfont_context *ctx, int consolefd, unsigned char *buf, > - unsigned int *count, unsigned int *width, unsigned int *height) > + unsigned int *count, unsigned int *width, unsigned int *height, > + unsigned int *vpitch) > __attribute__((nonnull(1))); > > /* > @@ -180,7 +181,8 @@ int kfont_get_font(struct kfont_context > * Return 0 on success, -1 on failure. > */ > int kfont_put_font(struct kfont_context *ctx, int consolefd, unsigned char *buf, > - unsigned int count, unsigned int width, unsigned int height) > + unsigned int count, unsigned int width, unsigned int height, > + unsigned int vpitch) > __attribute__((nonnull(1))); > > /* > @@ -239,7 +241,7 @@ void kfont_disactivatemap(int fd); > #include <stdio.h> > > /* Maximum font size that we try to handle */ > -#define MAXFONTSIZE 65536 > +#define MAXFONTSIZE (512*64*128) > > /** > * readpsffont reads a PSF font. > Index: kbd-2.5.1/src/libkfont/setfont.c > =================================================================== > --- kbd-2.5.1.orig/src/libkfont/setfont.c > +++ kbd-2.5.1/src/libkfont/setfont.c > @@ -45,8 +45,9 @@ findpartialfont(struct kfont_context *ct > static int erase_mode = 1; > > static int > -do_loadfont(struct kfont_context *ctx, int fd, const unsigned char *inbuf, > - unsigned int width, unsigned int height, unsigned int hwunit, > +try_loadfont(struct kfont_context *ctx, int fd, const unsigned char *inbuf, > + unsigned int width, unsigned int height, unsigned int vpitch, > + unsigned int hwunit, > unsigned int fontsize, const char *filename) > { > unsigned char *buf = NULL; > @@ -54,13 +55,13 @@ do_loadfont(struct kfont_context *ctx, i > int bad_video_erase_char = 0; > int ret; > > - if (height < 1 || height > 32) { > - KFONT_ERR(ctx, _("Bad character height %d"), height); > + if (height < 1 || height > 64) { > + KFONT_ERR(ctx, _("Bad character height %d (limit is 64)"), height); Hm. But max_font_height is 128. Shouldn't it be height > 128 ? > return -EX_DATAERR; > } > > - if (width < 1 || width > 32) { > - KFONT_ERR(ctx, _("Bad character width %d"), width); > + if (width < 1 || width > 128) { > + KFONT_ERR(ctx, _("Bad character width %d (limit is 128)"), width); Same here. max_font_width is 64. > return -EX_DATAERR; > } > > @@ -68,8 +69,8 @@ do_loadfont(struct kfont_context *ctx, i > hwunit = height; > > if ((ctx->options & (1 << kfont_double_size)) && > - (height > 16 || width > 16)) { > - KFONT_ERR(ctx, _("Cannot double %dx%d font (limit is 16x16)"), width, height); > + (height > 32 || width > 64)) { > + KFONT_ERR(ctx, _("Cannot double %dx%d font (limit is 32x64)"), width, height); > kfont_unset_option(ctx, kfont_double_size); > } > > @@ -78,7 +79,7 @@ do_loadfont(struct kfont_context *ctx, i > unsigned int kbytewidth = (2 * width + 7) / 8; > unsigned int charsize = height * bytewidth; > > - kcharsize = 32 * kbytewidth; > + kcharsize = vpitch * kbytewidth; > buflen = kcharsize * ((fontsize < 128) ? 128 : fontsize); > > buf = calloc(1, buflen); > @@ -112,7 +113,7 @@ do_loadfont(struct kfont_context *ctx, i > unsigned int bytewidth = (width + 7) / 8;> unsigned int charsize = height * bytewidth; > > - kcharsize = 32 * bytewidth; > + kcharsize = vpitch * bytewidth; > buflen = kcharsize * ((fontsize < 128) ? 128 : fontsize); > > buf = calloc(1, buflen); > @@ -169,7 +170,7 @@ do_loadfont(struct kfont_context *ctx, i > KFONT_INFO(ctx, _("Loading %d-char %dx%d (%d) font"), > fontsize, width, height, hwunit); > > - if (kfont_put_font(ctx, fd, buf, fontsize, width, hwunit) < 0) { > + if (kfont_put_font(ctx, fd, buf, fontsize, width, hwunit, vpitch) < 1) { > ret = -EX_OSERR; > goto err; > } > @@ -181,6 +182,20 @@ err: > } > > static int > +do_loadfont(struct kfont_context *ctx, int fd, const unsigned char *inbuf, > + unsigned int width, unsigned int height, unsigned int hwunit, > + unsigned int fontsize, const char *filename) > +{ > + int ret; > + > + if (height <= 32 && width <= 32) > + /* This can work with pre-6.2 kernels and its size and vpitch limitations */ > + return try_loadfont(ctx, fd, inbuf, width, height, 32, hwunit, fontsize, filename); > + else > + return try_loadfont(ctx, fd, inbuf, width, height, height, hwunit, fontsize, filename); > +} > + > +static int > do_loadtable(struct kfont_context *ctx, int fd, struct unicode_list *uclistheads, > unsigned int fontsize) > { > @@ -585,19 +600,19 @@ save_font(struct kfont_context *ctx, int > /* this is the max font size the kernel is willing to handle */ > unsigned char buf[MAXFONTSIZE]; > > - unsigned int i, ct, width, height, bytewidth, charsize, kcharsize; > + unsigned int i, ct, width, height, bytewidth, charsize, kcharsize, vpitch; > int ret; > > - ct = sizeof(buf) / (32 * 32 / 8); /* max size 32x32, 8 bits/byte */ > + ct = sizeof(buf) / (64 * 128 / 8); /* max size 64x128, 8 bits/byte */ > > - if (kfont_get_font(ctx, consolefd, buf, &ct, &width, &height) < 0) > + if (kfont_get_font(ctx, consolefd, buf, &ct, &width, &height, &vpitch) < 0) > return -EX_OSERR; > > /* save as efficiently as possible */ > bytewidth = (width + 7) / 8; > height = font_charheight(buf, ct, width); > charsize = height * bytewidth; > - kcharsize = 32 * bytewidth; > + kcharsize = vpitch * bytewidth; > > /* Do we need a psf header? */ > /* Yes if ct==512 - otherwise we cannot distinguish > Index: kbd-2.5.1/src/showconsolefont.c > =================================================================== > --- kbd-2.5.1.orig/src/showconsolefont.c > +++ kbd-2.5.1/src/showconsolefont.c > @@ -205,7 +205,7 @@ int main(int argc, char **argv) > if (info) { > nr = rows = cols = 0; > > - ret = kfont_get_font(kfont, fd, NULL, &nr, &rows, &cols); > + ret = kfont_get_font(kfont, fd, NULL, &nr, &rows, &cols, NULL); > if (ret != 0) > leave(kfont, EXIT_FAILURE); > > Index: kbd-2.5.1/tests/libtswrap/ioctl.c > =================================================================== > --- kbd-2.5.1.orig/tests/libtswrap/ioctl.c > +++ kbd-2.5.1/tests/libtswrap/ioctl.c > @@ -93,6 +93,12 @@ static struct translate_names kd_font_op > { KD_FONT_OP_GET, "KD_FONT_OP_GET" }, > { KD_FONT_OP_SET_DEFAULT, "KD_FONT_OP_SET_DEFAULT" }, > { KD_FONT_OP_COPY, "KD_FONT_OP_COPY" }, > +#ifdef KD_FONT_OP_SET_TALL > + { KD_FONT_OP_SET_TALL, "KD_FONT_OP_SET_TALL" }, > +#endif > +#ifdef KD_FONT_OP_GET_TALL > + { KD_FONT_OP_GET_TALL, "KD_FONT_OP_GET_TALL" }, > +#endif > { 0, NULL } > }; > > > _______________________________________________ > kbd mailing list > kbd@lists.altlinux.org > https://lists.altlinux.org/mailman/listinfo/kbd > -- Rgrds, legion
Hello,
Ping, is there anything to be done on this?
Samuel
Samuel Thibault, le dim. 18 déc. 2022 01:32:09 +0100, a ecrit:
> Hello,
>
> This patch series adds to Linux and kbd the support for fonts larger than 32x32
> by dropping the oldish VGA constraints that don't apply to fb-based consoles.
>
> Samuel
On Sun, Dec 18, 2022 at 04:28:57PM +0100, Samuel Thibault wrote:
> Alexey Gladkov, le dim. 18 déc. 2022 16:25:01 +0100, a ecrit:
> > On Sun, Dec 18, 2022 at 03:55:32PM +0100, Samuel Thibault wrote:
> > > Alexey Gladkov, le dim. 18 déc. 2022 15:39:38 +0100, a ecrit:
> > > > On Sun, Dec 18, 2022 at 01:32:12AM +0100, Samuel Thibault wrote:
> > > > > -#define max_font_size 65536
> > > > > +#define max_font_width 64
> > > > > +#define max_font_height 128
> > > > > +#define max_font_glyphs 512
> > > > > +#define max_font_size (max_font_glyphs*max_font_width*max_font_height)
> > > >
> > > > As a suggestion that you can safely ignore. Maybe make max_font_glyphs a
> > > > sysctl parameter to be able to use larger fonts ?
> > > >
> > > > I get requests from time to time in kbd that it is not possible to load a
> > > > larger font.
> > >
> > > 64KiB was really low, while the theoretically possible max was
> > > 32*32*512 = 512KB, so I understand there used to be such requests :)
> > >
> > > Here, by setting the max to 64x128*512, I don't think we'll need more.
> >
> > I was not talking about the size of one glyph, but about the number of
> > glyphs in the font. Right now the font cannot have more than 512 glyphs.
>
> That one is unfortunately *very* hardcoded in the VT code, since it's
> the very representation of the console text in vc_screenbuf which is set
> to the VGA-based 16bits per glyph, with a 8+8 or 9+7 separation between
> glyph number and color number. Lifting that would be way more involved.
Yeah, but I thought that since someone decided to touch this old code,
then this someone will improve this old limit :)
--
Rgrds, legion
Alexey Gladkov, le dim. 18 déc. 2022 16:25:01 +0100, a ecrit:
> On Sun, Dec 18, 2022 at 03:55:32PM +0100, Samuel Thibault wrote:
> > Alexey Gladkov, le dim. 18 déc. 2022 15:39:38 +0100, a ecrit:
> > > On Sun, Dec 18, 2022 at 01:32:12AM +0100, Samuel Thibault wrote:
> > > > -#define max_font_size 65536
> > > > +#define max_font_width 64
> > > > +#define max_font_height 128
> > > > +#define max_font_glyphs 512
> > > > +#define max_font_size (max_font_glyphs*max_font_width*max_font_height)
> > >
> > > As a suggestion that you can safely ignore. Maybe make max_font_glyphs a
> > > sysctl parameter to be able to use larger fonts ?
> > >
> > > I get requests from time to time in kbd that it is not possible to load a
> > > larger font.
> >
> > 64KiB was really low, while the theoretically possible max was
> > 32*32*512 = 512KB, so I understand there used to be such requests :)
> >
> > Here, by setting the max to 64x128*512, I don't think we'll need more.
>
> I was not talking about the size of one glyph, but about the number of
> glyphs in the font. Right now the font cannot have more than 512 glyphs.
That one is unfortunately *very* hardcoded in the VT code, since it's
the very representation of the console text in vc_screenbuf which is set
to the VGA-based 16bits per glyph, with a 8+8 or 9+7 separation between
glyph number and color number. Lifting that would be way more involved.
Samuel
On Sun, Dec 18, 2022 at 03:55:32PM +0100, Samuel Thibault wrote: > Hello, > > Alexey Gladkov, le dim. 18 déc. 2022 15:39:38 +0100, a ecrit: > > On Sun, Dec 18, 2022 at 01:32:12AM +0100, Samuel Thibault wrote: > > > This moves 32x32 font size limitation checking down to drivers, so that > > > fbcon can allow large fonts. > > > > > > We still keep a limitation to 64x128 pixels so as to have a simple bounded > > > allocation for con_font_get and in the userland kbd tool. That glyph size > > > will however be enough to have 128x36 characters on a "16/9 8K display". > > > > > > Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org> > > > > > > --- > > > V1 -> V2: Switch con_font_get to kvmalloc/kvfree instead of kmalloc/kfree > > > > > > Index: linux-6.0/drivers/tty/vt/vt.c > > > =================================================================== > > > --- linux-6.0.orig/drivers/tty/vt/vt.c > > > +++ linux-6.0/drivers/tty/vt/vt.c > > > @@ -4575,17 +4575,20 @@ void reset_palette(struct vc_data *vc) > > > /* > > > * Font switching > > > * > > > - * Currently we only support fonts up to 32 pixels wide, at a maximum height > > > - * of 32 pixels. Userspace fontdata is stored with 32 bytes (shorts/ints, > > > - * depending on width) reserved for each character which is kinda wasty, but > > > - * this is done in order to maintain compatibility with the EGA/VGA fonts. It > > > - * is up to the actual low-level console-driver convert data into its favorite > > > - * format (maybe we should add a `fontoffset' field to the `display' > > > - * structure so we won't have to convert the fontdata all the time. > > > + * Currently we only support fonts up to 128 pixels wide, at a maximum height > > > + * of 128 pixels. Userspace fontdata may have to be stored with 32 bytes > > > + * (shorts/ints, depending on width) reserved for each character which is > > > + * kinda wasty, but this is done in order to maintain compatibility with the > > > + * EGA/VGA fonts. It is up to the actual low-level console-driver convert data > > > + * into its favorite format (maybe we should add a `fontoffset' field to the > > > + * `display' structure so we won't have to convert the fontdata all the time. > > > * /Jes > > > */ > > > > > > -#define max_font_size 65536 > > > +#define max_font_width 64 > > > +#define max_font_height 128 > > > +#define max_font_glyphs 512 > > > +#define max_font_size (max_font_glyphs*max_font_width*max_font_height) > > > > As a suggestion that you can safely ignore. Maybe make max_font_glyphs a > > sysctl parameter to be able to use larger fonts ? > > > > I get requests from time to time in kbd that it is not possible to load a > > larger font. > > 64KiB was really low, while the theoretically possible max was > 32*32*512 = 512KB, so I understand there used to be such requests :) > > Here, by setting the max to 64x128*512, I don't think we'll need more. I was not talking about the size of one glyph, but about the number of glyphs in the font. Right now the font cannot have more than 512 glyphs. > Even with a 8K screen (will such really exist and want a text console?) > the max 64x128 gets 128 characters on a single line, for soemthing like > 36 lines. So I guess it's not worth adding yet another sysctl :) Ok. > Samuel > -- Rgrds, legion
Hello,
Alexey Gladkov, le dim. 18 déc. 2022 15:39:38 +0100, a ecrit:
> On Sun, Dec 18, 2022 at 01:32:12AM +0100, Samuel Thibault wrote:
> > This moves 32x32 font size limitation checking down to drivers, so that
> > fbcon can allow large fonts.
> >
> > We still keep a limitation to 64x128 pixels so as to have a simple bounded
> > allocation for con_font_get and in the userland kbd tool. That glyph size
> > will however be enough to have 128x36 characters on a "16/9 8K display".
> >
> > Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
> >
> > ---
> > V1 -> V2: Switch con_font_get to kvmalloc/kvfree instead of kmalloc/kfree
> >
> > Index: linux-6.0/drivers/tty/vt/vt.c
> > ===================================================================
> > --- linux-6.0.orig/drivers/tty/vt/vt.c
> > +++ linux-6.0/drivers/tty/vt/vt.c
> > @@ -4575,17 +4575,20 @@ void reset_palette(struct vc_data *vc)
> > /*
> > * Font switching
> > *
> > - * Currently we only support fonts up to 32 pixels wide, at a maximum height
> > - * of 32 pixels. Userspace fontdata is stored with 32 bytes (shorts/ints,
> > - * depending on width) reserved for each character which is kinda wasty, but
> > - * this is done in order to maintain compatibility with the EGA/VGA fonts. It
> > - * is up to the actual low-level console-driver convert data into its favorite
> > - * format (maybe we should add a `fontoffset' field to the `display'
> > - * structure so we won't have to convert the fontdata all the time.
> > + * Currently we only support fonts up to 128 pixels wide, at a maximum height
> > + * of 128 pixels. Userspace fontdata may have to be stored with 32 bytes
> > + * (shorts/ints, depending on width) reserved for each character which is
> > + * kinda wasty, but this is done in order to maintain compatibility with the
> > + * EGA/VGA fonts. It is up to the actual low-level console-driver convert data
> > + * into its favorite format (maybe we should add a `fontoffset' field to the
> > + * `display' structure so we won't have to convert the fontdata all the time.
> > * /Jes
> > */
> >
> > -#define max_font_size 65536
> > +#define max_font_width 64
> > +#define max_font_height 128
> > +#define max_font_glyphs 512
> > +#define max_font_size (max_font_glyphs*max_font_width*max_font_height)
>
> As a suggestion that you can safely ignore. Maybe make max_font_glyphs a
> sysctl parameter to be able to use larger fonts ?
>
> I get requests from time to time in kbd that it is not possible to load a
> larger font.
64KiB was really low, while the theoretically possible max was
32*32*512 = 512KB, so I understand there used to be such requests :)
Here, by setting the max to 64x128*512, I don't think we'll need more.
Even with a 8K screen (will such really exist and want a text console?)
the max 64x128 gets 128 characters on a single line, for soemthing like
36 lines. So I guess it's not worth adding yet another sysctl :)
Samuel
On Sun, Dec 18, 2022 at 01:32:12AM +0100, Samuel Thibault wrote: > This moves 32x32 font size limitation checking down to drivers, so that > fbcon can allow large fonts. > > We still keep a limitation to 64x128 pixels so as to have a simple bounded > allocation for con_font_get and in the userland kbd tool. That glyph size > will however be enough to have 128x36 characters on a "16/9 8K display". > > Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org> > > --- > V1 -> V2: Switch con_font_get to kvmalloc/kvfree instead of kmalloc/kfree > > Index: linux-6.0/drivers/tty/vt/vt.c > =================================================================== > --- linux-6.0.orig/drivers/tty/vt/vt.c > +++ linux-6.0/drivers/tty/vt/vt.c > @@ -4575,17 +4575,20 @@ void reset_palette(struct vc_data *vc) > /* > * Font switching > * > - * Currently we only support fonts up to 32 pixels wide, at a maximum height > - * of 32 pixels. Userspace fontdata is stored with 32 bytes (shorts/ints, > - * depending on width) reserved for each character which is kinda wasty, but > - * this is done in order to maintain compatibility with the EGA/VGA fonts. It > - * is up to the actual low-level console-driver convert data into its favorite > - * format (maybe we should add a `fontoffset' field to the `display' > - * structure so we won't have to convert the fontdata all the time. > + * Currently we only support fonts up to 128 pixels wide, at a maximum height > + * of 128 pixels. Userspace fontdata may have to be stored with 32 bytes > + * (shorts/ints, depending on width) reserved for each character which is > + * kinda wasty, but this is done in order to maintain compatibility with the > + * EGA/VGA fonts. It is up to the actual low-level console-driver convert data > + * into its favorite format (maybe we should add a `fontoffset' field to the > + * `display' structure so we won't have to convert the fontdata all the time. > * /Jes > */ > > -#define max_font_size 65536 > +#define max_font_width 64 > +#define max_font_height 128 > +#define max_font_glyphs 512 > +#define max_font_size (max_font_glyphs*max_font_width*max_font_height) As a suggestion that you can safely ignore. Maybe make max_font_glyphs a sysctl parameter to be able to use larger fonts ? I get requests from time to time in kbd that it is not possible to load a larger font. > static int con_font_get(struct vc_data *vc, struct console_font_op *op) > { > @@ -4595,7 +4598,7 @@ static int con_font_get(struct vc_data * > unsigned int vpitch = op->op == KD_FONT_OP_GET_TALL ? op->height : 32; > > if (op->data) { > - font.data = kmalloc(max_font_size, GFP_KERNEL); > + font.data = kvmalloc(max_font_size, GFP_KERNEL); > if (!font.data) > return -ENOMEM; > } else > @@ -4630,7 +4633,7 @@ static int con_font_get(struct vc_data * > rc = -EFAULT; > > out: > - kfree(font.data); > + kvfree(font.data); > return rc; > } > > @@ -4645,9 +4648,10 @@ static int con_font_set(struct vc_data * > return -EINVAL; > if (!op->data) > return -EINVAL; > - if (op->charcount > 512) > + if (op->charcount > max_font_glyphs) > return -EINVAL; > - if (op->width <= 0 || op->width > 32 || !op->height || op->height > 32) > + if (op->width <= 0 || op->width > max_font_width || !op->height || > + op->height > max_font_height) > return -EINVAL; > if (vpitch < op->height) > return -EINVAL; > Index: linux-6.0/drivers/usb/misc/sisusbvga/sisusb_con.c > =================================================================== > --- linux-6.0.orig/drivers/usb/misc/sisusbvga/sisusb_con.c > +++ linux-6.0/drivers/usb/misc/sisusbvga/sisusb_con.c > @@ -1203,7 +1203,7 @@ sisusbcon_font_set(struct vc_data *c, st > struct sisusb_usb_data *sisusb; > unsigned charcount = font->charcount; > > - if (font->width != 8 || vpitch != 32 || > + if (font->width != 8 || font->height > 32 || vpitch != 32 || > (charcount != 256 && charcount != 512)) > return -EINVAL; > > Index: linux-6.0/drivers/video/console/vgacon.c > =================================================================== > --- linux-6.0.orig/drivers/video/console/vgacon.c > +++ linux-6.0/drivers/video/console/vgacon.c > @@ -1037,7 +1037,7 @@ static int vgacon_font_set(struct vc_dat > if (vga_video_type < VIDEO_TYPE_EGAM) > return -EINVAL; > > - if (font->width != VGA_FONTWIDTH || vpitch != 32 || > + if (font->width != VGA_FONTWIDTH || font->height > 32 || vpitch != 32 || > (charcount != 256 && charcount != 512)) > return -EINVAL; > > Index: linux-6.0/drivers/video/fbdev/core/fbcon.c > =================================================================== > --- linux-6.0.orig/drivers/video/fbdev/core/fbcon.c > +++ linux-6.0/drivers/video/fbdev/core/fbcon.c > @@ -2279,6 +2279,8 @@ static int fbcon_get_font(struct vc_data > > font->width = vc->vc_font.width; > font->height = vc->vc_font.height; > + if (font->height > vpitch) > + return -ENOSPC; > font->charcount = vc->vc_hi_font_mask ? 512 : 256; > if (!font->data) > return 0; > > _______________________________________________ > kbd mailing list > kbd@lists.altlinux.org > https://lists.altlinux.org/mailman/listinfo/kbd > -- Rgrds, legion
The new KD_FONT_OP_GET/SET_TALL font operations allow to load fonts taller than 32 pixels by dropping the VGA-specific vertical pitch limitation. The new maximum font size has thus been raised to 64x128. We however continue using the older font operations for smaller fonts, to continue supporting older kernels. Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org> Index: kbd-2.5.1/src/compat/linux-kd.h =================================================================== --- kbd-2.5.1.orig/src/compat/linux-kd.h +++ kbd-2.5.1/src/compat/linux-kd.h @@ -90,7 +90,8 @@ struct console_font_op { unsigned int flags; /* KD_FONT_FLAG_* */ unsigned int width, height; unsigned int charcount; - unsigned char *data; /* font data with height fixed to 32 */ + unsigned char *data; /* font data with vpitch fixed to 32 for + * KD_FONT_OP_SET/GET */ }; #define KD_FONT_OP_SET 0 /* Set font */ @@ -98,6 +99,8 @@ struct console_font_op { #define KD_FONT_OP_SET_DEFAULT 2 /* Set font to default, \ data points to name / NULL */ #define KD_FONT_OP_COPY 3 /* Copy from another console */ +#define KD_FONT_OP_SET_TALL 4 /* Set font with arbitrary vpitch */ +#define KD_FONT_OP_GET_TALL 5 /* Get font with arbitrary vpitch */ #define KD_FONT_FLAG_OLD 0x80000000 /* Invoked via old interface */ #define KD_FONT_FLAG_DONT_RECALC 1 /* Don't call adjust_height() */ Index: kbd-2.5.1/src/libkfont/kdfontop.c =================================================================== --- kbd-2.5.1.orig/src/libkfont/kdfontop.c +++ kbd-2.5.1/src/libkfont/kdfontop.c @@ -51,19 +51,33 @@ get_font_kdfontop(struct kfont_context * unsigned char *buf, unsigned int *count, unsigned int *width, - unsigned int *height) + unsigned int *height, + unsigned int *vpitch) { struct console_font_op cfo; +#ifdef KD_FONT_OP_GET_TALL + cfo.op = KD_FONT_OP_GET_TALL; +#else cfo.op = KD_FONT_OP_GET; +#endif cfo.flags = 0; - cfo.width = cfo.height = 32; + cfo.width = 64; + cfo.height = 128; cfo.charcount = *count; cfo.data = buf; +retry: errno = 0; if (ioctl(consolefd, KDFONTOP, &cfo)) { +#ifdef KD_FONT_OP_GET_TALL + if (errno == ENOSYS && cfo.op == KD_FONT_OP_GET_TALL) { + /* Kernel before 6.2. */ + cfo.op = KD_FONT_OP_GET; + goto retry; + } +#endif if (errno != ENOSYS && errno != EINVAL) { KFONT_ERR(ctx, "ioctl(KDFONTOP): %m"); return -1; @@ -76,6 +90,14 @@ get_font_kdfontop(struct kfont_context * *height = cfo.height; if (width) *width = cfo.width; + if (vpitch) { +#ifdef KD_FONT_OP_GET_TALL + if (cfo.op == KD_FONT_OP_GET_TALL) + *vpitch = cfo.height; + else +#endif + *vpitch = 32; + } return 0; } @@ -88,16 +110,17 @@ int kfont_get_font(struct kfont_context *ctx, int fd, unsigned char *buf, unsigned int *count, unsigned int *width, - unsigned int *height) + unsigned int *height, + unsigned int *vpitch) { - return get_font_kdfontop(ctx, fd, buf, count, width, height); + return get_font_kdfontop(ctx, fd, buf, count, width, height, vpitch); } int unsigned kfont_get_fontsize(struct kfont_context *ctx, int fd) { unsigned int count = 0; - if (!kfont_get_font(ctx, fd, NULL, &count, NULL, NULL)) + if (!kfont_get_font(ctx, fd, NULL, &count, NULL, NULL, NULL)) return count; return 256; } @@ -106,11 +129,20 @@ static int put_font_kdfontop(struct kfont_context *ctx, int consolefd, unsigned char *buf, unsigned int count, unsigned int width, - unsigned int height) + unsigned int height, + unsigned int vpitch) { struct console_font_op cfo; - cfo.op = KD_FONT_OP_SET; + if (vpitch == 32 && width <= 32) + cfo.op = KD_FONT_OP_SET; + else { +#ifdef KD_FONT_OP_SET_TALL + cfo.op = KD_FONT_OP_SET_TALL; +#else + return 1; +#endif + } cfo.flags = 0; cfo.width = width; cfo.height = height; @@ -154,7 +186,7 @@ put_font_kdfontop(struct kfont_context * int kfont_put_font(struct kfont_context *ctx, int fd, unsigned char *buf, unsigned int count, - unsigned int width, unsigned int height) + unsigned int width, unsigned int height, unsigned int vpitch) { if (!width) width = 8; @@ -162,5 +194,5 @@ kfont_put_font(struct kfont_context *ctx if (!height) height = font_charheight(buf, count, width); - return put_font_kdfontop(ctx, fd, buf, count, width, height); + return put_font_kdfontop(ctx, fd, buf, count, width, height, vpitch); } Index: kbd-2.5.1/src/libkfont/kfont.h =================================================================== --- kbd-2.5.1.orig/src/libkfont/kfont.h +++ kbd-2.5.1/src/libkfont/kfont.h @@ -171,7 +171,8 @@ int kfont_load_unicodemap(struct kfont_c * Sets number of glyphs in COUNT, glyph size in WIDTH and HEIGHT. */ int kfont_get_font(struct kfont_context *ctx, int consolefd, unsigned char *buf, - unsigned int *count, unsigned int *width, unsigned int *height) + unsigned int *count, unsigned int *width, unsigned int *height, + unsigned int *vpitch) __attribute__((nonnull(1))); /* @@ -180,7 +181,8 @@ int kfont_get_font(struct kfont_context * Return 0 on success, -1 on failure. */ int kfont_put_font(struct kfont_context *ctx, int consolefd, unsigned char *buf, - unsigned int count, unsigned int width, unsigned int height) + unsigned int count, unsigned int width, unsigned int height, + unsigned int vpitch) __attribute__((nonnull(1))); /* @@ -239,7 +241,7 @@ void kfont_disactivatemap(int fd); #include <stdio.h> /* Maximum font size that we try to handle */ -#define MAXFONTSIZE 65536 +#define MAXFONTSIZE (512*64*128) /** * readpsffont reads a PSF font. Index: kbd-2.5.1/src/libkfont/setfont.c =================================================================== --- kbd-2.5.1.orig/src/libkfont/setfont.c +++ kbd-2.5.1/src/libkfont/setfont.c @@ -45,8 +45,9 @@ findpartialfont(struct kfont_context *ct static int erase_mode = 1; static int -do_loadfont(struct kfont_context *ctx, int fd, const unsigned char *inbuf, - unsigned int width, unsigned int height, unsigned int hwunit, +try_loadfont(struct kfont_context *ctx, int fd, const unsigned char *inbuf, + unsigned int width, unsigned int height, unsigned int vpitch, + unsigned int hwunit, unsigned int fontsize, const char *filename) { unsigned char *buf = NULL; @@ -54,13 +55,13 @@ do_loadfont(struct kfont_context *ctx, i int bad_video_erase_char = 0; int ret; - if (height < 1 || height > 32) { - KFONT_ERR(ctx, _("Bad character height %d"), height); + if (height < 1 || height > 64) { + KFONT_ERR(ctx, _("Bad character height %d (limit is 64)"), height); return -EX_DATAERR; } - if (width < 1 || width > 32) { - KFONT_ERR(ctx, _("Bad character width %d"), width); + if (width < 1 || width > 128) { + KFONT_ERR(ctx, _("Bad character width %d (limit is 128)"), width); return -EX_DATAERR; } @@ -68,8 +69,8 @@ do_loadfont(struct kfont_context *ctx, i hwunit = height; if ((ctx->options & (1 << kfont_double_size)) && - (height > 16 || width > 16)) { - KFONT_ERR(ctx, _("Cannot double %dx%d font (limit is 16x16)"), width, height); + (height > 32 || width > 64)) { + KFONT_ERR(ctx, _("Cannot double %dx%d font (limit is 32x64)"), width, height); kfont_unset_option(ctx, kfont_double_size); } @@ -78,7 +79,7 @@ do_loadfont(struct kfont_context *ctx, i unsigned int kbytewidth = (2 * width + 7) / 8; unsigned int charsize = height * bytewidth; - kcharsize = 32 * kbytewidth; + kcharsize = vpitch * kbytewidth; buflen = kcharsize * ((fontsize < 128) ? 128 : fontsize); buf = calloc(1, buflen); @@ -112,7 +113,7 @@ do_loadfont(struct kfont_context *ctx, i unsigned int bytewidth = (width + 7) / 8; unsigned int charsize = height * bytewidth; - kcharsize = 32 * bytewidth; + kcharsize = vpitch * bytewidth; buflen = kcharsize * ((fontsize < 128) ? 128 : fontsize); buf = calloc(1, buflen); @@ -169,7 +170,7 @@ do_loadfont(struct kfont_context *ctx, i KFONT_INFO(ctx, _("Loading %d-char %dx%d (%d) font"), fontsize, width, height, hwunit); - if (kfont_put_font(ctx, fd, buf, fontsize, width, hwunit) < 0) { + if (kfont_put_font(ctx, fd, buf, fontsize, width, hwunit, vpitch) < 1) { ret = -EX_OSERR; goto err; } @@ -181,6 +182,20 @@ err: } static int +do_loadfont(struct kfont_context *ctx, int fd, const unsigned char *inbuf, + unsigned int width, unsigned int height, unsigned int hwunit, + unsigned int fontsize, const char *filename) +{ + int ret; + + if (height <= 32 && width <= 32) + /* This can work with pre-6.2 kernels and its size and vpitch limitations */ + return try_loadfont(ctx, fd, inbuf, width, height, 32, hwunit, fontsize, filename); + else + return try_loadfont(ctx, fd, inbuf, width, height, height, hwunit, fontsize, filename); +} + +static int do_loadtable(struct kfont_context *ctx, int fd, struct unicode_list *uclistheads, unsigned int fontsize) { @@ -585,19 +600,19 @@ save_font(struct kfont_context *ctx, int /* this is the max font size the kernel is willing to handle */ unsigned char buf[MAXFONTSIZE]; - unsigned int i, ct, width, height, bytewidth, charsize, kcharsize; + unsigned int i, ct, width, height, bytewidth, charsize, kcharsize, vpitch; int ret; - ct = sizeof(buf) / (32 * 32 / 8); /* max size 32x32, 8 bits/byte */ + ct = sizeof(buf) / (64 * 128 / 8); /* max size 64x128, 8 bits/byte */ - if (kfont_get_font(ctx, consolefd, buf, &ct, &width, &height) < 0) + if (kfont_get_font(ctx, consolefd, buf, &ct, &width, &height, &vpitch) < 0) return -EX_OSERR; /* save as efficiently as possible */ bytewidth = (width + 7) / 8; height = font_charheight(buf, ct, width); charsize = height * bytewidth; - kcharsize = 32 * bytewidth; + kcharsize = vpitch * bytewidth; /* Do we need a psf header? */ /* Yes if ct==512 - otherwise we cannot distinguish Index: kbd-2.5.1/src/showconsolefont.c =================================================================== --- kbd-2.5.1.orig/src/showconsolefont.c +++ kbd-2.5.1/src/showconsolefont.c @@ -205,7 +205,7 @@ int main(int argc, char **argv) if (info) { nr = rows = cols = 0; - ret = kfont_get_font(kfont, fd, NULL, &nr, &rows, &cols); + ret = kfont_get_font(kfont, fd, NULL, &nr, &rows, &cols, NULL); if (ret != 0) leave(kfont, EXIT_FAILURE); Index: kbd-2.5.1/tests/libtswrap/ioctl.c =================================================================== --- kbd-2.5.1.orig/tests/libtswrap/ioctl.c +++ kbd-2.5.1/tests/libtswrap/ioctl.c @@ -93,6 +93,12 @@ static struct translate_names kd_font_op { KD_FONT_OP_GET, "KD_FONT_OP_GET" }, { KD_FONT_OP_SET_DEFAULT, "KD_FONT_OP_SET_DEFAULT" }, { KD_FONT_OP_COPY, "KD_FONT_OP_COPY" }, +#ifdef KD_FONT_OP_SET_TALL + { KD_FONT_OP_SET_TALL, "KD_FONT_OP_SET_TALL" }, +#endif +#ifdef KD_FONT_OP_GET_TALL + { KD_FONT_OP_GET_TALL, "KD_FONT_OP_GET_TALL" }, +#endif { 0, NULL } };