this repo has no description
13
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(windows): fix parsing of UTF-16 codepoints in eventFromRecord

authored by

CJ van den Berg and committed by
Tim Culverhouse
99942da4 49ed1602

+41 -12
+41 -12
src/windows/Tty.zig
··· 135 135 pub const EventState = struct { 136 136 ansi_buf: [128]u8 = undefined, 137 137 ansi_idx: usize = 0, 138 + utf16_buf: [2]u16 = undefined, 139 + utf16_half: bool = false, 138 140 escape_st: bool = false, 139 141 }; 140 142 ··· 143 145 0x0001 => { // Key event 144 146 const event = record.Event.KeyEvent; 145 147 146 - const base_layout: u21 = switch (event.wVirtualKeyCode) { 147 - 0x00 => { // delivered when we get an escape sequence 148 + if (state.utf16_half) half: { 149 + state.utf16_half = false; 150 + state.utf16_buf[1] = event.uChar.UnicodeChar; 151 + const codepoint: u21 = std.unicode.utf16DecodeSurrogatePair(&state.utf16_buf) catch break :half; 152 + const n = std.unicode.utf8Encode(codepoint, &self.buf) catch return null; 153 + 154 + const key: Key = .{ 155 + .codepoint = codepoint, 156 + .base_layout_codepoint = codepoint, 157 + .mods = translateMods(event.dwControlKeyState), 158 + .text = self.buf[0..n], 159 + }; 160 + 161 + switch (event.bKeyDown) { 162 + 0 => return .{ .key_release = key }, 163 + else => return .{ .key_press = key }, 164 + } 165 + } 166 + 167 + const base_layout: u16 = switch (event.wVirtualKeyCode) { 168 + 0x00 => blk: { // delivered when we get an escape sequence or a unicode codepoint 148 169 state.ansi_buf[state.ansi_idx] = event.uChar.AsciiChar; 149 170 state.ansi_idx += 1; 150 - if (state.ansi_idx <= 2) { 151 - return null; 152 - } 153 171 switch (state.ansi_buf[1]) { 154 172 '[' => { // CSI, read until 0x40 to 0xFF 155 - switch (event.uChar.AsciiChar) { 173 + if (state.ansi_idx <= 2) return null; 174 + switch (event.uChar.UnicodeChar) { 156 175 0x40...0xFF => { 157 176 return .cap_da1; 158 177 }, ··· 160 179 } 161 180 }, 162 181 ']' => { // OSC, read until ESC \ or BEL 163 - switch (event.uChar.AsciiChar) { 182 + if (state.ansi_idx <= 2) return null; 183 + switch (event.uChar.UnicodeChar) { 164 184 0x07 => { 165 185 return .cap_da1; 166 186 }, ··· 177 197 else => return null, 178 198 } 179 199 }, 180 - else => return null, 200 + else => {}, 181 201 } 202 + break :blk event.uChar.UnicodeChar; 182 203 }, 183 204 0x08 => Key.backspace, 184 205 0x09 => Key.tab, ··· 271 292 else => return null, 272 293 }; 273 294 274 - var codepoint: u21 = base_layout; 295 + if (std.unicode.utf16IsHighSurrogate(base_layout)) { 296 + state.utf16_buf[0] = base_layout; 297 + state.utf16_half = true; 298 + return null; 299 + } 300 + if (std.unicode.utf16IsLowSurrogate(base_layout)) { 301 + return null; 302 + } 303 + 304 + const codepoint: u21 = base_layout; 275 305 var text: ?[]const u8 = null; 276 306 switch (event.uChar.UnicodeChar) { 277 307 0x00...0x1F => {}, 278 - else => |cp| { 279 - codepoint = cp; 280 - const n = try std.unicode.utf8Encode(cp, &self.buf); 308 + else => { 309 + const n = try std.unicode.utf8Encode(codepoint, &self.buf); 281 310 text = self.buf[0..n]; 282 311 }, 283 312 }