reactos/sdk/lib/conutils/pager.c

160 lines
4.1 KiB
C

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Console Utilities Library
* FILE: sdk/lib/conutils/pager.c
* PURPOSE: Console/terminal paging functionality.
* 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"
#include "pager.h"
// Temporary HACK
#define CON_STREAM_WRITE ConStreamWrite
/* Returns TRUE when all the text is displayed, and FALSE if display is stopped */
BOOL
ConWritePaging(
IN PCON_PAGER Pager,
IN PAGE_PROMPT PagePrompt,
IN BOOL StartPaging,
IN PTCHAR szStr,
IN DWORD len)
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
/* Used to see how big the screen is */
DWORD ScreenLines = 0;
/* Chars since start of line */
DWORD CharSL;
DWORD from = 0, i = 0;
/* Parameters validation */
if (!Pager)
return FALSE;
/* Reset LineCount and return if no string has been given */
if (StartPaging == TRUE)
Pager->LineCount = 0;
if (szStr == NULL)
return TRUE;
/* Get the size of the visual screen that can be printed to */
if (!ConGetScreenInfo(Pager->Screen, &csbi))
{
/* We assume it's a file handle */
CON_STREAM_WRITE(Pager->Screen->Stream, szStr, len);
return TRUE;
}
/*
* Get the number of lines currently displayed on screen, minus 1
* to account for the "press any key..." prompt from PagePrompt().
*/
ScreenLines = (csbi.srWindow.Bottom - csbi.srWindow.Top);
CharSL = csbi.dwCursorPosition.X;
/* Make sure the user doesn't have the screen too small */
if (ScreenLines < 4)
{
CON_STREAM_WRITE(Pager->Screen->Stream, szStr, len);
return TRUE;
}
while (i < len)
{
/* Search until the end of a line is reached */
if (szStr[i++] != TEXT('\n') && ++CharSL < csbi.dwSize.X)
continue;
Pager->LineCount++;
CharSL = 0;
if (Pager->LineCount >= ScreenLines)
{
CON_STREAM_WRITE(Pager->Screen->Stream, &szStr[from], i-from);
from = i;
/* Prompt the user; give him some values for statistics */
// FIXME TODO: The prompt proc can also take ScreenLines ??
if (!PagePrompt(Pager, from, len))
return FALSE;
// TODO: Recalculate 'ScreenLines' in case the user redimensions
// the window during the prompt.
/* Reset the number of lines being printed */
Pager->LineCount = 0;
}
}
if (i > from)
CON_STREAM_WRITE(Pager->Screen->Stream, &szStr[from], i-from);
return TRUE;
}
BOOL
ConPutsPaging(
IN PCON_PAGER Pager,
IN PAGE_PROMPT PagePrompt,
IN BOOL StartPaging,
IN LPTSTR szStr)
{
DWORD len;
/* Return if no string has been given */
if (szStr == NULL)
return TRUE;
len = wcslen(szStr);
return ConWritePaging(Pager, PagePrompt, StartPaging, szStr, len);
}
BOOL
ConResPagingEx(
IN PCON_PAGER Pager,
IN PAGE_PROMPT PagePrompt,
IN BOOL StartPaging,
IN HINSTANCE hInstance OPTIONAL,
IN UINT uID)
{
INT Len;
PWCHAR szStr = NULL;
Len = K32LoadStringW(hInstance, uID, (PWSTR)&szStr, 0);
if (szStr && Len)
return ConWritePaging(Pager, PagePrompt, StartPaging, szStr, Len);
else
return TRUE;
}
BOOL
ConResPaging(
IN PCON_PAGER Pager,
IN PAGE_PROMPT PagePrompt,
IN BOOL StartPaging,
IN UINT uID)
{
return ConResPagingEx(Pager, PagePrompt, StartPaging,
NULL /*GetModuleHandleW(NULL)*/, uID);
}