1 /* 2 * PROJECT: ReactOS Console Utilities Library 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: Console/terminal screen management. 5 * COPYRIGHT: Copyright 2017-2018 ReactOS Team 6 * Copyright 2017-2018 Hermes Belusca-Maito 7 */ 8 9 /** 10 * @file screen.c 11 * @ingroup ConUtils 12 * 13 * @brief Console/terminal screen management. 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 30 // Temporary HACK 31 #define CON_STREAM_WRITE ConStreamWrite 32 33 34 #if 0 35 36 VOID 37 ConClearLine(IN PCON_STREAM Stream) 38 { 39 HANDLE hOutput = ConStreamGetOSHandle(Stream); 40 41 /* 42 * Erase the full line where the cursor is, and move 43 * the cursor back to the beginning of the line. 44 */ 45 46 if (IsConsoleHandle(hOutput)) 47 { 48 CONSOLE_SCREEN_BUFFER_INFO csbi; 49 DWORD dwWritten; 50 51 GetConsoleScreenBufferInfo(hOutput, &csbi); 52 53 csbi.dwCursorPosition.X = 0; 54 // csbi.dwCursorPosition.Y; 55 56 FillConsoleOutputCharacterW(hOutput, L' ', 57 csbi.dwSize.X, 58 csbi.dwCursorPosition, 59 &dwWritten); 60 SetConsoleCursorPosition(hOutput, csbi.dwCursorPosition); 61 } 62 else if (IsTTYHandle(hOutput)) 63 { 64 ConPuts(Stream, L"\x1B[2K\x1B[1G"); // FIXME: Just use WriteFile 65 } 66 // else, do nothing for files 67 } 68 69 #endif 70 71 72 BOOL 73 ConGetScreenInfo( 74 IN PCON_SCREEN Screen, 75 OUT PCONSOLE_SCREEN_BUFFER_INFO pcsbi) 76 { 77 BOOL Success; 78 HANDLE hOutput; 79 80 /* Parameters validation */ 81 if (!Screen || !pcsbi) 82 return FALSE; 83 84 hOutput = ConStreamGetOSHandle(Screen->Stream); 85 86 /* Screen handle must be of TTY type (console or TTY) */ 87 if (!IsTTYHandle(hOutput)) 88 return FALSE; 89 90 /* Update cached screen information */ 91 if (IsConsoleHandle(hOutput)) 92 { 93 Success = GetConsoleScreenBufferInfo(hOutput, &Screen->csbi); 94 } 95 else 96 { 97 #if 0 98 /* TODO: Do something adequate for TTYs */ 99 // FIXME: At the moment we return hardcoded info. 100 Screen->csbi.dwSize.X = 80; 101 Screen->csbi.dwSize.Y = 25; 102 103 // Screen->csbi.dwCursorPosition; 104 // Screen->csbi.wAttributes; 105 // Screen->csbi.srWindow; 106 Screen->csbi.dwMaximumWindowSize = Screen->csbi.dwSize; 107 #else 108 hOutput = CreateFileW(L"CONOUT$", GENERIC_READ|GENERIC_WRITE, 109 FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, 110 OPEN_EXISTING, 0, NULL); 111 112 Success = IsConsoleHandle(hOutput) && 113 GetConsoleScreenBufferInfo(hOutput, &Screen->csbi); 114 115 CloseHandle(hOutput); 116 #endif 117 } 118 119 if (Success) 120 { 121 /* Return it to the caller */ 122 *pcsbi = Screen->csbi; 123 } 124 125 return Success; 126 } 127 128 // For real consoles, erase everything, otherwise (TTY) erase just the "screen". 129 // FIXME: Or we can add a BOOL flag? 130 VOID 131 ConClearScreen(IN PCON_SCREEN Screen) 132 { 133 HANDLE hOutput; 134 135 /* Parameters validation */ 136 if (!Screen) return; 137 138 #if 0 139 /* Get the size of the visual screen */ 140 if (!ConGetScreenInfo(Screen, &csbi)) 141 { 142 /* We assume it's a file handle */ 143 return; 144 } 145 #endif 146 147 hOutput = ConStreamGetOSHandle(Screen->Stream); 148 149 if (IsConsoleHandle(hOutput)) 150 { 151 CONSOLE_SCREEN_BUFFER_INFO csbi; 152 COORD coPos; 153 DWORD dwWritten; 154 155 GetConsoleScreenBufferInfo(hOutput, &csbi); 156 157 coPos.X = 0; 158 coPos.Y = 0; 159 FillConsoleOutputAttribute(hOutput, csbi.wAttributes, 160 csbi.dwSize.X * csbi.dwSize.Y, 161 coPos, &dwWritten); 162 FillConsoleOutputCharacterW(hOutput, L' ', 163 csbi.dwSize.X * csbi.dwSize.Y, 164 coPos, &dwWritten); 165 SetConsoleCursorPosition(hOutput, coPos); 166 } 167 else if (IsTTYHandle(hOutput)) 168 { 169 /* Clear the full screen and move the cursor to (0,0) */ 170 ConPuts(Screen->Stream, L"\x1B[2J\x1B[1;1H"); 171 } 172 else 173 { 174 /* Issue a Form-Feed control */ 175 WCHAR ch = L'\f'; 176 CON_STREAM_WRITE(Screen->Stream, &ch, 1); 177 } 178 } 179 180 /* EOF */ 181