Merge PR #283 "[USBPORT] Transaction Translator (TT) support bringup"
[reactos.git] / sdk / lib / conutils / pager.c
1 /*
2 * PROJECT: ReactOS Console Utilities Library
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Console/terminal paging functionality.
5 * COPYRIGHT: Copyright 2017-2018 ReactOS Team
6 * Copyright 2017-2018 Hermes Belusca-Maito
7 */
8
9 /**
10 * @file pager.c
11 * @ingroup ConUtils
12 *
13 * @brief Console/terminal paging functionality.
14 **/
15
16 /* FIXME: Temporary HACK before we cleanly support UNICODE functions */
17 #define UNICODE
18 #define _UNICODE
19
20 #include <windef.h>
21 #include <winbase.h>
22 // #include <winnls.h>
23 #include <wincon.h> // Console APIs (only if kernel32 support included)
24 #include <strsafe.h>
25
26 #include "conutils.h"
27 #include "stream.h"
28 #include "screen.h"
29 #include "pager.h"
30
31 // Temporary HACK
32 #define CON_STREAM_WRITE ConStreamWrite
33
34
35
36 /* Returns TRUE when all the text is displayed, and FALSE if display is stopped */
37 BOOL
38 ConWritePaging(
39 IN PCON_PAGER Pager,
40 IN PAGE_PROMPT PagePrompt,
41 IN BOOL StartPaging,
42 IN PTCHAR szStr,
43 IN DWORD len)
44 {
45 CONSOLE_SCREEN_BUFFER_INFO csbi;
46
47 /* Used to see how big the screen is */
48 DWORD ScreenLines = 0;
49
50 /* Chars since start of line */
51 DWORD CharSL;
52
53 DWORD from = 0, i = 0;
54
55 /* Parameters validation */
56 if (!Pager)
57 return FALSE;
58
59 /* Reset LineCount and return if no string has been given */
60 if (StartPaging == TRUE)
61 Pager->LineCount = 0;
62 if (szStr == NULL)
63 return TRUE;
64
65 /* Get the size of the visual screen that can be printed to */
66 if (!ConGetScreenInfo(Pager->Screen, &csbi))
67 {
68 /* We assume it's a file handle */
69 CON_STREAM_WRITE(Pager->Screen->Stream, szStr, len);
70 return TRUE;
71 }
72
73 /*
74 * Get the number of lines currently displayed on screen, minus 1
75 * to account for the "press any key..." prompt from PagePrompt().
76 */
77 ScreenLines = (csbi.srWindow.Bottom - csbi.srWindow.Top);
78 CharSL = csbi.dwCursorPosition.X;
79
80 /* Make sure the user doesn't have the screen too small */
81 if (ScreenLines < 4)
82 {
83 CON_STREAM_WRITE(Pager->Screen->Stream, szStr, len);
84 return TRUE;
85 }
86
87 while (i < len)
88 {
89 /* Search until the end of a line is reached */
90 if (szStr[i++] != TEXT('\n') && ++CharSL < csbi.dwSize.X)
91 continue;
92
93 Pager->LineCount++;
94 CharSL = 0;
95
96 if (Pager->LineCount >= ScreenLines)
97 {
98 CON_STREAM_WRITE(Pager->Screen->Stream, &szStr[from], i-from);
99 from = i;
100
101 /* Prompt the user; give him some values for statistics */
102 // FIXME TODO: The prompt proc can also take ScreenLines ??
103 if (!PagePrompt(Pager, from, len))
104 return FALSE;
105
106 // TODO: Recalculate 'ScreenLines' in case the user redimensions
107 // the window during the prompt.
108
109 /* Reset the number of lines being printed */
110 Pager->LineCount = 0;
111 }
112 }
113 if (i > from)
114 CON_STREAM_WRITE(Pager->Screen->Stream, &szStr[from], i-from);
115
116 return TRUE;
117 }
118
119 BOOL
120 ConPutsPaging(
121 IN PCON_PAGER Pager,
122 IN PAGE_PROMPT PagePrompt,
123 IN BOOL StartPaging,
124 IN LPTSTR szStr)
125 {
126 DWORD len;
127
128 /* Return if no string has been given */
129 if (szStr == NULL)
130 return TRUE;
131
132 len = wcslen(szStr);
133 return ConWritePaging(Pager, PagePrompt, StartPaging, szStr, len);
134 }
135
136 BOOL
137 ConResPagingEx(
138 IN PCON_PAGER Pager,
139 IN PAGE_PROMPT PagePrompt,
140 IN BOOL StartPaging,
141 IN HINSTANCE hInstance OPTIONAL,
142 IN UINT uID)
143 {
144 INT Len;
145 PWCHAR szStr = NULL;
146
147 Len = K32LoadStringW(hInstance, uID, (PWSTR)&szStr, 0);
148 if (szStr && Len)
149 return ConWritePaging(Pager, PagePrompt, StartPaging, szStr, Len);
150 else
151 return TRUE;
152 }
153
154 BOOL
155 ConResPaging(
156 IN PCON_PAGER Pager,
157 IN PAGE_PROMPT PagePrompt,
158 IN BOOL StartPaging,
159 IN UINT uID)
160 {
161 return ConResPagingEx(Pager, PagePrompt, StartPaging,
162 NULL /*GetModuleHandleW(NULL)*/, uID);
163 }
164
165 /* EOF */