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