/* * 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 // limits.h // For MB_LEN_MAX #include #include // #include #include // Console APIs (only if kernel32 support included) #include #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); }