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