fix(windows): fix parsing of UTF-16 codepoints in eventFromRecord
This commit is contained in:
parent
49ed160268
commit
99942da4e1
1 changed files with 41 additions and 12 deletions
|
@ -135,6 +135,8 @@ pub fn nextEvent(self: *Tty) !Event {
|
||||||
pub const EventState = struct {
|
pub const EventState = struct {
|
||||||
ansi_buf: [128]u8 = undefined,
|
ansi_buf: [128]u8 = undefined,
|
||||||
ansi_idx: usize = 0,
|
ansi_idx: usize = 0,
|
||||||
|
utf16_buf: [2]u16 = undefined,
|
||||||
|
utf16_half: bool = false,
|
||||||
escape_st: bool = false,
|
escape_st: bool = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -143,16 +145,33 @@ pub fn eventFromRecord(self: *Tty, record: *const INPUT_RECORD, state: *EventSta
|
||||||
0x0001 => { // Key event
|
0x0001 => { // Key event
|
||||||
const event = record.Event.KeyEvent;
|
const event = record.Event.KeyEvent;
|
||||||
|
|
||||||
const base_layout: u21 = switch (event.wVirtualKeyCode) {
|
if (state.utf16_half) half: {
|
||||||
0x00 => { // delivered when we get an escape sequence
|
state.utf16_half = false;
|
||||||
|
state.utf16_buf[1] = event.uChar.UnicodeChar;
|
||||||
|
const codepoint: u21 = std.unicode.utf16DecodeSurrogatePair(&state.utf16_buf) catch break :half;
|
||||||
|
const n = std.unicode.utf8Encode(codepoint, &self.buf) catch return null;
|
||||||
|
|
||||||
|
const key: Key = .{
|
||||||
|
.codepoint = codepoint,
|
||||||
|
.base_layout_codepoint = codepoint,
|
||||||
|
.mods = translateMods(event.dwControlKeyState),
|
||||||
|
.text = self.buf[0..n],
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (event.bKeyDown) {
|
||||||
|
0 => return .{ .key_release = key },
|
||||||
|
else => return .{ .key_press = key },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const base_layout: u16 = switch (event.wVirtualKeyCode) {
|
||||||
|
0x00 => blk: { // delivered when we get an escape sequence or a unicode codepoint
|
||||||
state.ansi_buf[state.ansi_idx] = event.uChar.AsciiChar;
|
state.ansi_buf[state.ansi_idx] = event.uChar.AsciiChar;
|
||||||
state.ansi_idx += 1;
|
state.ansi_idx += 1;
|
||||||
if (state.ansi_idx <= 2) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
switch (state.ansi_buf[1]) {
|
switch (state.ansi_buf[1]) {
|
||||||
'[' => { // CSI, read until 0x40 to 0xFF
|
'[' => { // CSI, read until 0x40 to 0xFF
|
||||||
switch (event.uChar.AsciiChar) {
|
if (state.ansi_idx <= 2) return null;
|
||||||
|
switch (event.uChar.UnicodeChar) {
|
||||||
0x40...0xFF => {
|
0x40...0xFF => {
|
||||||
return .cap_da1;
|
return .cap_da1;
|
||||||
},
|
},
|
||||||
|
@ -160,7 +179,8 @@ pub fn eventFromRecord(self: *Tty, record: *const INPUT_RECORD, state: *EventSta
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
']' => { // OSC, read until ESC \ or BEL
|
']' => { // OSC, read until ESC \ or BEL
|
||||||
switch (event.uChar.AsciiChar) {
|
if (state.ansi_idx <= 2) return null;
|
||||||
|
switch (event.uChar.UnicodeChar) {
|
||||||
0x07 => {
|
0x07 => {
|
||||||
return .cap_da1;
|
return .cap_da1;
|
||||||
},
|
},
|
||||||
|
@ -177,8 +197,9 @@ pub fn eventFromRecord(self: *Tty, record: *const INPUT_RECORD, state: *EventSta
|
||||||
else => return null,
|
else => return null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
else => return null,
|
else => {},
|
||||||
}
|
}
|
||||||
|
break :blk event.uChar.UnicodeChar;
|
||||||
},
|
},
|
||||||
0x08 => Key.backspace,
|
0x08 => Key.backspace,
|
||||||
0x09 => Key.tab,
|
0x09 => Key.tab,
|
||||||
|
@ -271,13 +292,21 @@ pub fn eventFromRecord(self: *Tty, record: *const INPUT_RECORD, state: *EventSta
|
||||||
else => return null,
|
else => return null,
|
||||||
};
|
};
|
||||||
|
|
||||||
var codepoint: u21 = base_layout;
|
if (std.unicode.utf16IsHighSurrogate(base_layout)) {
|
||||||
|
state.utf16_buf[0] = base_layout;
|
||||||
|
state.utf16_half = true;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (std.unicode.utf16IsLowSurrogate(base_layout)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const codepoint: u21 = base_layout;
|
||||||
var text: ?[]const u8 = null;
|
var text: ?[]const u8 = null;
|
||||||
switch (event.uChar.UnicodeChar) {
|
switch (event.uChar.UnicodeChar) {
|
||||||
0x00...0x1F => {},
|
0x00...0x1F => {},
|
||||||
else => |cp| {
|
else => {
|
||||||
codepoint = cp;
|
const n = try std.unicode.utf8Encode(codepoint, &self.buf);
|
||||||
const n = try std.unicode.utf8Encode(cp, &self.buf);
|
|
||||||
text = self.buf[0..n];
|
text = self.buf[0..n];
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue