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 */ 166