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