github.com/jogo/docker@v1.7.0-rc1/pkg/term/term_windows.go (about) 1 // +build windows 2 package term 3 4 import ( 5 "io" 6 "os" 7 8 "github.com/Sirupsen/logrus" 9 "github.com/docker/docker/pkg/term/winconsole" 10 ) 11 12 // State holds the console mode for the terminal. 13 type State struct { 14 mode uint32 15 } 16 17 // Winsize is used for window size. 18 type Winsize struct { 19 Height uint16 20 Width uint16 21 x uint16 22 y uint16 23 } 24 25 func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) { 26 switch { 27 case os.Getenv("ConEmuANSI") == "ON": 28 // The ConEmu shell emulates ANSI well by default. 29 return os.Stdin, os.Stdout, os.Stderr 30 case os.Getenv("MSYSTEM") != "": 31 // MSYS (mingw) does not emulate ANSI well. 32 return winconsole.WinConsoleStreams() 33 default: 34 return winconsole.WinConsoleStreams() 35 } 36 } 37 38 // GetFdInfo returns file descriptor and bool indicating whether the file is a terminal. 39 func GetFdInfo(in interface{}) (uintptr, bool) { 40 return winconsole.GetHandleInfo(in) 41 } 42 43 // GetWinsize retrieves the window size of the terminal connected to the passed file descriptor. 44 func GetWinsize(fd uintptr) (*Winsize, error) { 45 info, err := winconsole.GetConsoleScreenBufferInfo(fd) 46 if err != nil { 47 return nil, err 48 } 49 50 // TODO(azlinux): Set the pixel width / height of the console (currently unused by any caller) 51 return &Winsize{ 52 Width: uint16(info.Window.Right - info.Window.Left + 1), 53 Height: uint16(info.Window.Bottom - info.Window.Top + 1), 54 x: 0, 55 y: 0}, nil 56 } 57 58 // SetWinsize sets the size of the given terminal connected to the passed file descriptor. 59 func SetWinsize(fd uintptr, ws *Winsize) error { 60 // TODO(azlinux): Implement SetWinsize 61 logrus.Debugf("[windows] SetWinsize: WARNING -- Unsupported method invoked") 62 return nil 63 } 64 65 // IsTerminal returns true if the given file descriptor is a terminal. 66 func IsTerminal(fd uintptr) bool { 67 return winconsole.IsConsole(fd) 68 } 69 70 // RestoreTerminal restores the terminal connected to the given file descriptor to a 71 // previous state. 72 func RestoreTerminal(fd uintptr, state *State) error { 73 return winconsole.SetConsoleMode(fd, state.mode) 74 } 75 76 // SaveState saves the state of the terminal connected to the given file descriptor. 77 func SaveState(fd uintptr) (*State, error) { 78 mode, e := winconsole.GetConsoleMode(fd) 79 if e != nil { 80 return nil, e 81 } 82 return &State{mode}, nil 83 } 84 85 // DisableEcho disables echo for the terminal connected to the given file descriptor. 86 // -- See http://msdn.microsoft.com/en-us/library/windows/desktop/ms683462(v=vs.85).aspx 87 func DisableEcho(fd uintptr, state *State) error { 88 mode := state.mode 89 mode &^= winconsole.ENABLE_ECHO_INPUT 90 mode |= winconsole.ENABLE_PROCESSED_INPUT | winconsole.ENABLE_LINE_INPUT 91 // TODO(azlinux): Core code registers a goroutine to catch os.Interrupt and reset the terminal state. 92 return winconsole.SetConsoleMode(fd, mode) 93 } 94 95 // SetRawTerminal puts the terminal connected to the given file descriptor into raw 96 // mode and returns the previous state of the terminal so that it can be 97 // restored. 98 func SetRawTerminal(fd uintptr) (*State, error) { 99 state, err := MakeRaw(fd) 100 if err != nil { 101 return nil, err 102 } 103 // TODO(azlinux): Core code registers a goroutine to catch os.Interrupt and reset the terminal state. 104 return state, err 105 } 106 107 // MakeRaw puts the terminal connected to the given file descriptor into raw 108 // mode and returns the previous state of the terminal so that it can be 109 // restored. 110 func MakeRaw(fd uintptr) (*State, error) { 111 state, err := SaveState(fd) 112 if err != nil { 113 return nil, err 114 } 115 116 // See 117 // -- https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx 118 // -- https://msdn.microsoft.com/en-us/library/windows/desktop/ms683462(v=vs.85).aspx 119 mode := state.mode 120 121 // Disable these modes 122 mode &^= winconsole.ENABLE_ECHO_INPUT 123 mode &^= winconsole.ENABLE_LINE_INPUT 124 mode &^= winconsole.ENABLE_MOUSE_INPUT 125 mode &^= winconsole.ENABLE_WINDOW_INPUT 126 mode &^= winconsole.ENABLE_PROCESSED_INPUT 127 128 // Enable these modes 129 mode |= winconsole.ENABLE_EXTENDED_FLAGS 130 mode |= winconsole.ENABLE_INSERT_MODE 131 mode |= winconsole.ENABLE_QUICK_EDIT_MODE 132 133 err = winconsole.SetConsoleMode(fd, mode) 134 if err != nil { 135 return nil, err 136 } 137 return state, nil 138 }