Beispiel #1
0
func newAnsiWriter(nFile int) *ansiWriter {
	logFile := ioutil.Discard

	if isDebugEnv := os.Getenv(ansiterm.LogEnv); isDebugEnv == "1" {
		logFile, _ = os.Create("ansiReaderWriter.log")
	}

	logger = &logrus.Logger{
		Out:       logFile,
		Formatter: new(logrus.TextFormatter),
		Level:     logrus.DebugLevel,
	}

	file, fd := winterm.GetStdFile(nFile)
	info, err := winterm.GetConsoleScreenBufferInfo(fd)
	if err != nil {
		return nil
	}

	parser := ansiterm.CreateParser("Ground", winterm.CreateWinEventHandler(fd, file))
	logger.Infof("newAnsiWriter: parser %p", parser)

	aw := &ansiWriter{
		file:           file,
		fd:             fd,
		infoReset:      info,
		command:        make([]byte, 0, ansiterm.ANSI_MAX_CMD_LENGTH),
		escapeSequence: []byte(ansiterm.KEY_ESC_CSI),
		parser:         parser,
	}

	logger.Infof("newAnsiWriter: aw.parser %p", aw.parser)
	logger.Infof("newAnsiWriter: %v", aw)
	return aw
}
Beispiel #2
0
// GetWinsize returns the window size based on the specified file descriptor.
func GetWinsize(fd uintptr) (*Winsize, error) {
	info, err := winterm.GetConsoleScreenBufferInfo(fd)
	if err != nil {
		return nil, err
	}

	winsize := &Winsize{
		Width:  uint16(info.Window.Right - info.Window.Left + 1),
		Height: uint16(info.Window.Bottom - info.Window.Top + 1),
	}

	return winsize, nil
}
Beispiel #3
0
// GetWinsize returns the window size based on the specified file descriptor.
func GetWinsize(fd uintptr) (*Winsize, error) {

	info, err := winterm.GetConsoleScreenBufferInfo(fd)
	if err != nil {
		return nil, err
	}

	winsize := &Winsize{
		Width:  uint16(info.Window.Right - info.Window.Left + 1),
		Height: uint16(info.Window.Bottom - info.Window.Top + 1),
		x:      0,
		y:      0}

	// Note: GetWinsize is called frequently -- uncomment only for excessive details
	// logrus.Debugf("[windows] GetWinsize: Console(%v)", info.String())
	// logrus.Debugf("[windows] GetWinsize: Width(%v), Height(%v), x(%v), y(%v)", winsize.Width, winsize.Height, winsize.x, winsize.y)
	return winsize, nil
}
Beispiel #4
0
// SetWinsize tries to set the specified window size for the specified file descriptor.
func SetWinsize(fd uintptr, ws *Winsize) error {

	// Ensure the requested dimensions are no larger than the maximum window size
	info, err := winterm.GetConsoleScreenBufferInfo(fd)
	if err != nil {
		return err
	}

	if ws.Width == 0 || ws.Height == 0 || ws.Width > uint16(info.MaximumWindowSize.X) || ws.Height > uint16(info.MaximumWindowSize.Y) {
		return fmt.Errorf("Illegal window size: (%v,%v) -- Maximum allow: (%v,%v)",
			ws.Width, ws.Height, info.MaximumWindowSize.X, info.MaximumWindowSize.Y)
	}

	// Narrow the sizes to that used by Windows
	width := winterm.SHORT(ws.Width)
	height := winterm.SHORT(ws.Height)

	// Set the dimensions while ensuring they remain within the bounds of the backing console buffer
	// -- Shrinking will always succeed. Growing may push the edges past the buffer boundary. When that occurs,
	//    shift the upper left just enough to keep the new window within the buffer.
	rect := info.Window
	if width < rect.Right-rect.Left+1 {
		rect.Right = rect.Left + width - 1
	} else if width > rect.Right-rect.Left+1 {
		rect.Right = rect.Left + width - 1
		if rect.Right >= info.Size.X {
			rect.Left = info.Size.X - width
			rect.Right = info.Size.X - 1
		}
	}

	if height < rect.Bottom-rect.Top+1 {
		rect.Bottom = rect.Top + height - 1
	} else if height > rect.Bottom-rect.Top+1 {
		rect.Bottom = rect.Top + height - 1
		if rect.Bottom >= info.Size.Y {
			rect.Top = info.Size.Y - height
			rect.Bottom = info.Size.Y - 1
		}
	}
	logrus.Debugf("[windows] SetWinsize: Requested((%v,%v)) Actual(%v)", ws.Width, ws.Height, rect)

	return winterm.SetConsoleWindowInfo(fd, true, rect)
}
// NewAnsiWriter returns an io.Writer that provides VT100 terminal emulation on top of a
// Windows console output handle.
func NewAnsiWriter(nFile int) io.Writer {
	initLogger()
	file, fd := winterm.GetStdFile(nFile)
	info, err := winterm.GetConsoleScreenBufferInfo(fd)
	if err != nil {
		return nil
	}

	parser := ansiterm.CreateParser("Ground", winterm.CreateWinEventHandler(fd, file))
	logger.Infof("newAnsiWriter: parser %p", parser)

	aw := &ansiWriter{
		file:           file,
		fd:             fd,
		infoReset:      info,
		command:        make([]byte, 0, ansiterm.ANSI_MAX_CMD_LENGTH),
		escapeSequence: []byte(ansiterm.KEY_ESC_CSI),
		parser:         parser,
	}

	logger.Infof("newAnsiWriter: aw.parser %p", aw.parser)
	logger.Infof("newAnsiWriter: %v", aw)
	return aw
}