SchOS/include/dev/kbd.h
Nexoniarz 2372806862 Job control, function keys, and real sleeps
- SIGSTOP/SIGTSTP/SIGTTIN/SIGTTOU stop, SIGCONT resumes; the parent gets
  SIGCHLD and wait4 reports WUNTRACED/WCONTINUED; ps shows T. Ctrl-Z works,
  and mc no longer hangs waiting for its subshell to stop.
- Blocking reads (console, pty, pipe) and sleeps take a pending stop and
  carry on after SIGCONT; a caught signal without SA_RESTART ends them
  with EINTR.
- nanosleep reads tv_nsec (sleep 0.5 used to return at once), writes the
  remainder, and clock_nanosleep understands TIMER_ABSTIME.
- rt_sigaction uses the k_sigaction layout for Linux-ABI processes: the old
  action's restorer was written 112 bytes past the caller's struct. Flags
  are kept; SIGKILL and SIGSTOP cannot be caught.
- F1..F12 reach programs, as the Linux console sends them (PS/2, USB, I2C).
- TIOCLINUX subcode 6 answers "no modifiers" instead of echoing the 6 back.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
2026-10-25 02:37:45 +01:00

118 lines
5.1 KiB
C

// PC keyboard interface constants
//
// The scancode tables themselves are no longer here. They moved to
// kernel/dev/keymap.c when there became more than one of them -- a header
// full of `static` arrays gives every file that includes it its own private
// copy, which was harmless while exactly one file did.
#ifndef KBD_H
#define KBD_H
#define KBSTATP 0x64 // kbd controller status port(I)
#define KBS_DIB 0x01 // kbd data in buffer
#define KBDATAP 0x60 // kbd data port(I)
#define NO 0
#define SHIFT (1<<0)
#define CTL (1<<1)
#define ALT (1<<2)
#define CAPSLOCK (1<<3)
#define NUMLOCK (1<<4)
#define SCROLLLOCK (1<<5)
#define E0ESC (1<<6)
// Right Alt, tracked apart from left Alt.
//
// They used to be the same bit, which is fine for typing -- neither is used to
// look up a character -- and wrong for chords. On a Polish layout AltGr is how
// you type a c e l n o s x z with their diacritics, and it is held constantly.
// Nothing the kernel binds may involve it.
#define RALT (1<<7)
// Special keycodes.
//
// **Above every Unicode codepoint, deliberately**, and they did not use to be:
// KBD_UP was 0xE2 and its neighbours filled 0xE0..0xE9. Those are exactly the
// UTF-8 lead bytes for three-byte characters, so typing any of U+0800..U+FFFF
// -- which is most punctuation, every arrow, every maths symbol, and the whole
// of CJK -- produced a keycode the console read as an arrow key and turned
// into `ESC [ A`. `∞`, `→`, `≤` and `'` all vanished from the input line while
// `ą` and `ę` came through, because those are two-byte sequences whose lead
// byte is 0xC4 and nothing claimed 0xC4.
//
// The chord codes below already knew this rule and said so; the navigation
// keys predate them and were never brought in line. The rule, stated once: a
// value that a key produces is either a Unicode codepoint or it is above
// 0x10FFFF, and nothing in between means anything.
#define KBD_SPECIAL 0x110000
#define KBD_HOME (KBD_SPECIAL + 0x00)
#define KBD_END (KBD_SPECIAL + 0x01)
#define KBD_UP (KBD_SPECIAL + 0x02)
#define KBD_DN (KBD_SPECIAL + 0x03)
#define KBD_LF (KBD_SPECIAL + 0x04)
#define KBD_RT (KBD_SPECIAL + 0x05)
#define KBD_PGUP (KBD_SPECIAL + 0x06)
#define KBD_PGDN (KBD_SPECIAL + 0x07)
#define KBD_INS (KBD_SPECIAL + 0x08)
#define KBD_DEL (KBD_SPECIAL + 0x09)
// F1..F12, consecutive: KBD_F1 + n is F(n+1).
#define KBD_F1 (KBD_SPECIAL + 0x10)
#define KBD_F12 (KBD_SPECIAL + 0x1B)
// Switch virtual terminal.
//
// *Which* chord is a runtime setting, not a constant here, and that is the
// interesting part. Three separate parties have a claim on every candidate:
//
// the HOST, which sees the keystroke first and may never pass it on
// Alt+F4, Alt+F2 window manager
// Ctrl+Alt+F1..F6 display manager, and it matches loosely --
// adding Shift does not get past it
// Ctrl+Alt+<digit> QEMU's own console tabs
//
// APPLICATIONS, which lose the key permanently if the kernel eats it
// Alt+<anything> Meta. zsh binds Meta-digit as digit-argument
// Ctrl+<letter> control characters
// Ctrl+Shift+<digit> types a character -- Ctrl+Shift+2 is ^@
// F1..F6 alone help, and full-screen programs
//
// the KEYBOARD LAYOUT
// AltGr+<letter> Polish diacritics, and on some setups AltGr
// arrives as Ctrl+Alt
//
// There is no combination that is free for everyone on every host, and the
// guest cannot find out what its host grabs -- the keystroke simply never
// arrives, which is indistinguishable from a chord nobody pressed. So the
// kernel ships a default and lets it be changed: VT_SETCHORD, and `chvt -c`
// in userspace. Setting it to no modifiers disables the chord entirely and
// leaves `chvt N` as the only way to switch, which is a legitimate choice on
// a machine whose host takes everything.
//
// The default is AltGr+F1..F6, and the "AltGr wants it" line above needs
// reading carefully: what a Polish layout wants is AltGr+*letter*. AltGr with
// a function key produces nothing on any layout, no window manager binds it,
// and no application asks for it. Right Alt being a separate modifier bit
// here is what makes the distinction expressible at all -- it used to share
// ALT, which is harmless for typing and useless for this.
#define KBD_VT_SWITCH (KBD_SPECIAL + 0x20)
// Previous / next terminal, on the same modifiers as the chord above. The
// minus and equals keys, which sit together and read as - and + -- a relative
// move for when you have two terminals and do not care which number they are.
#define KBD_VT_PREV (KBD_SPECIAL + 0x30)
#define KBD_VT_NEXT (KBD_SPECIAL + 0x31)
#define SCAN_MINUS 0x0C // - / _
#define SCAN_EQUALS 0x0D // = / +
#define SCAN_F1 0x3B // F1..F6 are scancodes 0x3B..0x40
#define SCAN_1 0x02 // 1..6 are scancodes 0x02..0x07
// C('A') == Control-A
#define C(x) (x - '@')
#endif /* KBD_H */