Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Has been cancelled
Go + Wails v3 + Vue 3 + SQLite + FreeRDP3 (purego) 183 tests, 76 source files, 9,910 lines of code Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
190 lines
6.6 KiB
Go
190 lines
6.6 KiB
Go
package rdp
|
|
|
|
// RDP mouse event flags — these match the MS-RDPBCGR specification.
|
|
const (
|
|
MouseFlagMove uint32 = 0x0800 // Mouse moved (no button change)
|
|
MouseFlagButton1 uint32 = 0x1000 // Left button
|
|
MouseFlagButton2 uint32 = 0x2000 // Right button
|
|
MouseFlagButton3 uint32 = 0x4000 // Middle button
|
|
MouseFlagDown uint32 = 0x8000 // Button pressed (absence = released)
|
|
|
|
// Extended mouse flags for wheel events
|
|
MouseFlagWheel uint32 = 0x0200 // Vertical wheel rotation
|
|
MouseFlagWheelNeg uint32 = 0x0100 // Negative wheel direction (scroll down)
|
|
MouseFlagHWheel uint32 = 0x0400 // Horizontal wheel rotation
|
|
)
|
|
|
|
// ScancodeMap maps JavaScript KeyboardEvent.code strings to RDP hardware
|
|
// scancodes (Set 1 / XT scan codes). This covers the standard US 104-key
|
|
// layout. Extended keys (those with a 0xE0 prefix on the wire) have the
|
|
// high byte set to 0xE0.
|
|
//
|
|
// Reference: USB HID to PS/2 scancode mapping + MS-RDPBCGR 2.2.8.1.1.3.1.1.1
|
|
var ScancodeMap = map[string]uint32{
|
|
// ── Row 0: Escape + Function keys ──────────────────────────────
|
|
"Escape": 0x0001,
|
|
"F1": 0x003B,
|
|
"F2": 0x003C,
|
|
"F3": 0x003D,
|
|
"F4": 0x003E,
|
|
"F5": 0x003F,
|
|
"F6": 0x0040,
|
|
"F7": 0x0041,
|
|
"F8": 0x0042,
|
|
"F9": 0x0043,
|
|
"F10": 0x0044,
|
|
"F11": 0x0057,
|
|
"F12": 0x0058,
|
|
|
|
// ── Row 1: Number row ──────────────────────────────────────────
|
|
"Backquote": 0x0029, // ` ~
|
|
"Digit1": 0x0002,
|
|
"Digit2": 0x0003,
|
|
"Digit3": 0x0004,
|
|
"Digit4": 0x0005,
|
|
"Digit5": 0x0006,
|
|
"Digit6": 0x0007,
|
|
"Digit7": 0x0008,
|
|
"Digit8": 0x0009,
|
|
"Digit9": 0x000A,
|
|
"Digit0": 0x000B,
|
|
"Minus": 0x000C, // - _
|
|
"Equal": 0x000D, // = +
|
|
"Backspace": 0x000E,
|
|
|
|
// ── Row 2: QWERTY row ─────────────────────────────────────────
|
|
"Tab": 0x000F,
|
|
"KeyQ": 0x0010,
|
|
"KeyW": 0x0011,
|
|
"KeyE": 0x0012,
|
|
"KeyR": 0x0013,
|
|
"KeyT": 0x0014,
|
|
"KeyY": 0x0015,
|
|
"KeyU": 0x0016,
|
|
"KeyI": 0x0017,
|
|
"KeyO": 0x0018,
|
|
"KeyP": 0x0019,
|
|
"BracketLeft": 0x001A, // [ {
|
|
"BracketRight":0x001B, // ] }
|
|
"Backslash": 0x002B, // \ |
|
|
|
|
// ── Row 3: Home row ───────────────────────────────────────────
|
|
"CapsLock": 0x003A,
|
|
"KeyA": 0x001E,
|
|
"KeyS": 0x001F,
|
|
"KeyD": 0x0020,
|
|
"KeyF": 0x0021,
|
|
"KeyG": 0x0022,
|
|
"KeyH": 0x0023,
|
|
"KeyJ": 0x0024,
|
|
"KeyK": 0x0025,
|
|
"KeyL": 0x0026,
|
|
"Semicolon": 0x0027, // ; :
|
|
"Quote": 0x0028, // ' "
|
|
"Enter": 0x001C,
|
|
|
|
// ── Row 4: Bottom row ─────────────────────────────────────────
|
|
"ShiftLeft": 0x002A,
|
|
"KeyZ": 0x002C,
|
|
"KeyX": 0x002D,
|
|
"KeyC": 0x002E,
|
|
"KeyV": 0x002F,
|
|
"KeyB": 0x0030,
|
|
"KeyN": 0x0031,
|
|
"KeyM": 0x0032,
|
|
"Comma": 0x0033, // , <
|
|
"Period": 0x0034, // . >
|
|
"Slash": 0x0035, // / ?
|
|
"ShiftRight": 0x0036,
|
|
|
|
// ── Row 5: Bottom modifiers + space ───────────────────────────
|
|
"ControlLeft": 0x001D,
|
|
"MetaLeft": 0xE05B, // Left Windows / Super
|
|
"AltLeft": 0x0038,
|
|
"Space": 0x0039,
|
|
"AltRight": 0xE038, // Right Alt (extended)
|
|
"MetaRight": 0xE05C, // Right Windows / Super
|
|
"ContextMenu": 0xE05D, // Application / Menu key
|
|
"ControlRight": 0xE01D, // Right Ctrl (extended)
|
|
|
|
// ── Navigation cluster ────────────────────────────────────────
|
|
"PrintScreen": 0xE037,
|
|
"ScrollLock": 0x0046,
|
|
"Pause": 0x0045, // Note: Pause has special handling on wire
|
|
"Insert": 0xE052,
|
|
"Home": 0xE047,
|
|
"PageUp": 0xE049,
|
|
"Delete": 0xE053,
|
|
"End": 0xE04F,
|
|
"PageDown": 0xE051,
|
|
|
|
// ── Arrow keys ────────────────────────────────────────────────
|
|
"ArrowUp": 0xE048,
|
|
"ArrowLeft": 0xE04B,
|
|
"ArrowDown": 0xE050,
|
|
"ArrowRight": 0xE04D,
|
|
|
|
// ── Numpad ────────────────────────────────────────────────────
|
|
"NumLock": 0x0045,
|
|
"NumpadDivide": 0xE035,
|
|
"NumpadMultiply":0x0037,
|
|
"NumpadSubtract":0x004A,
|
|
"Numpad7": 0x0047,
|
|
"Numpad8": 0x0048,
|
|
"Numpad9": 0x0049,
|
|
"NumpadAdd": 0x004E,
|
|
"Numpad4": 0x004B,
|
|
"Numpad5": 0x004C,
|
|
"Numpad6": 0x004D,
|
|
"Numpad1": 0x004F,
|
|
"Numpad2": 0x0050,
|
|
"Numpad3": 0x0051,
|
|
"NumpadEnter": 0xE01C,
|
|
"Numpad0": 0x0052,
|
|
"NumpadDecimal": 0x0053,
|
|
|
|
// ── Multimedia / browser keys (common on 104+ key layouts) ───
|
|
"BrowserBack": 0xE06A,
|
|
"BrowserForward": 0xE069,
|
|
"BrowserRefresh": 0xE067,
|
|
"BrowserStop": 0xE068,
|
|
"BrowserSearch": 0xE065,
|
|
"BrowserFavorites":0xE066,
|
|
"BrowserHome": 0xE032,
|
|
"VolumeMute": 0xE020,
|
|
"VolumeDown": 0xE02E,
|
|
"VolumeUp": 0xE030,
|
|
"MediaTrackNext": 0xE019,
|
|
"MediaTrackPrevious":0xE010,
|
|
"MediaStop": 0xE024,
|
|
"MediaPlayPause": 0xE022,
|
|
"LaunchMail": 0xE06C,
|
|
"LaunchApp1": 0xE06B,
|
|
"LaunchApp2": 0xE021,
|
|
|
|
// ── International keys ────────────────────────────────────────
|
|
"IntlBackslash": 0x0056, // key between left Shift and Z on ISO keyboards
|
|
"IntlYen": 0x007D, // Yen key on Japanese keyboards
|
|
"IntlRo": 0x0073, // Ro key on Japanese keyboards
|
|
}
|
|
|
|
// JSKeyToScancode translates a JavaScript KeyboardEvent.code string to an
|
|
// RDP hardware scancode. Returns the scancode and true if a mapping exists,
|
|
// or 0 and false for unmapped keys.
|
|
func JSKeyToScancode(jsCode string) (uint32, bool) {
|
|
sc, ok := ScancodeMap[jsCode]
|
|
return sc, ok
|
|
}
|
|
|
|
// IsExtendedKey returns true if the scancode has the 0xE0 extended prefix.
|
|
// Extended keys require a two-byte sequence on the RDP wire.
|
|
func IsExtendedKey(scancode uint32) bool {
|
|
return (scancode & 0xFF00) == 0xE000
|
|
}
|
|
|
|
// ScancodeValue returns the low byte of the scancode (the actual scan code
|
|
// value without the extended prefix).
|
|
func ScancodeValue(scancode uint32) uint8 {
|
|
return uint8(scancode & 0xFF)
|
|
}
|