reactos/sdk/lib/conutils/screen.c
Hermès Bélusca-Maïto 4e697fee2c
[CONUTILS] Split stream.c into input and output stream modules.
As code grows, this will allow for better maintenance of the console
stream code. In particular the input stream module will contain special
code for handling TTYs, and this is something not all console programs
will need. Having this code in a separate module will allow for the linker
to possibly remove this code when it is unused.
2018-01-31 02:10:41 +01:00

174 lines
4.3 KiB
C

/*
* PROJECT: ReactOS Console Utilities Library
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Console/terminal screen management.
* COPYRIGHT: Copyright 2017-2018 ReactOS Team
* Copyright 2017-2018 Hermes Belusca-Maito
*/
/* FIXME: Temporary HACK before we cleanly support UNICODE functions */
#define UNICODE
#define _UNICODE
#include <windef.h>
#include <winbase.h>
// #include <winnls.h>
#include <wincon.h> // Console APIs (only if kernel32 support included)
#include <strsafe.h>
#include "conutils.h"
#include "stream.h"
#include "screen.h"
// Temporary HACK
#define CON_STREAM_WRITE ConStreamWrite
#if 0
VOID
ConClearLine(IN PCON_STREAM Stream)
{
HANDLE hOutput = ConStreamGetOSHandle(Stream);
/*
* Erase the full line where the cursor is, and move
* the cursor back to the beginning of the line.
*/
if (IsConsoleHandle(hOutput))
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
DWORD dwWritten;
GetConsoleScreenBufferInfo(hOutput, &csbi);
csbi.dwCursorPosition.X = 0;
// csbi.dwCursorPosition.Y;
FillConsoleOutputCharacterW(hOutput, L' ',
csbi.dwSize.X,
csbi.dwCursorPosition,
&dwWritten);
SetConsoleCursorPosition(hOutput, csbi.dwCursorPosition);
}
else if (IsTTYHandle(hOutput))
{
ConPuts(Stream, L"\x1B[2K\x1B[1G"); // FIXME: Just use WriteFile
}
// else, do nothing for files
}
#endif
BOOL
ConGetScreenInfo(
IN PCON_SCREEN Screen,
OUT PCONSOLE_SCREEN_BUFFER_INFO pcsbi)
{
BOOL Success;
HANDLE hOutput;
/* Parameters validation */
if (!Screen || !pcsbi)
return FALSE;
hOutput = ConStreamGetOSHandle(Screen->Stream);
/* Screen handle must be of TTY type (console or TTY) */
if (!IsTTYHandle(hOutput))
return FALSE;
/* Update cached screen information */
if (IsConsoleHandle(hOutput))
{
Success = GetConsoleScreenBufferInfo(hOutput, &Screen->csbi);
}
else
{
#if 0
/* TODO: Do something adequate for TTYs */
// FIXME: At the moment we return hardcoded info.
Screen->csbi.dwSize.X = 80;
Screen->csbi.dwSize.Y = 25;
// Screen->csbi.dwCursorPosition;
// Screen->csbi.wAttributes;
// Screen->csbi.srWindow;
Screen->csbi.dwMaximumWindowSize = Screen->csbi.dwSize;
#else
hOutput = CreateFileW(L"CONOUT$", GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, NULL);
Success = IsConsoleHandle(hOutput) &&
GetConsoleScreenBufferInfo(hOutput, &Screen->csbi);
CloseHandle(hOutput);
#endif
}
if (Success)
{
/* Return it to the caller */
*pcsbi = Screen->csbi;
}
return Success;
}
// For real consoles, erase everything, otherwise (TTY) erase just the "screen".
// FIXME: Or we can add a BOOL flag?
VOID
ConClearScreen(IN PCON_SCREEN Screen)
{
HANDLE hOutput;
/* Parameters validation */
if (!Screen) return;
#if 0
/* Get the size of the visual screen */
if (!ConGetScreenInfo(Screen, &csbi))
{
/* We assume it's a file handle */
return;
}
#endif
hOutput = ConStreamGetOSHandle(Screen->Stream);
if (IsConsoleHandle(hOutput))
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
COORD coPos;
DWORD dwWritten;
GetConsoleScreenBufferInfo(hOutput, &csbi);
coPos.X = 0;
coPos.Y = 0;
FillConsoleOutputAttribute(hOutput, csbi.wAttributes,
csbi.dwSize.X * csbi.dwSize.Y,
coPos, &dwWritten);
FillConsoleOutputCharacterW(hOutput, L' ',
csbi.dwSize.X * csbi.dwSize.Y,
coPos, &dwWritten);
SetConsoleCursorPosition(hOutput, coPos);
}
else if (IsTTYHandle(hOutput))
{
/* Clear the full screen and move the cursor to (0,0) */
ConPuts(Screen->Stream, L"\x1B[2J\x1B[1;1H");
}
else
{
/* Issue a Form-Feed control */
WCHAR ch = L'\f';
CON_STREAM_WRITE(Screen->Stream, &ch, 1);
}
}
/* EOF */