X gets a VT: keyboard, terminal switching, and a way out
Xorg uses VTs only when stat("/dev/tty0") reports Linux's tty major 4.
SchOS's terminals sit under major 1, so X ran on no VT at all: the console
kept drawing over it, Ctrl+Alt+F-keys did nothing, and nothing ended the
session. stat now reports terminals under Linux's numbers.
startx picks the VT only when uname says Linux, so root's xserverrc passes
the current one itself. An xorg.conf.d file names X's input devices, since
Alpine's Xorg looks them up through udev and SchOS has none yet.
Alt+F1..F6 and Ctrl+Alt+F1..F6 now switch terminals as on Linux, alongside
the settable chord. USB keyboards gain arrows, Home/End/PgUp/PgDn/Ins/Del
and the switch keys, which the PS/2 path always had.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
parent
df1394eaa3
commit
4a7165c951
5 changed files with 123 additions and 9 deletions
|
|
@ -25,6 +25,8 @@
|
|||
#include "core/dma.h"
|
||||
#include "dev/usb.h"
|
||||
#include "dev/input.h"
|
||||
#include "dev/kbd.h"
|
||||
#include "dev/vt.h"
|
||||
|
||||
#define NHID 8
|
||||
|
||||
|
|
@ -106,7 +108,7 @@ static const uchar hid_shifted[0x39] = {
|
|||
// which means the entire line discipline is reused rather than reimplemented.
|
||||
#define KQSIZE 64
|
||||
static struct {
|
||||
uchar buf[KQSIZE];
|
||||
int buf[KQSIZE]; // characters, and KBD_* codes past KBD_SPECIAL
|
||||
uint r, w;
|
||||
} kq;
|
||||
|
||||
|
|
@ -149,6 +151,32 @@ usb_kbd_getc(void)
|
|||
}
|
||||
|
||||
// Was this usage in that report?
|
||||
// The keys past the character table, as the console names them. The PS/2
|
||||
// path has always produced these (kernel/dev/kbd.c); this one skipped every
|
||||
// usage from 0x39 up, so on a USB keyboard the console had no arrows, no
|
||||
// Home/End/PgUp/PgDn/Delete, and no way to switch terminals.
|
||||
static int
|
||||
hid_special(uchar usage, uchar mods)
|
||||
{
|
||||
// F1..F6 with Alt, AltGr or Ctrl+Alt: switch terminals, as on Linux.
|
||||
if (usage >= 0x3A && usage < 0x3A + NVT && (mods & HID_MOD_ALT) &&
|
||||
!(mods & HID_MOD_SHIFT))
|
||||
return KBD_VT_SWITCH + (usage - 0x3A);
|
||||
switch (usage) {
|
||||
case 0x49: return KBD_INS;
|
||||
case 0x4A: return KBD_HOME;
|
||||
case 0x4B: return KBD_PGUP;
|
||||
case 0x4C: return KBD_DEL;
|
||||
case 0x4D: return KBD_END;
|
||||
case 0x4E: return KBD_PGDN;
|
||||
case 0x4F: return KBD_RT;
|
||||
case 0x50: return KBD_LF;
|
||||
case 0x51: return KBD_DN;
|
||||
case 0x52: return KBD_UP;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
was_down(const uchar *prev, uchar usage)
|
||||
{
|
||||
|
|
@ -222,18 +250,23 @@ keyboard_report(struct hid *h, const uchar *rep, int len)
|
|||
for(i = 2; i < 8; i++){
|
||||
uchar usage = rep[i];
|
||||
|
||||
if(usage == 0 || usage >= 0x39)
|
||||
if(usage == 0)
|
||||
continue;
|
||||
if(was_down(h->prev, usage))
|
||||
continue; // still held from last time, not a new press
|
||||
|
||||
c = (mods & HID_MOD_SHIFT) ? hid_shifted[usage] : hid_unshifted[usage];
|
||||
if(c == 0)
|
||||
continue;
|
||||
if(usage >= 0x39){
|
||||
if((c = hid_special(usage, mods)) == 0)
|
||||
continue;
|
||||
} else {
|
||||
c = (mods & HID_MOD_SHIFT) ? hid_shifted[usage] : hid_unshifted[usage];
|
||||
if(c == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ctrl folds a letter down into its control character, which is how ^C
|
||||
// and ^D reach the line discipline at all.
|
||||
if(mods & HID_MOD_CTRL){
|
||||
if((mods & HID_MOD_CTRL) && c < KBD_SPECIAL){
|
||||
if(c >= 'a' && c <= 'z')
|
||||
c = c - 'a' + 1;
|
||||
else if(c >= 'A' && c <= 'Z')
|
||||
|
|
@ -242,6 +275,8 @@ keyboard_report(struct hid *h, const uchar *rep, int len)
|
|||
continue;
|
||||
}
|
||||
kq_put(c);
|
||||
if(c >= KBD_VT_SWITCH && c < KBD_VT_SWITCH + NVT)
|
||||
continue; // a held chord switches once
|
||||
|
||||
// The newest key is the one that repeats, as on any keyboard.
|
||||
acquire(&kqlock);
|
||||
|
|
|
|||
Loading…
Reference in a new issue