Bug #11501


Scroll Lock translation to control sequence is patently unhelpful

Added by Joshua M. Clulow about 3 years ago. Updated about 3 years ago.

Start date:
Due date:
% Done:


Estimated time:
Gerrit CR:



Most keyboards (using any interconnect) have a series of function keys beyond the alphanumeric; e.g., F1, F2, F3, Pause, Print Screen, etc. Some function keys are generally "sticky" and associated with an indicator light; e.g., Caps Lock, Scroll Lock, and Num Lock.

Of the sticky keys, the Scroll Lock key is the most archaic: its function is not standard across different operating systems, or even different terminal or windowing environments. On illumos, the key is not even sticky when using the framebuffer text console! Instead of acting as a modifier or even merely influencing the indicator light state, a control sequence is emitted as keyboard input: CSI 210 z. This control sequence is not, as near as I can tell, recognised by any software. A user pressing the Scroll Lock key will likely confuse whatever application (including the shell, or the kernel line discipline) is currently active.

The SPICE server code used for framebuffer and keyboard emulation in some hypervisors (e.g., QEMU/KVM on Linux) makes an unfortunately aggressive attempt to keep the emulated Scroll Lock indicator light (which we do not handle!) synchronised with the Scroll Lock state on the client keyboard. Every two seconds, it will produce an emulated press and release of the Scroll Lock key in the guest, making the console effectively unusable.

Keyboard Handling Background

The keyboard handling subsystem involves a number of modules and a somewhat impenetrable Rube Goldberg machine of STREAMS. Roughly, we're looking at this structure:

console stdin <- wc <-  conskbd  <- keyboard driver (kb8042, usbkbm, etc)
                       [kbtrans]       [kbtrans]

Drivers for physical keyboards (e.g., kb8042 on Intel, or usbkbm on all platforms for USB keyboards) start out by setting up an instance of the common kbtrans framework through kbtrans_streams_init(). This framework begins in the TR_ASCII translation mode. The keyboard drivers are capable of simulating either a native scancode set (e.g., PC AT keyboard for kb8042) or the USB HID scancode set; this can be set via the CONSSETKBDTYPE ioctl().

The conskbd module is pushed on top of the lower keyboard driver. While it initialises, it forces the underlying keyboard to use the USB scancode set via CONSSETKBDTYPE. It also disables translation to ASCII by switching to the TR_UNTRANS_EVENT mode via KIOCTRANS. This means that conskbd gets raw key press/release events from the keyboard driver. The conskbd module has its own kbtrans instance which remains in the TR_ASCII mode by default (for use on the text console) until a subsequent VUIDSFORMAT or KIOCTRANS ioctl(2) from, say, a windowing system.

In practice, a key press or release event is received by the keyboard driver which passes it to kbtrans_streams_key() where it is effectively handed on to conskbd unmodified. It is then passed again to kbtrans_streams_key() by conskbd, where it is:

  • transformed from a USB scancode to a symbolic key (see sys/kbd.h)
  • (for the console) transformed by kbtrans_ascii_keypressed() to an ASCII byte sequence to effectively be passed up to stdin

The structure of the key maps in sys/kbd.h appears to reflect a world centred around the old Sun Type 3/4 keyboards. There are some comments in the sys/kbd.h and terminfo.src that suggest that the function keys were considered in groups based on their location on keyboards from that era. Of particular note: R3, the third key from the left on the top row of the right hand bank on a Sun Type 4, was labelled Scroll Lock. As such, it is represented using the macro RF(3) in the tables that translate from scancodes to symbolic keys.

Proposed Fix

In the FUNCKEYS arm of kbtrans_ascii_keypressed(), we should just drop Scroll Lock key presses (i.e., RF(3)) on the floor. This is late enough in processing that if a windowing system takes over and disables TR_ASCII mode, the system can still receive the Scroll Lock presses and (hopefully) correctly control the indicator lights as SPICE expects. This also doesn't preclude subsequent reactivation of Scroll Lock processing on the text console if somebody wants to implement an actual scrolling lock of some kind, provided they are willing to absorb the keystrokes and toggle the indicator light as expected.


Also available in: Atom PDF