123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- // +build windows
- package winterm
- // effectiveSr gets the current effective scroll region in buffer coordinates
- func (h *windowsAnsiEventHandler) effectiveSr(window SMALL_RECT) scrollRegion {
- top := addInRange(window.Top, h.sr.top, window.Top, window.Bottom)
- bottom := addInRange(window.Top, h.sr.bottom, window.Top, window.Bottom)
- if top >= bottom {
- top = window.Top
- bottom = window.Bottom
- }
- return scrollRegion{top: top, bottom: bottom}
- }
- func (h *windowsAnsiEventHandler) scrollUp(param int) error {
- info, err := GetConsoleScreenBufferInfo(h.fd)
- if err != nil {
- return err
- }
- sr := h.effectiveSr(info.Window)
- return h.scroll(param, sr, info)
- }
- func (h *windowsAnsiEventHandler) scrollDown(param int) error {
- return h.scrollUp(-param)
- }
- func (h *windowsAnsiEventHandler) deleteLines(param int) error {
- info, err := GetConsoleScreenBufferInfo(h.fd)
- if err != nil {
- return err
- }
- start := info.CursorPosition.Y
- sr := h.effectiveSr(info.Window)
- // Lines cannot be inserted or deleted outside the scrolling region.
- if start >= sr.top && start <= sr.bottom {
- sr.top = start
- return h.scroll(param, sr, info)
- } else {
- return nil
- }
- }
- func (h *windowsAnsiEventHandler) insertLines(param int) error {
- return h.deleteLines(-param)
- }
- // scroll scrolls the provided scroll region by param lines. The scroll region is in buffer coordinates.
- 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) deleteCharacters(param int) error {
- info, err := GetConsoleScreenBufferInfo(h.fd)
- if err != nil {
- return err
- }
- return h.scrollLine(param, info.CursorPosition, info)
- }
- func (h *windowsAnsiEventHandler) insertCharacters(param int) error {
- return h.deleteCharacters(-param)
- }
- // scrollLine scrolls a line horizontally starting at the provided position by a number of columns.
- func (h *windowsAnsiEventHandler) scrollLine(columns int, position COORD, info *CONSOLE_SCREEN_BUFFER_INFO) error {
- // Copy from and clip to the scroll region (full buffer width)
- scrollRect := SMALL_RECT{
- Top: position.Y,
- Bottom: position.Y,
- Left: position.X,
- Right: info.Size.X - 1,
- }
- // Origin to which area should be copied
- destOrigin := COORD{
- X: position.X - int16(columns),
- Y: position.Y,
- }
- char := CHAR_INFO{
- UnicodeChar: ' ',
- Attributes: h.attributes,
- }
- if err := ScrollConsoleScreenBuffer(h.fd, scrollRect, scrollRect, destOrigin, char); err != nil {
- return err
- }
- return nil
- }
|