Tizen_4.0 base
[platform/upstream/docker-engine.git] / vendor / github.com / Azure / go-ansiterm / winterm / scroll_helper.go
1 // +build windows
2
3 package winterm
4
5 // effectiveSr gets the current effective scroll region in buffer coordinates
6 func (h *windowsAnsiEventHandler) effectiveSr(window SMALL_RECT) scrollRegion {
7         top := addInRange(window.Top, h.sr.top, window.Top, window.Bottom)
8         bottom := addInRange(window.Top, h.sr.bottom, window.Top, window.Bottom)
9         if top >= bottom {
10                 top = window.Top
11                 bottom = window.Bottom
12         }
13         return scrollRegion{top: top, bottom: bottom}
14 }
15
16 func (h *windowsAnsiEventHandler) scrollUp(param int) error {
17         info, err := GetConsoleScreenBufferInfo(h.fd)
18         if err != nil {
19                 return err
20         }
21
22         sr := h.effectiveSr(info.Window)
23         return h.scroll(param, sr, info)
24 }
25
26 func (h *windowsAnsiEventHandler) scrollDown(param int) error {
27         return h.scrollUp(-param)
28 }
29
30 func (h *windowsAnsiEventHandler) deleteLines(param int) error {
31         info, err := GetConsoleScreenBufferInfo(h.fd)
32         if err != nil {
33                 return err
34         }
35
36         start := info.CursorPosition.Y
37         sr := h.effectiveSr(info.Window)
38         // Lines cannot be inserted or deleted outside the scrolling region.
39         if start >= sr.top && start <= sr.bottom {
40                 sr.top = start
41                 return h.scroll(param, sr, info)
42         } else {
43                 return nil
44         }
45 }
46
47 func (h *windowsAnsiEventHandler) insertLines(param int) error {
48         return h.deleteLines(-param)
49 }
50
51 // scroll scrolls the provided scroll region by param lines. The scroll region is in buffer coordinates.
52 func (h *windowsAnsiEventHandler) scroll(param int, sr scrollRegion, info *CONSOLE_SCREEN_BUFFER_INFO) error {
53         logger.Infof("scroll: scrollTop: %d, scrollBottom: %d", sr.top, sr.bottom)
54         logger.Infof("scroll: windowTop: %d, windowBottom: %d", info.Window.Top, info.Window.Bottom)
55
56         // Copy from and clip to the scroll region (full buffer width)
57         scrollRect := SMALL_RECT{
58                 Top:    sr.top,
59                 Bottom: sr.bottom,
60                 Left:   0,
61                 Right:  info.Size.X - 1,
62         }
63
64         // Origin to which area should be copied
65         destOrigin := COORD{
66                 X: 0,
67                 Y: sr.top - int16(param),
68         }
69
70         char := CHAR_INFO{
71                 UnicodeChar: ' ',
72                 Attributes:  h.attributes,
73         }
74
75         if err := ScrollConsoleScreenBuffer(h.fd, scrollRect, scrollRect, destOrigin, char); err != nil {
76                 return err
77         }
78         return nil
79 }
80
81 func (h *windowsAnsiEventHandler) deleteCharacters(param int) error {
82         info, err := GetConsoleScreenBufferInfo(h.fd)
83         if err != nil {
84                 return err
85         }
86         return h.scrollLine(param, info.CursorPosition, info)
87 }
88
89 func (h *windowsAnsiEventHandler) insertCharacters(param int) error {
90         return h.deleteCharacters(-param)
91 }
92
93 // scrollLine scrolls a line horizontally starting at the provided position by a number of columns.
94 func (h *windowsAnsiEventHandler) scrollLine(columns int, position COORD, info *CONSOLE_SCREEN_BUFFER_INFO) error {
95         // Copy from and clip to the scroll region (full buffer width)
96         scrollRect := SMALL_RECT{
97                 Top:    position.Y,
98                 Bottom: position.Y,
99                 Left:   position.X,
100                 Right:  info.Size.X - 1,
101         }
102
103         // Origin to which area should be copied
104         destOrigin := COORD{
105                 X: position.X - int16(columns),
106                 Y: position.Y,
107         }
108
109         char := CHAR_INFO{
110                 UnicodeChar: ' ',
111                 Attributes:  h.attributes,
112         }
113
114         if err := ScrollConsoleScreenBuffer(h.fd, scrollRect, scrollRect, destOrigin, char); err != nil {
115                 return err
116         }
117         return nil
118 }