windows-nt/Source/XPSP1/NT/base/ntsetup/textmode/kernel/sphelp.c
2020-09-26 16:20:57 +08:00

396 lines
10 KiB
C

/*++
Copyright (c) 1993 Microsoft Corporation
Module Name:
sphelp.c
Abstract:
Routines for displaying on-line help during text setup.
Author:
Ted Miller (tedm) 2-Aug-1993
Revision History:
--*/
#include "spprecmp.h"
#pragma hdrstop
#define MAX_HELP_SCREENS 100
PWSTR HelpScreen[MAX_HELP_SCREENS+1];
VOID
SpHelp(
IN ULONG MessageId, OPTIONAL
IN PCWSTR FileText, OPTIONAL
IN ULONG Flags
)
{
UCHAR StatusAttribute, BackgroundAttribute, HeaderAttribute,
ClientAttribute, ClientIntenseAttribute;
PWSTR HelpText,p,q;
ULONG ScreenCount;
ULONG ValidKeys[8];
ULONG CurrentScreen;
ULONG y;
BOOLEAN Intense;
BOOLEAN Done;
unsigned kc;
//
// Pick the video attributes we want
//
if(Flags & SPHELP_LICENSETEXT) {
StatusAttribute = DEFAULT_STATUS_ATTRIBUTE;
BackgroundAttribute = DEFAULT_BACKGROUND;
HeaderAttribute = DEFAULT_ATTRIBUTE;
ClientAttribute = DEFAULT_ATTRIBUTE;
ClientIntenseAttribute = (ATT_FG_INTENSE | ATT_BG_INTENSE);
} else {
StatusAttribute = (ATT_FG_WHITE | ATT_BG_BLUE);
BackgroundAttribute = ATT_WHITE;
HeaderAttribute = (ATT_FG_BLUE | ATT_BG_WHITE);
ClientAttribute = (ATT_FG_BLACK | ATT_BG_WHITE);
ClientIntenseAttribute = (ATT_FG_BLUE | ATT_BG_WHITE);
}
//
// Retreive the help text.
//
if (FileText) {
HelpText = (PWSTR)FileText;
} else {
HelpText = SpRetreiveMessageText(NULL,MessageId,NULL,0);
if (!HelpText) { // no way to return an error code, so fail quietly
goto s0;
}
}
//
// Shop off extra blank lines in the text.
//
p = HelpText + wcslen(HelpText);
while((p > HelpText) && SpIsSpace(*(p-1))) {
p--;
}
if(q = wcschr(p,L'\n')) {
*(++q) = 0;
}
//
// Break up the help text into screens.
// The maximum length of a help screen will be the client screen size
// minus two lines for spacing. A %P alone at the beginning of a line
// forces a page break.
//
for(p=HelpText,ScreenCount=0; *p; ) {
//
// Mark the start of a new screen.
//
HelpScreen[ScreenCount++] = p;
//
// Count lines in the help text.
//
for(y=0; *p; ) {
//
// Determine whether this line is really a hard page break
// or if we have exhausted the number of lines allowed on a screen.
//
if(((p[0] == L'%') && (p[1] == 'P')) || (++y == CLIENT_HEIGHT-2)) {
break;
}
//
// Find next line start.
//
if(q = wcschr(p,L'\r')) {
p = q + 2;
} else {
p = wcschr(p,0);
}
}
//
// Find the end of the line that broke us out of the loop
// and then the start of the next line (if any).
//
if(q = wcschr(p,L'\r')) {
p = q + 2;
} else {
p = wcschr(p,0);
}
if(ScreenCount == MAX_HELP_SCREENS) {
break;
}
}
//
// Sentinal value: point to the terminating nul byte.
//
HelpScreen[ScreenCount] = p;
//
// Display header text in blue on white.
//
SpvidClearScreenRegion(0,0,VideoVars.ScreenWidth,HEADER_HEIGHT,BackgroundAttribute);
if(Flags & SPHELP_LICENSETEXT) {
SpDisplayHeaderText(SP_HEAD_LICENSE,HeaderAttribute);
} else {
SpDisplayHeaderText(SP_HEAD_HELP,HeaderAttribute);
}
//
// The first screen to display is screen 0.
//
CurrentScreen = 0;
Done = FALSE;
do {
SpvidClearScreenRegion(
0,
HEADER_HEIGHT,
VideoVars.ScreenWidth,
VideoVars.ScreenHeight-(HEADER_HEIGHT+STATUS_HEIGHT),
BackgroundAttribute
);
//
// Display the current screen.
//
for(y=HEADER_HEIGHT+1, p=HelpScreen[CurrentScreen]; *p && (p < HelpScreen[CurrentScreen+1]); y++) {
Intense = FALSE;
if(p[0] == L'%') {
if(p[1] == L'I') {
Intense = TRUE;
p += 2;
} else {
if(p[1] == L'P') {
p += 2; // don't display %P
}
}
}
q = wcschr(p,L'\r');
if(q) {
*q = 0;
}
SpvidDisplayString(
p,
(UCHAR)(Intense ? ClientIntenseAttribute : ClientAttribute),
3,
y
);
if(q) {
*q = '\r';
p = q + 2;
} else {
p = wcschr(p,0);
}
}
//
// Construct a list of valid keypresses from the user, depending
// on whether this is the first, last, etc. screen.
//
// If there are previous screens, BACKSPACE=Read Last Help is an option.
// If there are additional screens, ENTER=Continue Reading Help is an option.
// ESC=Cancel Help is always an option for help text.
//
// For licensing text, we allow pageup/pagedown when appropriate,
// and on the last page we allow accept/reject.
//
kc = 0;
if(Flags & SPHELP_LICENSETEXT) {
ValidKeys[kc++] = KEY_F8;
ValidKeys[kc++] = ASCI_ESC;
if(CurrentScreen) {
ValidKeys[kc++] = KEY_PAGEUP;
}
if(CurrentScreen < ScreenCount-1) {
ValidKeys[kc++] = KEY_PAGEDOWN;
}
} else {
ValidKeys[kc++] = ASCI_ESC;
if(CurrentScreen) {
ValidKeys[kc++] = ASCI_BS;
ValidKeys[kc++] = KEY_PAGEUP;
}
if(CurrentScreen < ScreenCount-1) {
ValidKeys[kc++] = ASCI_CR;
ValidKeys[kc++] = KEY_PAGEDOWN;
}
}
ValidKeys[kc] = 0;
if(CurrentScreen && (CurrentScreen < ScreenCount-1)) {
//
// There are screens before and after this one.
//
if(Flags & SPHELP_LICENSETEXT) {
SpDisplayStatusOptions(
StatusAttribute,
SP_STAT_X_EQUALS_ACCEPT_LICENSE,
SP_STAT_X_EQUALS_REJECT_LICENSE,
SP_STAT_PAGEDOWN_EQUALS_NEXT_LIC,
SP_STAT_PAGEUP_EQUALS_PREV_LIC,
0
);
} else {
SpDisplayStatusOptions(
StatusAttribute,
SP_STAT_ENTER_EQUALS_CONTINUE_HELP,
SP_STAT_BACKSP_EQUALS_PREV_HELP,
SP_STAT_ESC_EQUALS_CANCEL_HELP,
0
);
}
} else {
if(CurrentScreen) {
//
// This is the last page but not the only page.
//
if(Flags & SPHELP_LICENSETEXT) {
SpDisplayStatusOptions(
StatusAttribute,
SP_STAT_X_EQUALS_ACCEPT_LICENSE,
SP_STAT_X_EQUALS_REJECT_LICENSE,
SP_STAT_PAGEUP_EQUALS_PREV_LIC,
0
);
} else {
SpDisplayStatusOptions(
StatusAttribute,
SP_STAT_BACKSP_EQUALS_PREV_HELP,
SP_STAT_ESC_EQUALS_CANCEL_HELP,
0
);
}
} else {
if(CurrentScreen < ScreenCount-1) {
//
// This is the first page but additional pages exist.
//
if(Flags & SPHELP_LICENSETEXT) {
SpDisplayStatusOptions(
StatusAttribute,
SP_STAT_X_EQUALS_ACCEPT_LICENSE,
SP_STAT_X_EQUALS_REJECT_LICENSE,
SP_STAT_PAGEDOWN_EQUALS_NEXT_LIC,
0
);
} else {
SpDisplayStatusOptions(
StatusAttribute,
SP_STAT_ENTER_EQUALS_CONTINUE_HELP,
SP_STAT_ESC_EQUALS_CANCEL_HELP,
0
);
}
} else {
//
// This is the only page.
//
if(Flags & SPHELP_LICENSETEXT) {
SpDisplayStatusOptions(
StatusAttribute,
SP_STAT_X_EQUALS_ACCEPT_LICENSE,
SP_STAT_X_EQUALS_REJECT_LICENSE,
0
);
} else {
SpDisplayStatusOptions(
StatusAttribute,
SP_STAT_ESC_EQUALS_CANCEL_HELP,
0
);
}
}
}
}
switch(SpWaitValidKey(ValidKeys,NULL,NULL)) {
case ASCI_ESC:
if(Flags & SPHELP_LICENSETEXT) {
SpDone(0,FALSE,TRUE);
}
// ELSE FALL THROUGH
case KEY_F8:
Done = TRUE;
break;
case KEY_PAGEUP:
case ASCI_BS:
ASSERT(CurrentScreen);
CurrentScreen--;
break;
case KEY_PAGEDOWN:
case ASCI_CR:
ASSERT(CurrentScreen < ScreenCount-1);
CurrentScreen++;
break;
}
} while(!Done);
//
// Clean up.
//
if(!FileText) {
SpMemFree(HelpText);
}
s0:
CLEAR_ENTIRE_SCREEN();
SpDisplayHeaderText(
SpGetHeaderTextId(),
DEFAULT_ATTRIBUTE
);
}