diff --git a/windows/doc.go b/windows/doc.go new file mode 100644 index 00000000..15fc9ee9 --- /dev/null +++ b/windows/doc.go @@ -0,0 +1,3 @@ +package windows + +//go generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go syscall_windows.go diff --git a/windows/go.mod b/windows/go.mod new file mode 100644 index 00000000..119ee37b --- /dev/null +++ b/windows/go.mod @@ -0,0 +1,5 @@ +module github.com/charmbracelet/x/windows + +go 1.18 + +require golang.org/x/sys v0.20.0 diff --git a/windows/go.sum b/windows/go.sum new file mode 100644 index 00000000..5d1e088e --- /dev/null +++ b/windows/go.sum @@ -0,0 +1,2 @@ +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= diff --git a/windows/syscall_windows.go b/windows/syscall_windows.go new file mode 100644 index 00000000..dd49431f --- /dev/null +++ b/windows/syscall_windows.go @@ -0,0 +1,10 @@ +package windows + +import "golang.org/x/sys/windows" + +var NewLazySystemDLL = windows.NewLazySystemDLL + +type Handle = windows.Handle + +//sys GetKeyboardLayout(threadId uint32) (hkl Handle, err error) = user32.GetKeyboardLayout +//sys ToUnicodeEx(vkey uint32, scancode uint32, keystate *byte, pwszBuff *uint16, cchBuff int32, flags uint32, hkl Handle) (ret int32, err error) = user32.ToUnicodeEx diff --git a/windows/zsyscall_windows.go b/windows/zsyscall_windows.go new file mode 100644 index 00000000..97096a42 --- /dev/null +++ b/windows/zsyscall_windows.go @@ -0,0 +1,61 @@ +// Code generated by 'go generate'; DO NOT EDIT. + +package windows + +import ( + "syscall" + "unsafe" +) + +var _ unsafe.Pointer + +// Do the interface allocations only once for common +// Errno values. +const ( + errnoERROR_IO_PENDING = 997 +) + +var ( + errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) + errERROR_EINVAL error = syscall.EINVAL +) + +// errnoErr returns common boxed Errno values, to prevent +// allocations at runtime. +func errnoErr(e syscall.Errno) error { + switch e { + case 0: + return errERROR_EINVAL + case errnoERROR_IO_PENDING: + return errERROR_IO_PENDING + } + // TODO: add more here, after collecting data on the common + // error values see on Windows. (perhaps when running + // all.bat?) + return e +} + +var ( + moduser32 = NewLazySystemDLL("user32.dll") + + procGetKeyboardLayout = moduser32.NewProc("GetKeyboardLayout") + procToUnicodeEx = moduser32.NewProc("ToUnicodeEx") +) + +func GetKeyboardLayout(threadId uint32) (hkl Handle, err error) { + r0, _, e1 := syscall.Syscall(procGetKeyboardLayout.Addr(), 1, uintptr(threadId), 0, 0) + hkl = Handle(r0) + if hkl == 0 { + err = errnoErr(e1) + } + return +} + +func ToUnicodeEx(vkey uint32, scancode uint32, keystate *byte, pwszBuff *uint16, cchBuff int32, flags uint32, hkl Handle) (ret int32, err error) { + r0, _, e1 := syscall.Syscall9(procToUnicodeEx.Addr(), 7, uintptr(vkey), uintptr(scancode), uintptr(unsafe.Pointer(keystate)), uintptr(unsafe.Pointer(pwszBuff)), uintptr(cchBuff), uintptr(flags), uintptr(hkl), 0, 0) + ret = int32(r0) + if ret == 0 { + err = errnoErr(e1) + } + return +}