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