From f33c09daf40e391d5a115ba1d6181155390426eb Mon Sep 17 00:00:00 2001 From: mochalins <117967760+mochalins@users.noreply.github.com> Date: Mon, 16 Sep 2024 18:07:09 +0900 Subject: [PATCH] feat: windows polling --- src/backend/windows.zig | 60 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/backend/windows.zig b/src/backend/windows.zig index cd80155..ffa0ccb 100644 --- a/src/backend/windows.zig +++ b/src/backend/windows.zig @@ -73,6 +73,11 @@ pub const Port = struct { else => |e| return windows.unexpectedError(e), } } + errdefer self.close(); + + if (SetCommMask(self.file.?.handle, .{ .RXCHAR = true }) == 0) { + return windows.unexpectedError(windows.GetLastError()); + } } pub fn close(self: *@This()) void { @@ -123,6 +128,37 @@ pub const Port = struct { } } + pub fn poll(self: @This()) !bool { + if (self.file == null) return false; + + var events: EventMask = undefined; + + var overlapped: windows.OVERLAPPED = .{ + .Internal = 0, + .InternalHigh = 0, + .DUMMYUNIONNAME = .{ + .DUMMYSTRUCTNAME = .{ + .Offset = 0, + .OffsetHigh = 0, + }, + }, + .hEvent = try windows.CreateEventEx( + null, + "", + windows.CREATE_EVENT_MANUAL_RESET, + windows.EVENT_ALL_ACCESS, + ), + }; + if (WaitCommEvent(self.file.?.handle, &events, &overlapped) == 0) { + switch (windows.GetLastError()) { + windows.Win32Error.IO_PENDING => return false, + else => |e| return windows.unexpectedError(e), + } + } + + return events.RXCHAR; + } + pub fn reader(self: @This()) ?Reader { return .{ .context = self.file orelse return null, @@ -301,6 +337,17 @@ extern "kernel32" fn GetCommState( lpDCB: *DCB, ) callconv(windows.WINAPI) windows.BOOL; +extern "kernel32" fn SetCommMask( + hFile: windows.HANDLE, + dwEvtMask: EventMask, +) callconv(windows.WINAPI) windows.BOOL; + +extern "kernel32" fn WaitCommEvent( + hFile: windows.HANDLE, + lpEvtMask: *EventMask, + lpOverlapped: ?*windows.OVERLAPPED, +) callconv(windows.WINAPI) windows.BOOL; + extern "kernel32" fn PurgeComm( hFile: windows.HANDLE, dwFlags: packed struct(windows.DWORD) { @@ -311,3 +358,16 @@ extern "kernel32" fn PurgeComm( _: u28 = 0, }, ) callconv(windows.WINAPI) windows.BOOL; + +const EventMask = packed struct(windows.DWORD) { + RXCHAR: bool = false, + RXFLAG: bool = false, + TXEMPTY: bool = false, + CTS: bool = false, + DSR: bool = false, + RLSD: bool = false, + BREAK: bool = false, + ERR: bool = false, + RING: bool = false, + _: u23 = 0, +};