Commit 81cf4d7d authored by Nicolas Pitre's avatar Nicolas Pitre Committed by Greg Kroah-Hartman
Browse files

vt: add VT_GETCONSIZECSRPOS to retrieve console size and cursor position



The console dimension and cursor position are available through the
/dev/vcsa interface already. However the /dev/vcsa header format uses
single-byte fields therefore those values are clamped to 255.

As surprizing as this may seem, some people do use 240-column 67-row
screens (a 1920x1080 monitor with 8x16 pixel fonts) which is getting
close to the limit. Monitors with higher resolution are not uncommon
these days (3840x2160 producing a 480x135 character display) and it is
just a matter of time before someone with, say, a braille display using
the Linux VT console and BRLTTY on such a screen reports a bug about
missing and oddly misaligned screen content.

Let's add VT_GETCONSIZECSRPOS for the retrieval of console size and cursor
position without byte-sized limitations. The actual console size limit as
encoded in vt.c is 32767x32767 so using a short here is appropriate. Then
this can be used to get the cursor position when /dev/vcsa reports 255.

The screen dimension may already be obtained using TIOCGWINSZ and adding
the same information to VT_GETCONSIZECSRPOS might be redundant. However
applications that care about cursor position also care about display
size and having 2 separate system calls to obtain them separately is
wasteful. Also, the cursor position can be queried by writing "\e[6n" to
a tty and reading back the result but that may be done only by the actual
application using that tty and not a sideline observer.

Signed-off-by: default avatarNicolas Pitre <npitre@baylibre.com>
Link: https://lore.kernel.org/r/20250520171851.1219676-3-nico@fluxnic.net


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 80fa7a03
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -951,6 +951,22 @@ int vt_ioctl(struct tty_struct *tty,
					(unsigned short __user *)arg);
	case VT_WAITEVENT:
		return vt_event_wait_ioctl((struct vt_event __user *)arg);

	case VT_GETCONSIZECSRPOS:
	{
		struct vt_consizecsrpos concsr;

		console_lock();
		concsr.con_cols = vc->vc_cols;
		concsr.con_rows = vc->vc_rows;
		concsr.csr_col = vc->state.x;
		concsr.csr_row = vc->state.y;
		console_unlock();
		if (copy_to_user(up, &concsr, sizeof(concsr)))
			return -EFAULT;
		return 0;
	}

	default:
		return -ENOIOCTLCMD;
	}
+11 −0
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@
#ifndef _UAPI_LINUX_VT_H
#define _UAPI_LINUX_VT_H

#include <linux/ioctl.h>
#include <linux/types.h>

/*
 * These constants are also useful for user-level apps (e.g., VC
@@ -84,4 +86,13 @@ struct vt_setactivate {

#define VT_SETACTIVATE	0x560F	/* Activate and set the mode of a console */

/* get console size and cursor position */
struct vt_consizecsrpos {
	__u16 con_rows;		/* number of console rows */
	__u16 con_cols;		/* number of console columns */
	__u16 csr_row;		/* current cursor's row */
	__u16 csr_col;		/* current cursor's column */
};
#define VT_GETCONSIZECSRPOS	_IOR('V', 0x10, struct vt_consizecsrpos)

#endif /* _UAPI_LINUX_VT_H */