2 * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
14 #include <boot/platform/generic/text_console.h>
17 // #pragma mark - PagerTextSource
20 PagerTextSource::~PagerTextSource()
29 next_line(const PagerTextSource
& textSource
, size_t width
, size_t offset
,
30 char* buffer
, size_t bufferSize
)
32 size_t bytesRead
= textSource
.Read(offset
, buffer
, bufferSize
- 1);
36 buffer
[bytesRead
] = '\0';
38 // replace all '\0's by spaces
39 for (size_t i
= 0; i
< bytesRead
; i
++) {
40 if (buffer
[i
] == '\0')
44 if (const char* lineEnd
= strchr(buffer
, '\n'))
45 bytesRead
= lineEnd
- buffer
;
47 if (bytesRead
> (size_t)width
)
50 // replace unprintables by '.'
51 for (size_t i
= 0; i
< bytesRead
; i
++) {
52 if (!isprint(buffer
[i
]))
56 bool lineBreak
= buffer
[bytesRead
] == '\n';
58 buffer
[bytesRead
] = '\0';
60 return bytesRead
+ (lineBreak
? 1 : 0);
65 count_lines(const PagerTextSource
& textSource
, size_t width
, char* buffer
,
72 size_t bytesRead
= next_line(textSource
, width
, offset
, buffer
,
86 offset_of_line(const PagerTextSource
& textSource
, size_t width
, char* buffer
,
87 size_t bufferSize
, int32 line
)
93 if (line
== lineCount
)
96 size_t bytesRead
= next_line(textSource
, width
, offset
, buffer
,
113 pager(const PagerTextSource
& textSource
)
115 console_set_cursor(0, 0);
117 int32 width
= console_width();
118 int32 height
= console_height();
120 char lineBuffer
[256];
122 int32 lineCount
= count_lines(textSource
, width
, lineBuffer
,
128 // get the text offset for the top line
129 size_t offset
= offset_of_line(textSource
, width
, lineBuffer
,
130 sizeof(lineBuffer
), topLine
);
132 // clear the screen and print the lines
133 console_clear_screen();
135 int32 screenLine
= 0;
136 while (screenLine
+ 1 < height
) {
137 size_t bytesRead
= next_line(textSource
, width
, offset
, lineBuffer
,
142 console_set_cursor(0, screenLine
);
149 // print the statistics line at the bottom
150 console_set_cursor(0, height
- 1);
151 console_set_color(BLACK
, GRAY
);
152 int32 bottomLine
= std::min(topLine
+ height
- 2, lineCount
- 1);
153 printf("%" B_PRIuSIZE
" - %" B_PRIuSIZE
" %" B_PRIuSIZE
"%%",
154 topLine
, bottomLine
, (bottomLine
+ 1) * 100 / lineCount
);
155 console_set_color(WHITE
, BLACK
);
157 // wait for a key that changes the position
158 int32 previousTopLine
= topLine
;
160 while (!quit
&& topLine
== previousTopLine
) {
161 switch (console_wait_for_key()) {
162 case TEXT_CONSOLE_KEY_ESCAPE
:
169 case TEXT_CONSOLE_KEY_DOWN
:
170 case TEXT_CONSOLE_KEY_RETURN
:
175 case TEXT_CONSOLE_KEY_UP
:
180 case TEXT_CONSOLE_KEY_PAGE_UP
:
182 topLine
-= height
- 1;
185 case TEXT_CONSOLE_KEY_PAGE_DOWN
:
187 topLine
+= height
- 1;
190 case TEXT_CONSOLE_KEY_HOME
:
195 case TEXT_CONSOLE_KEY_END
:
201 if (topLine
> lineCount
- (height
- 1))
202 topLine
= lineCount
- (height
- 1);