mirror of
https://github.com/netbirdio/netbird.git
synced 2026-05-19 07:09:56 +00:00
275 lines
6.6 KiB
Go
275 lines
6.6 KiB
Go
//go:build !js && !ios && !android
|
|
|
|
package server
|
|
|
|
// QEMU Extended Key Event carries hardware scancodes encoded as PC AT Set 1.
|
|
// Single-byte codes cover the standard keys; the "extended" prefix 0xE0 is
|
|
// merged into the high byte (so 0xE048 is the extended-Up arrow). This file
|
|
// translates those scancodes into the per-platform identifiers each input
|
|
// backend wants:
|
|
//
|
|
// - Linux uinput wants Linux KEY_* codes (defined in
|
|
// linux/input-event-codes.h). uinput is what we use for virtual Xvfb
|
|
// sessions on Linux.
|
|
// - X11 XTest wants XKB keycodes, which on a standard layout equal
|
|
// Linux KEY_* + 8 (the per-server offset between the Linux event code
|
|
// and the X server's keycode space).
|
|
// - Windows SendInput accepts the PC AT scancode directly via
|
|
// KEYEVENTF_SCANCODE, so no mapping table is needed there; the
|
|
// extended-key bit is set when the QEMU scancode high byte is 0xE0.
|
|
// - macOS CGEventCreateKeyboardEvent takes a "virtual keycode" from
|
|
// Apple's HID set, which is unrelated to PC AT and needs its own
|
|
// table (see qemuToMacVK in input_darwin.go).
|
|
//
|
|
// Linux KEY_* codes. Only the ones we reference, since the full
|
|
// linux/input-event-codes.h list isn't useful here. Naming mirrors the
|
|
// existing constants in input_uinput_unix.go (mixed case, no underscores).
|
|
const (
|
|
keyEsc = 1
|
|
key1 = 2
|
|
key2 = 3
|
|
key3 = 4
|
|
key4 = 5
|
|
key5 = 6
|
|
key6 = 7
|
|
key7 = 8
|
|
key8 = 9
|
|
key9 = 10
|
|
key0 = 11
|
|
keyMinus = 12
|
|
keyEqual = 13
|
|
keyBackspace = 14
|
|
keyTab = 15
|
|
keyQ = 16
|
|
keyW = 17
|
|
keyE = 18
|
|
keyR = 19
|
|
keyT = 20
|
|
keyY = 21
|
|
keyU = 22
|
|
keyI = 23
|
|
keyO = 24
|
|
keyP = 25
|
|
keyLeftBracket = 26
|
|
keyRightBracket = 27
|
|
keyEnter = 28
|
|
keyLeftCtrl = 29
|
|
keyA = 30
|
|
keyS = 31
|
|
keyD = 32
|
|
keyF = 33
|
|
keyG = 34
|
|
keyH = 35
|
|
keyJ = 36
|
|
keyK = 37
|
|
keyL = 38
|
|
keySemicolon = 39
|
|
keyApostrophe = 40
|
|
keyGrave = 41
|
|
keyLeftShift = 42
|
|
keyBackslash = 43
|
|
keyZ = 44
|
|
keyX = 45
|
|
keyC = 46
|
|
keyV = 47
|
|
keyB = 48
|
|
keyN = 49
|
|
keyM = 50
|
|
keyComma = 51
|
|
keyDot = 52
|
|
keySlash = 53
|
|
keyRightShift = 54
|
|
keyKPAsterisk = 55
|
|
keyLeftAlt = 56
|
|
keySpace = 57
|
|
keyCapsLock = 58
|
|
keyF1 = 59
|
|
keyF2 = 60
|
|
keyF3 = 61
|
|
keyF4 = 62
|
|
keyF5 = 63
|
|
keyF6 = 64
|
|
keyF7 = 65
|
|
keyF8 = 66
|
|
keyF9 = 67
|
|
keyF10 = 68
|
|
keyNumLock = 69
|
|
keyScrollLock = 70
|
|
keyKP7 = 71
|
|
keyKP8 = 72
|
|
keyKP9 = 73
|
|
keyKPMinus = 74
|
|
keyKP4 = 75
|
|
keyKP5 = 76
|
|
keyKP6 = 77
|
|
keyKPPlus = 78
|
|
keyKP1 = 79
|
|
keyKP2 = 80
|
|
keyKP3 = 81
|
|
keyKP0 = 82
|
|
keyKPDot = 83
|
|
key102nd = 86
|
|
keyF11 = 87
|
|
keyF12 = 88
|
|
keyKPEnter = 96
|
|
keyRightCtrl = 97
|
|
keyKPSlash = 98
|
|
keySysRq = 99
|
|
keyRightAlt = 100
|
|
keyHome = 102
|
|
keyUp = 103
|
|
keyPageUp = 104
|
|
keyLeft = 105
|
|
keyRight = 106
|
|
keyEnd = 107
|
|
keyDown = 108
|
|
keyPageDown = 109
|
|
keyInsert = 110
|
|
keyDelete = 111
|
|
keyMute = 113
|
|
keyVolumeDown = 114
|
|
keyVolumeUp = 115
|
|
keyLeftMeta = 125
|
|
keyRightMeta = 126
|
|
keyCompose = 127
|
|
)
|
|
|
|
// qemuToLinuxKey maps the PC AT Set 1 scancode QEMU sends to a Linux KEY_*
|
|
// code. The high byte 0xE0 marks "extended" scancodes (arrows, the right-
|
|
// side modifier keys, keypad enter/divide, browser keys, etc.).
|
|
//
|
|
// Keep this table dense so a reviewer sees the whole keyboard at a glance,
|
|
// and so adding a new key is a single line.
|
|
var qemuToLinuxKey = map[uint32]int{
|
|
// Single-byte (non-extended) scancodes.
|
|
0x01: keyEsc,
|
|
0x02: key1,
|
|
0x03: key2,
|
|
0x04: key3,
|
|
0x05: key4,
|
|
0x06: key5,
|
|
0x07: key6,
|
|
0x08: key7,
|
|
0x09: key8,
|
|
0x0A: key9,
|
|
0x0B: key0,
|
|
0x0C: keyMinus,
|
|
0x0D: keyEqual,
|
|
0x0E: keyBackspace,
|
|
0x0F: keyTab,
|
|
0x10: keyQ,
|
|
0x11: keyW,
|
|
0x12: keyE,
|
|
0x13: keyR,
|
|
0x14: keyT,
|
|
0x15: keyY,
|
|
0x16: keyU,
|
|
0x17: keyI,
|
|
0x18: keyO,
|
|
0x19: keyP,
|
|
0x1A: keyLeftBracket,
|
|
0x1B: keyRightBracket,
|
|
0x1C: keyEnter,
|
|
0x1D: keyLeftCtrl,
|
|
0x1E: keyA,
|
|
0x1F: keyS,
|
|
0x20: keyD,
|
|
0x21: keyF,
|
|
0x22: keyG,
|
|
0x23: keyH,
|
|
0x24: keyJ,
|
|
0x25: keyK,
|
|
0x26: keyL,
|
|
0x27: keySemicolon,
|
|
0x28: keyApostrophe,
|
|
0x29: keyGrave,
|
|
0x2A: keyLeftShift,
|
|
0x2B: keyBackslash,
|
|
0x2C: keyZ,
|
|
0x2D: keyX,
|
|
0x2E: keyC,
|
|
0x2F: keyV,
|
|
0x30: keyB,
|
|
0x31: keyN,
|
|
0x32: keyM,
|
|
0x33: keyComma,
|
|
0x34: keyDot,
|
|
0x35: keySlash,
|
|
0x36: keyRightShift,
|
|
0x37: keyKPAsterisk,
|
|
0x38: keyLeftAlt,
|
|
0x39: keySpace,
|
|
0x3A: keyCapsLock,
|
|
0x3B: keyF1,
|
|
0x3C: keyF2,
|
|
0x3D: keyF3,
|
|
0x3E: keyF4,
|
|
0x3F: keyF5,
|
|
0x40: keyF6,
|
|
0x41: keyF7,
|
|
0x42: keyF8,
|
|
0x43: keyF9,
|
|
0x44: keyF10,
|
|
0x45: keyNumLock,
|
|
0x46: keyScrollLock,
|
|
0x47: keyKP7,
|
|
0x48: keyKP8,
|
|
0x49: keyKP9,
|
|
0x4A: keyKPMinus,
|
|
0x4B: keyKP4,
|
|
0x4C: keyKP5,
|
|
0x4D: keyKP6,
|
|
0x4E: keyKPPlus,
|
|
0x4F: keyKP1,
|
|
0x50: keyKP2,
|
|
0x51: keyKP3,
|
|
0x52: keyKP0,
|
|
0x53: keyKPDot,
|
|
0x56: key102nd,
|
|
0x57: keyF11,
|
|
0x58: keyF12,
|
|
|
|
// Extended (0xE0-prefixed) scancodes.
|
|
0xE01C: keyKPEnter,
|
|
0xE01D: keyRightCtrl,
|
|
0xE020: keyMute,
|
|
0xE02E: keyVolumeDown,
|
|
0xE030: keyVolumeUp,
|
|
0xE035: keyKPSlash,
|
|
0xE037: keySysRq, // PrintScreen
|
|
0xE038: keyRightAlt,
|
|
0xE047: keyHome,
|
|
0xE048: keyUp,
|
|
0xE049: keyPageUp,
|
|
0xE04B: keyLeft,
|
|
0xE04D: keyRight,
|
|
0xE04F: keyEnd,
|
|
0xE050: keyDown,
|
|
0xE051: keyPageDown,
|
|
0xE052: keyInsert,
|
|
0xE053: keyDelete,
|
|
0xE05B: keyLeftMeta,
|
|
0xE05C: keyRightMeta,
|
|
0xE05D: keyCompose,
|
|
}
|
|
|
|
// qemuScancodeToLinuxKey is the lookup the uinput and X11 paths use.
|
|
// Returns 0 (which Linux treats as KEY_RESERVED) when the scancode has no
|
|
// mapping, signalling "fall back to the keysym path".
|
|
func qemuScancodeToLinuxKey(scancode uint32) int {
|
|
return qemuToLinuxKey[scancode]
|
|
}
|
|
|
|
// qemuScancodeIsExtended reports whether a QEMU scancode is in the
|
|
// 0xE0-prefixed extended range. Used by Windows SendInput to set the
|
|
// KEYEVENTF_EXTENDEDKEY flag.
|
|
func qemuScancodeIsExtended(scancode uint32) bool {
|
|
return scancode&0xFF00 == 0xE000
|
|
}
|
|
|
|
// qemuScancodeLowByte returns the byte SendInput's wScan field actually
|
|
// stores: the low byte of the scancode regardless of any extended prefix.
|
|
func qemuScancodeLowByte(scancode uint32) uint16 {
|
|
return uint16(scancode & 0xFF)
|
|
}
|