github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/utils/readline/raw_windows.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build windows 6 // +build windows 7 8 // Package terminal provides support functions for dealing with terminals, as 9 // commonly found on UNIX systems. 10 // 11 // Putting a terminal into raw mode is the most common requirement: 12 // 13 // oldState, err := terminal.MakeRaw(0) 14 // if err != nil { 15 // panic(err) 16 // } 17 // defer terminal.Restore(0, oldState) 18 package readline 19 20 import ( 21 "golang.org/x/sys/windows" 22 ) 23 24 type State struct { 25 mode uint32 26 } 27 28 // IsTerminal returns true if the given file descriptor is a terminal. 29 func IsTerminal(fd int) bool { 30 var st uint32 31 err := windows.GetConsoleMode(windows.Handle(fd), &st) 32 return err == nil 33 } 34 35 // MakeRaw put the terminal connected to the given file descriptor into raw 36 // mode and returns the previous state of the terminal so that it can be 37 // restored. 38 func MakeRaw(fd int) (*State, error) { 39 var st uint32 40 if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil { 41 return nil, err 42 } 43 raw := st &^ (windows.ENABLE_ECHO_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT) 44 raw |= windows.ENABLE_VIRTUAL_TERMINAL_INPUT 45 if err := windows.SetConsoleMode(windows.Handle(fd), raw); err != nil { 46 return nil, err 47 } 48 return &State{st}, nil 49 } 50 51 // GetState returns the current state of a terminal which may be useful to 52 // restore the terminal after a signal. 53 func GetState(fd int) (*State, error) { 54 var st uint32 55 if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil { 56 return nil, err 57 } 58 return &State{st}, nil 59 } 60 61 // Restore restores the terminal connected to the given file descriptor to a 62 // previous state. 63 func Restore(fd int, state *State) error { 64 return windows.SetConsoleMode(windows.Handle(fd), state.mode) 65 } 66 67 // GetSize returns the dimensions of the given terminal. 68 func GetSize(fd int) (width, height int, err error) { 69 var info windows.ConsoleScreenBufferInfo 70 if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil { 71 return 0, 0, err 72 } 73 return int(info.Window.Right - info.Window.Left + 1), int(info.Window.Bottom - info.Window.Top + 1), nil 74 }