src.elv.sh@v0.21.0-dev.0.20240515223629-06979efb9a2a/pkg/cli/examples/win_tty/main_windows.go (about) 1 package main 2 3 import ( 4 "log" 5 "os" 6 "strings" 7 "unicode" 8 9 "golang.org/x/sys/windows" 10 11 "src.elv.sh/pkg/sys/ewindows" 12 ) 13 14 func main() { 15 restore := setup(os.Stdin, os.Stdout) 16 defer restore() 17 18 log.Println("ready") 19 console, err := windows.GetStdHandle(windows.STD_INPUT_HANDLE) 20 if err != nil { 21 log.Fatalf("GetStdHandle(STD_INPUT_HANDLE): %v", err) 22 } 23 for { 24 var buf [1]ewindows.InputRecord 25 nr, err := ewindows.ReadConsoleInput(console, buf[:]) 26 if nr == 0 { 27 log.Fatal("no event read") 28 } 29 if err != nil { 30 log.Fatal(err) 31 } 32 event := buf[0].GetEvent() 33 switch event := event.(type) { 34 case *ewindows.KeyEvent: 35 typ := "up" 36 if event.BKeyDown != 0 { 37 typ = "down" 38 } 39 r := rune(event.UChar[0]) + rune(event.UChar[1])<<8 40 rs := "(" + string(r) + ")" 41 if unicode.IsControl(r) { 42 rs = " " 43 } 44 var mods []string 45 testMod := func(mask uint32, name string) { 46 if event.DwControlKeyState&mask != 0 { 47 mods = append(mods, name) 48 } 49 } 50 testMod(0x1, "right alt") 51 testMod(0x2, "left alt") 52 testMod(0x4, "right ctrl") 53 testMod(0x8, "left ctrl") 54 testMod(0x10, "shift") 55 // testMod(0x20, "numslock") 56 testMod(0x40, "scrolllock") 57 testMod(0x80, "capslock") 58 testMod(0x100, "enhanced") 59 60 log.Printf("%4s, key code = %02x, char = %04x %s, mods = %s\n", 61 typ, event.WVirtualKeyCode, r, rs, strings.Join(mods, ", ")) 62 } 63 } 64 } 65 66 const ( 67 wantedInMode = windows.ENABLE_WINDOW_INPUT | 68 windows.ENABLE_MOUSE_INPUT | windows.ENABLE_PROCESSED_INPUT 69 wantedOutMode = windows.ENABLE_PROCESSED_OUTPUT | 70 windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING 71 ) 72 73 func setup(in, out *os.File) func() { 74 hIn := windows.Handle(in.Fd()) 75 hOut := windows.Handle(out.Fd()) 76 77 var oldInMode, oldOutMode uint32 78 err := windows.GetConsoleMode(hIn, &oldInMode) 79 if err != nil { 80 log.Fatal(err) 81 } 82 err = windows.GetConsoleMode(hOut, &oldOutMode) 83 if err != nil { 84 log.Fatal(err) 85 } 86 87 err = windows.SetConsoleMode(hIn, wantedInMode) 88 if err != nil { 89 log.Fatal(err) 90 } 91 err = windows.SetConsoleMode(hOut, wantedOutMode) 92 if err != nil { 93 log.Fatal(err) 94 } 95 96 return func() { 97 err := windows.SetConsoleMode(hIn, oldInMode) 98 if err != nil { 99 log.Fatal(err) 100 } 101 err = windows.SetConsoleMode(hOut, oldOutMode) 102 if err != nil { 103 log.Fatal(err) 104 } 105 } 106 }