reactos/sdk/lib/conutils/screen.c

175 lines
4.5 KiB
C

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Console Utilities Library
* FILE: sdk/lib/conutils/screen.c
* PURPOSE: Console/terminal screen management.
* PROGRAMMERS: - Hermes Belusca-Maito (for the library);
* - All programmers who wrote the different console applications
* from which I took those functions and improved them.
*/
/* FIXME: Temporary HACK before we cleanly support UNICODE functions */
#define UNICODE
#define _UNICODE
#include <stdlib.h> // limits.h // For MB_LEN_MAX
#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);
}
}