winterm/scroll_helper.go
func (h *windowsAnsiEventHandler) scroll(param int, sr scrollRegion, info *CONSOLE_SCREEN_BUFFER_INFO) error {
	h.logf("scroll: scrollTop: %d, scrollBottom: %d", sr.top, sr.bottom)
	h.logf("scroll: windowTop: %d, windowBottom: %d", info.Window.Top, info.Window.Bottom)

	// Copy from and clip to the scroll region (full buffer width)
	scrollRect := SMALL_RECT{
		Top:    sr.top,
		Bottom: sr.bottom,
		Left:   0,
		Right:  info.Size.X - 1,
	}

	// Origin to which area should be copied
	destOrigin := COORD{
		X: 0,
		Y: sr.top - int16(param),
	}

	char := CHAR_INFO{
		UnicodeChar: ' ',
		Attributes:  h.attributes,
	}

	if err := ScrollConsoleScreenBuffer(h.fd, scrollRect, scrollRect, destOrigin, char); err != nil {
		return err
	}
	return nil
}
func (h *windowsAnsiEventHandler) scroll(param int, sr scrollRegion, info *CONSOLE_SCREEN_BUFFER_INFO) error {
	h.logf("scroll: scrollTop: %d, scrollBottom: %d", sr.top, sr.bottom)
	h.logf("scroll: windowTop: %d, windowBottom: %d", info.Window.Top, info.Window.Bottom)

	// Copy from and clip to the scroll region (full buffer width)
	scrollRect := SMALL_RECT{
		Top:    sr.top,
		Bottom: sr.bottom,
		Left:   0,
		Right:  info.Size.X - 1,
	}

	// Origin to which area should be copied
	destOrigin := COORD{
		X: 0,
		Y: sr.top - int16(param),
	}

	char := CHAR_INFO{
		UnicodeChar: ' ',
		Attributes:  h.attributes,
	}

	if err := ScrollConsoleScreenBuffer(h.fd, scrollRect, scrollRect, destOrigin, char); err != nil {
		return err
	}
	return nil
}
// scroll scrolls the provided scroll region by param lines. The scroll region is in buffer coordinates.