this repo has no description
13
fork

Configure Feed

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

get windows build working on Zig 0.16

authored by

Jeffrey C. Ollie and committed by
Tim Culverhouse
9f0e6583 5e39d991

+163 -79
+2
examples/vt.zig
··· 104 104 } 105 105 106 106 test { 107 + const builtin = @import("builtin"); 108 + if (builtin.os.tag == .windows) return error.SkipZigTest; 107 109 std.testing.refAllDecls(@This()); 108 110 }
+3 -1
src/Loop.zig
··· 114 114 const TtyRunError = error{ 115 115 AccessDenied, 116 116 Canceled, 117 + CodepointTooLarge, 117 118 ConnectionResetByPeer, 118 119 EndOfStream, 119 120 InputOutput, ··· 131 132 SocketUnconnected, 132 133 SystemResources, 133 134 Unexpected, 135 + Utf8CannotEncodeSurrogateHalf, 134 136 WouldBlock, 135 137 }; 136 138 ··· 251 253 } 252 254 }, 253 255 .cap_da1 => { 254 - std.Thread.Futex.wake(&vx.query_futex, 10); 256 + std.Io.futexWake(vx.io, std.atomic.Value(u32), &vx.query_futex, 10); 255 257 vx.queries_done.store(true, .unordered); 256 258 }, 257 259 .mouse => |mouse| {
+158 -78
src/tty.zig
··· 205 205 buf: [4]u8 = undefined, 206 206 207 207 /// File.Writer for efficient buffered writing 208 - tty_writer: std.fs.File.Writer, 208 + tty_writer: std.Io.File.Writer, 209 209 210 210 /// The last mouse button that was pressed. We store the previous state of button presses on each 211 211 /// mouse event so we can detect which button was released ··· 228 228 .ENABLE_LVB_GRID_WORLDWIDE = 1, // enables reverse video and underline 229 229 }; 230 230 231 - pub fn init(buffer: []u8) !Tty { 232 - const stdin: std.fs.File = .stdin(); 233 - const stdout: std.fs.File = .stdout(); 231 + pub fn init(io: std.Io, buffer: []u8) !WindowsTty { 232 + const stdin: std.Io.File = .stdin(); 233 + const stdout: std.Io.File = .stdout(); 234 234 235 235 // get initial modes 236 - const initial_output_codepage = windows.kernel32.GetConsoleOutputCP(); 236 + const initial_output_codepage = GetConsoleOutputCP(); 237 237 const initial_input_mode = try getConsoleMode(CONSOLE_MODE_INPUT, stdin.handle); 238 238 const initial_output_mode = try getConsoleMode(CONSOLE_MODE_OUTPUT, stdout.handle); 239 239 240 240 // set new modes 241 241 try setConsoleMode(stdin.handle, input_raw_mode); 242 242 try setConsoleMode(stdout.handle, output_raw_mode); 243 - if (windows.kernel32.SetConsoleOutputCP(utf8_codepage) == 0) 244 - return windows.unexpectedError(windows.kernel32.GetLastError()); 243 + if (SetConsoleOutputCP(utf8_codepage) == .FALSE) 244 + return windows.unexpectedError(windows.GetLastError()); 245 245 246 - const self: Tty = .{ 246 + const self: WindowsTty = .{ 247 247 .stdin = stdin.handle, 248 248 .stdout = stdout.handle, 249 249 .initial_codepage = initial_output_codepage, 250 250 .initial_input_mode = initial_input_mode, 251 251 .initial_output_mode = initial_output_mode, 252 - .tty_writer = .initStreaming(stdout, buffer), 252 + .tty_writer = .initStreaming(stdout, io, buffer), 253 253 }; 254 254 255 255 // save a copy of this tty as the global_tty for panic handling ··· 258 258 return self; 259 259 } 260 260 261 - pub fn deinit(self: Tty) void { 262 - _ = windows.kernel32.SetConsoleOutputCP(self.initial_codepage); 261 + pub fn deinit(self: WindowsTty) void { 262 + _ = SetConsoleOutputCP(self.initial_codepage); 263 263 setConsoleMode(self.stdin, self.initial_input_mode) catch {}; 264 264 setConsoleMode(self.stdout, self.initial_output_mode) catch {}; 265 265 windows.CloseHandle(self.stdin); ··· 279 279 VIRTUAL_TERMINAL_INPUT: u1 = 0, 280 280 _: u22 = 0, 281 281 }; 282 + 282 283 pub const CONSOLE_MODE_OUTPUT = packed struct(u32) { 283 284 PROCESSED_OUTPUT: u1 = 0, 284 285 WRAP_AT_EOL_OUTPUT: u1 = 0, ··· 290 291 291 292 pub fn getConsoleMode(comptime T: type, handle: windows.HANDLE) !T { 292 293 var mode: u32 = undefined; 293 - if (windows.kernel32.GetConsoleMode(handle, &mode) == 0) return switch (windows.kernel32.GetLastError()) { 294 + if (GetConsoleMode(handle, &mode) == .FALSE) return switch (windows.GetLastError()) { 294 295 .INVALID_HANDLE => error.InvalidHandle, 295 296 else => |e| windows.unexpectedError(e), 296 297 }; ··· 298 299 } 299 300 300 301 pub fn setConsoleMode(handle: windows.HANDLE, mode: anytype) !void { 301 - if (windows.kernel32.SetConsoleMode(handle, @bitCast(mode)) == 0) return switch (windows.kernel32.GetLastError()) { 302 + if (SetConsoleMode(handle, @bitCast(mode)) == .FALSE) return switch (windows.GetLastError()) { 302 303 .INVALID_HANDLE => error.InvalidHandle, 303 304 else => |e| windows.unexpectedError(e), 304 305 }; 305 306 } 306 307 307 - pub fn writer(self: *Tty) *std.Io.Writer { 308 + pub fn writer(self: *WindowsTty) *std.Io.Writer { 308 309 return &self.tty_writer.interface; 309 310 } 310 311 311 - pub fn read(self: *const Tty, buf: []u8) !usize { 312 + pub fn read(self: *const WindowsTty, buf: []u8) !usize { 312 313 return posix.read(self.fd, buf); 313 314 } 314 315 315 - pub fn nextEvent(self: *Tty, parser: *Parser, paste_allocator: ?std.mem.Allocator) !Event { 316 + pub fn nextEvent(self: *WindowsTty, parser: *Parser, paste_allocator: ?std.mem.Allocator) !Event { 316 317 // We use a loop so we can ignore certain events 317 318 var state: EventState = .{}; 318 319 while (true) { 319 320 var event_count: u32 = 0; 320 321 var input_record: INPUT_RECORD = undefined; 321 - if (ReadConsoleInputW(self.stdin, &input_record, 1, &event_count) == 0) 322 - return windows.unexpectedError(windows.kernel32.GetLastError()); 322 + if (ReadConsoleInputW(self.stdin, &input_record, 1, &event_count) == .FALSE) 323 + return windows.unexpectedError(windows.GetLastError()); 323 324 324 325 if (try self.eventFromRecord(&input_record, &state, parser, paste_allocator)) |ev| { 325 326 return ev; ··· 334 335 utf16_half: bool = false, 335 336 }; 336 337 337 - pub fn eventFromRecord(self: *Tty, record: *const INPUT_RECORD, state: *EventState, parser: *Parser, paste_allocator: ?std.mem.Allocator) !?Event { 338 + pub const SMALL_RECT = extern struct { 339 + Left: windows.SHORT, 340 + Top: windows.SHORT, 341 + Right: windows.SHORT, 342 + Bottom: windows.SHORT, 343 + }; 344 + 345 + pub const COORD = extern struct { 346 + X: windows.SHORT, 347 + Y: windows.SHORT, 348 + }; 349 + 350 + pub const CONSOLE_SCREEN_BUFFER_INFO = extern struct { 351 + dwSize: COORD, 352 + dwCursorPosition: COORD, 353 + wAttributes: windows.WORD, 354 + srWindow: SMALL_RECT, 355 + dwMaximumWindowSize: COORD, 356 + }; 357 + 358 + pub fn eventFromRecord(self: *WindowsTty, record: *const INPUT_RECORD, state: *EventState, parser: *Parser, paste_allocator: ?std.mem.Allocator) !?Event { 338 359 switch (record.EventType) { 339 360 0x0001 => { // Key event 340 361 const event = record.Event.KeyEvent; ··· 353 374 }; 354 375 355 376 switch (event.bKeyDown) { 356 - 0 => return .{ .key_release = key }, 377 + .FALSE => return .{ .key_release = key }, 357 378 else => return .{ .key_press = key }, 358 379 } 359 380 } ··· 499 520 }; 500 521 501 522 switch (event.bKeyDown) { 502 - 0 => return .{ .key_release = key }, 523 + .FALSE => return .{ .key_release = key }, 503 524 else => return .{ .key_press = key }, 504 525 } 505 526 }, ··· 594 615 0x0004 => { // Screen resize events 595 616 // NOTE: Even though the event comes with a size, it may not be accurate. We ask for 596 617 // the size directly when we get this event 597 - var console_info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined; 598 - if (windows.kernel32.GetConsoleScreenBufferInfo(self.stdout, &console_info) == 0) { 599 - return windows.unexpectedError(windows.kernel32.GetLastError()); 618 + var console_info: CONSOLE_SCREEN_BUFFER_INFO = undefined; 619 + if (GetConsoleScreenBufferInfo(self.stdout, &console_info) == .FALSE) { 620 + return windows.unexpectedError(windows.GetLastError()); 600 621 } 601 622 const window_rect = console_info.srWindow; 602 623 const width = window_rect.Right - window_rect.Left + 1; ··· 612 633 }, 613 634 0x0010 => { // Focus events 614 635 switch (record.Event.FocusEvent.bSetFocus) { 615 - 0 => return .focus_out, 636 + .FALSE => return .focus_out, 616 637 else => return .focus_in, 617 638 } 618 639 }, ··· 642 663 }; 643 664 } 644 665 666 + pub fn getWinsize(self: *WindowsTty) !Winsize { 667 + var console_info: CONSOLE_SCREEN_BUFFER_INFO = undefined; 668 + if (GetConsoleScreenBufferInfo(self.stdout, &console_info) == .FALSE) { 669 + return windows.unexpectedError(windows.GetLastError()); 670 + } 671 + const window_rect = console_info.srWindow; 672 + const width = window_rect.Right - window_rect.Left + 1; 673 + const height = window_rect.Bottom - window_rect.Top + 1; 674 + return .{ 675 + .cols = @intCast(width), 676 + .rows = @intCast(height), 677 + .x_pixel = 0, 678 + .y_pixel = 0, 679 + }; 680 + } 681 + 645 682 // From gitub.com/ziglibs/zig-windows-console. Thanks :) 646 683 // 647 684 // Events ··· 649 686 UnicodeChar: windows.WCHAR, 650 687 AsciiChar: windows.CHAR, 651 688 }; 689 + 652 690 pub const KEY_EVENT_RECORD = extern struct { 653 691 bKeyDown: windows.BOOL, 654 692 wRepeatCount: windows.WORD, ··· 657 695 uChar: union_unnamed_248, 658 696 dwControlKeyState: windows.DWORD, 659 697 }; 698 + 660 699 pub const PKEY_EVENT_RECORD = *KEY_EVENT_RECORD; 661 700 662 701 pub const MOUSE_EVENT_RECORD = extern struct { ··· 665 704 dwControlKeyState: windows.DWORD, 666 705 dwEventFlags: windows.DWORD, 667 706 }; 707 + 668 708 pub const PMOUSE_EVENT_RECORD = *MOUSE_EVENT_RECORD; 669 709 670 710 pub const WINDOW_BUFFER_SIZE_RECORD = extern struct { 671 711 dwSize: windows.COORD, 672 712 }; 713 + 673 714 pub const PWINDOW_BUFFER_SIZE_RECORD = *WINDOW_BUFFER_SIZE_RECORD; 674 715 675 716 pub const MENU_EVENT_RECORD = extern struct { 676 717 dwCommandId: windows.UINT, 677 718 }; 719 + 678 720 pub const PMENU_EVENT_RECORD = *MENU_EVENT_RECORD; 679 721 680 722 pub const FOCUS_EVENT_RECORD = extern struct { 681 723 bSetFocus: windows.BOOL, 682 724 }; 725 + 683 726 pub const PFOCUS_EVENT_RECORD = *FOCUS_EVENT_RECORD; 684 727 685 728 const union_unnamed_249 = extern union { ··· 689 732 MenuEvent: MENU_EVENT_RECORD, 690 733 FocusEvent: FOCUS_EVENT_RECORD, 691 734 }; 735 + 692 736 pub const INPUT_RECORD = extern struct { 693 737 EventType: windows.WORD, 694 738 Event: union_unnamed_249, 695 739 }; 740 + 696 741 pub const PINPUT_RECORD = *INPUT_RECORD; 697 742 698 743 pub extern "kernel32" fn ReadConsoleInputW(hConsoleInput: windows.HANDLE, lpBuffer: PINPUT_RECORD, nLength: windows.DWORD, lpNumberOfEventsRead: *windows.DWORD) callconv(.winapi) windows.BOOL; 744 + pub extern "kernel32" fn GetConsoleOutputCP() callconv(.winapi) windows.UINT; 745 + pub extern "kernel32" fn GetConsoleMode(kConsoleHandle: windows.HANDLE, lpMode: *windows.DWORD) callconv(.winapi) windows.BOOL; 746 + pub extern "kernel32" fn SetConsoleMode(hConsoleHandle: windows.HANDLE, dwMode: windows.DWORD) callconv(.winapi) windows.BOOL; 747 + pub extern "kernel32" fn SetConsoleOutputCP(wCodePageId: windows.UINT) callconv(.winapi) windows.BOOL; 748 + pub extern "kernel32" fn GetConsoleScreenBufferInfo(hConsoleOutpur: windows.HANDLE, lpConsoleScreenBufferInfo: *CONSOLE_SCREEN_BUFFER_INFO) callconv(.winapi) windows.BOOL; 699 749 }; 700 750 701 - pub const TestTty = struct { 702 - const linux = std.os.linux; 703 - /// Used for API compat 704 - fd: posix.fd_t, 705 - pipe_read: posix.fd_t, 706 - pipe_write: posix.fd_t, 707 - tty_writer: *std.Io.Writer.Allocating, 751 + pub const TestTty = switch (builtin.os.tag) { 752 + .linux => struct { 753 + const linux = std.os.linux; 754 + /// Used for API compat 755 + fd: posix.fd_t, 756 + pipe_read: posix.fd_t, 757 + pipe_write: posix.fd_t, 758 + tty_writer: *std.Io.Writer.Allocating, 708 759 709 - /// Initializes a TestTty. 710 - pub fn init(_: std.Io, buffer: []u8) !TestTty { 711 - _ = buffer; 760 + /// Initializes a TestTty. 761 + pub fn init(_: std.Io, buffer: []u8) !@This() { 762 + _ = buffer; 712 763 713 - if (builtin.os.tag != .linux) return error.SkipZigTest; 714 - const list = try std.testing.allocator.create(std.Io.Writer.Allocating); 715 - list.* = .init(std.testing.allocator); 716 - var fds: [2]i32 = undefined; 717 - const rc = linux.pipe(&fds); 718 - switch (linux.errno(rc)) { 719 - .SUCCESS => {}, 720 - else => return error.PipeCreateFailed, 764 + const list = try std.testing.allocator.create(std.Io.Writer.Allocating); 765 + list.* = .init(std.testing.allocator); 766 + var fds: [2]i32 = undefined; 767 + const rc = linux.pipe(&fds); 768 + switch (linux.errno(rc)) { 769 + .SUCCESS => {}, 770 + else => return error.PipeCreateFailed, 771 + } 772 + return .{ 773 + .fd = fds[0], 774 + .pipe_read = fds[0], 775 + .pipe_write = fds[1], 776 + .tty_writer = list, 777 + }; 721 778 } 722 - return .{ 723 - .fd = fds[0], 724 - .pipe_read = fds[0], 725 - .pipe_write = fds[1], 726 - .tty_writer = list, 727 - }; 728 - } 729 779 730 - pub fn deinit(self: TestTty) void { 731 - _ = linux.close(self.pipe_read); 732 - _ = linux.close(self.pipe_write); 733 - self.tty_writer.deinit(); 734 - std.testing.allocator.destroy(self.tty_writer); 735 - } 780 + pub fn deinit(self: *@This()) void { 781 + _ = linux.close(self.pipe_read); 782 + _ = linux.close(self.pipe_write); 783 + self.tty_writer.deinit(); 784 + std.testing.allocator.destroy(self.tty_writer); 785 + } 736 786 737 - pub fn writer(self: *TestTty) *std.Io.Writer { 738 - return &self.tty_writer.writer; 739 - } 787 + pub fn writer(self: *@This()) *std.Io.Writer { 788 + return &self.tty_writer.writer; 789 + } 740 790 741 - pub fn read(self: *const TestTty, buf: []u8) !usize { 742 - return posix.read(self.fd, buf); 743 - } 791 + pub fn read(self: *const @This(), buf: []u8) !usize { 792 + return posix.read(self.fd, buf); 793 + } 744 794 745 - /// Get the window size from the kernel 746 - pub fn getWinsize(_: posix.fd_t) !Winsize { 747 - return .{ 748 - .rows = 40, 749 - .cols = 80, 750 - .x_pixel = 40 * 8, 751 - .y_pixel = 40 * 8 * 2, 752 - }; 753 - } 795 + /// Get the window size from the kernel 796 + pub fn getWinsize(_: *@This()) !Winsize { 797 + return .{ 798 + .rows = 40, 799 + .cols = 80, 800 + .x_pixel = 40 * 8, 801 + .y_pixel = 40 * 8 * 2, 802 + }; 803 + } 804 + 805 + /// Implemented for the Windows API 806 + pub fn nextEvent(_: *@This(), _: *Parser, _: ?std.mem.Allocator) !Event { 807 + return error.SkipZigTest; 808 + } 809 + 810 + pub fn resetSignalHandler() void { 811 + return; 812 + } 813 + }, 814 + else => struct { 815 + d: std.Io.Writer.Discarding, 816 + 817 + pub fn init(_: std.Io, buf: []u8) !@This() { 818 + return .{ 819 + .d = .init(buf), 820 + }; 821 + } 822 + 823 + pub fn deinit(_: *const @This()) void {} 824 + 825 + pub fn writer(self: *@This()) *std.Io.Writer { 826 + return &self.d.writer; 827 + } 754 828 755 - /// Implemented for the Windows API 756 - pub fn nextEvent(_: *Tty, _: *Parser, _: ?std.mem.Allocator) !Event { 757 - return error.SkipZigTest; 758 - } 829 + pub fn getWinsize(_: *@This()) !Winsize { 830 + return .{ 831 + .rows = 40, 832 + .cols = 80, 833 + .x_pixel = 40 * 8, 834 + .y_pixel = 40 * 8 * 2, 835 + }; 836 + } 759 837 760 - pub fn resetSignalHandler() void { 761 - return; 762 - } 838 + /// Implemented for the Windows API 839 + pub fn nextEvent(_: *@This(), _: *Parser, _: ?std.mem.Allocator) !Event { 840 + return error.SkipZigTest; 841 + } 842 + }, 763 843 }; 764 844 765 845 test {