--- /dev/null
+/*
+ * 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);
+}