diff options
Diffstat (limited to 'private/utils/mep/help/htest')
-rw-r--r-- | private/utils/mep/help/htest/cons.c | 2200 | ||||
-rw-r--r-- | private/utils/mep/help/htest/cons.h | 253 | ||||
-rw-r--r-- | private/utils/mep/help/htest/htest.c | 1441 | ||||
-rw-r--r-- | private/utils/mep/help/htest/makefile | 6 | ||||
-rw-r--r-- | private/utils/mep/help/htest/sources | 18 |
5 files changed, 3918 insertions, 0 deletions
diff --git a/private/utils/mep/help/htest/cons.c b/private/utils/mep/help/htest/cons.c new file mode 100644 index 000000000..894a78325 --- /dev/null +++ b/private/utils/mep/help/htest/cons.c @@ -0,0 +1,2200 @@ +/*++ + +Copyright (c) 1990 Microsoft Corporation + +Module Name: + + console.c + +Abstract: + + Interface to the console for Win32 applications. + +Author: + + Ramon Juan San Andres (ramonsa) 30-Nov-1990 + + +Revision History: + + +--*/ + +#include <string.h> +#include <malloc.h> +#include <assert.h> +#include <windows.h> + +#define FREE(x) free(x) +#define MALLOC(x) malloc(x) +#define REALLOC(x,y) realloc(x,y) + +#include "cons.h" + + + +// +// EVENT BUFFER +// +// The event buffer is used to store event records from the input +// queue. +// +#define INITIAL_EVENTS 32 +#define MAX_EVENTS 64 +#define EVENT_INCREMENT 4 + +#define ADVANCE TRUE +#define NOADVANCE FALSE +#define WAIT TRUE +#define NOWAIT FALSE + +// +// For accessing fields of an event record +// +#define EVENT_TYPE(p) ((p)->EventType) +#define EVENT_DATA(p) ((p)->Event) + +// +// For casting event records +// +#define PMOUSE_EVT(p) (&(EVENT_DATA(p).MouseEvent)) +#define PWINDOW_EVT(p) (&(EVENT_DATA(p).WindowBufferSizeEvent)) +#define PKEY_EVT(p) (&(EVENT_DATA(p).KeyEvent)) + +// +// The event buffer structure +// +typedef struct EVENT_BUFFER { + DWORD MaxEvents; // Max number of events in buffer + DWORD NumberOfEvents; // Number of events in buffer + DWORD EventIndex; // Event Index + BOOL BusyFlag; // Busy flag + CRITICAL_SECTION CriticalSection; // To maintain integrity + CRITICAL_SECTION PeekCriticalSection; // While peeking + PINPUT_RECORD EventBuffer; // Event Buffer +} EVENT_BUFFER, *PEVENT_BUFFER; + + + + + +// +// Screen attributes +// +#define BLACK_FGD 0 +#define BLUE_FGD FOREGROUND_BLUE +#define GREEN_FGD FOREGROUND_GREEN +#define CYAN_FGD (FOREGROUND_BLUE | FOREGROUND_GREEN) +#define RED_FGD FOREGROUND_RED +#define MAGENTA_FGD (FOREGROUND_BLUE | FOREGROUND_RED) +#define YELLOW_FGD (FOREGROUND_GREEN | FOREGROUND_RED) +#define WHITE_FGD (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED) + +#define BLACK_BGD 0 +#define BLUE_BGD BACKGROUND_BLUE +#define GREEN_BGD BACKGROUND_GREEN +#define CYAN_BGD (BACKGROUND_BLUE | BACKGROUND_GREEN) +#define RED_BGD BACKGROUND_RED +#define MAGENTA_BGD (BACKGROUND_BLUE | BACKGROUND_RED) +#define YELLOW_BGD (BACKGROUND_GREEN | BACKGROUND_RED) +#define WHITE_BGD (BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED) + + + +// +// The AttrBg and AttrFg arrays are used for mapping DOS attributes +// to the new attributes. +// +WORD AttrBg[ ] = { + BLACK_BGD, // black + BLUE_BGD, // blue + GREEN_BGD, // green + CYAN_BGD, // cyan + RED_BGD, // red + MAGENTA_BGD, // magenta + YELLOW_BGD, // brown + WHITE_BGD, // light gray + BACKGROUND_INTENSITY | BLACK_BGD, // dark gray + BACKGROUND_INTENSITY | BLUE_BGD, // light blue + BACKGROUND_INTENSITY | GREEN_BGD, // light green + BACKGROUND_INTENSITY | CYAN_BGD, // light cyan + BACKGROUND_INTENSITY | RED_BGD, // light red + BACKGROUND_INTENSITY | MAGENTA_BGD, // light magenta + BACKGROUND_INTENSITY | YELLOW_BGD, // light yellow + BACKGROUND_INTENSITY | WHITE_BGD // white +}; + +WORD AttrFg[ ] = { + BLACK_FGD, // black + BLUE_FGD, // blue + GREEN_FGD, // green + CYAN_FGD, // cyan + RED_FGD, // red + MAGENTA_FGD, // magenta + YELLOW_FGD, // brown + WHITE_FGD, // light gray + FOREGROUND_INTENSITY | BLACK_FGD, // dark gray + FOREGROUND_INTENSITY | BLUE_FGD, // light blue + FOREGROUND_INTENSITY | GREEN_FGD, // light green + FOREGROUND_INTENSITY | CYAN_FGD, // light cyan + FOREGROUND_INTENSITY | RED_FGD, // light red + FOREGROUND_INTENSITY | MAGENTA_FGD, // light magenta + FOREGROUND_INTENSITY | YELLOW_FGD, // light yellow + FOREGROUND_INTENSITY | WHITE_FGD // white +}; + +// +// GET_ATTRIBUTE performs the mapping from old attributes to new attributes +// +#define GET_ATTRIBUTE(x) (AttrFg[x & 0x000F ] | AttrBg[( x & 0x00F0 ) >> 4]) + + +// +// The LINE_INFO structure contains information about each line in the +// screen buffer. +// +typedef struct _LINE_INFO { + + BOOL Dirty; // True if has not been displayed + int colMinChanged; // if dirty, smallest col changed + int colMaxChanged; // if dirty, biggest col changed + PCHAR_INFO Line; // Pointer to the line. + +} LINE_INFO, *PLINE_INFO; + +#define ResetLineInfo(pli) \ + { pli->Dirty = 0; \ + pli->colMinChanged = 1000; \ + pli->colMaxChanged = -1; \ + } + +// +// The SCREEN_DATA structure contains the information about individual +// screens. +// +typedef struct SCREEN_DATA { + HANDLE ScreenHandle; // Handle to screen + PLINE_INFO LineInfo; // Array of line info. + PCHAR_INFO ScreenBuffer; // Screen buffer + ULONG MaxBufferSize; // Max. buffer size + ATTRIBUTE AttributeOld; // Attribute - original + WORD AttributeNew; // Attribute - converted + ROW FirstRow; // First row to update + ROW LastRow; // Last row to update + CRITICAL_SECTION CriticalSection; // To maintain integrity + DWORD CursorSize; // Cursor Size + SCREEN_INFORMATION ScreenInformation; // Screen information +} SCREEN_DATA, *PSCREEN_DATA; + + +// +// Static global data +// +static EVENT_BUFFER EventBuffer; // Event buffer +static HANDLE hInput; // handle to stdin +static HANDLE hOutput; // handle to stdout +static HANDLE hError; // handle to stderr +static PSCREEN_DATA OutputScreenData; // Screen data for hOutput +static PSCREEN_DATA ActiveScreenData; // Points to current screen data +static BOOL Initialized = FALSE; // Initialized flag + + +#if defined (DEBUG) + static char DbgBuffer[128]; +#endif + + +// +// Local Prototypes +// +BOOL +InitializeGlobalState ( + void + ); + + +PSCREEN_DATA +MakeScreenData ( + HANDLE ScreenHandle + ); + +BOOL +InitLineInfo ( + PSCREEN_DATA ScreenData + ); + +PINPUT_RECORD +NextEvent ( + BOOL fAdvance, + BOOL fWait + ); + +void +MouseEvent ( + PMOUSE_EVENT_RECORD pEvent + ); + +BOOL +WindowEvent ( + PWINDOW_BUFFER_SIZE_RECORD pEvent + ); + +BOOL +KeyEvent ( + PKEY_EVENT_RECORD pEvent, + PKBDKEY pKey + ); + + +BOOL +PutEvent ( + PINPUT_RECORD InputRecord + ); + + +BOOL +InitializeGlobalState ( + void + ) +/*++ + +Routine Description: + + Initializes our global state data. + +Arguments: + + None. + +Return Value: + + TRUE if success + FALSE otherwise. + +--*/ +{ + + + // + // Initialize the event buffer + // + InitializeCriticalSection( &(EventBuffer.CriticalSection) ); + InitializeCriticalSection( &(EventBuffer.PeekCriticalSection) ); + EventBuffer.NumberOfEvents = 0; + EventBuffer.EventIndex = 0; + EventBuffer.BusyFlag = FALSE; + EventBuffer.EventBuffer = MALLOC( INITIAL_EVENTS * sizeof(INPUT_RECORD) ); + + if ( !EventBuffer.EventBuffer ) { + return FALSE; + } + + EventBuffer.MaxEvents = INITIAL_EVENTS; + + + // + // Get handles to stdin, stdout and stderr + // + hInput = GetStdHandle( STD_INPUT_HANDLE ); + hOutput = GetStdHandle( STD_OUTPUT_HANDLE ); + hError = GetStdHandle( STD_ERROR_HANDLE ); + + + // + // Initialize the screen data for hOutput + // + if ( !(OutputScreenData = MakeScreenData( hOutput )) ) { + return FALSE; + } + + + // + // Current screen is hOutput + // + ActiveScreenData = OutputScreenData; + + + return (Initialized = TRUE); + +} + + + + + +PSCREEN_DATA +MakeScreenData ( + HANDLE ScreenHandle + ) +/*++ + +Routine Description: + + Allocates memory for a SCREEN_DATA information and initializes it. + +Arguments: + + ScreenHandle - Supplies handle of screen. + +Return Value: + + POINTER to allocated SCREEN_DATA structure + +--*/ +{ + PSCREEN_DATA ScreenData; // Pointer to screen data + CONSOLE_SCREEN_BUFFER_INFO ScrInfo; // Screen buffer info. + + + // + // Allocate space for the screen data. + // + if ( !(ScreenData = (PSCREEN_DATA)MALLOC(sizeof(SCREEN_DATA))) ) { + return NULL; + } + + // + // Allocate space for our copy of the screen buffer. + // + GetConsoleScreenBufferInfo( ScreenHandle, + &ScrInfo ); + + ScreenData->MaxBufferSize = ScrInfo.dwSize.Y * + ScrInfo.dwSize.X; + + ScreenData->ScreenBuffer = (PCHAR_INFO)MALLOC( ScreenData->MaxBufferSize * + sizeof(CHAR_INFO)); + + if ( !ScreenData->ScreenBuffer ) { + FREE( ScreenData ); + return NULL; + } + + // + // Allocate space for the LineInfo array + // + ScreenData->LineInfo = (PLINE_INFO)MALLOC( ScrInfo.dwSize.Y * sizeof( LINE_INFO ) ); + if ( !ScreenData->LineInfo ) { + FREE( ScreenData->ScreenBuffer ); + FREE( ScreenData ); + return NULL; + } + + + // + // Memory has been allocated, now initialize the structure + // + ScreenData->ScreenHandle = ScreenHandle; + + ScreenData->ScreenInformation.NumberOfRows = ScrInfo.dwSize.Y; + ScreenData->ScreenInformation.NumberOfCols = ScrInfo.dwSize.X; + + ScreenData->ScreenInformation.CursorRow = ScrInfo.dwCursorPosition.Y; + ScreenData->ScreenInformation.CursorCol = ScrInfo.dwCursorPosition.X; + + ScreenData->AttributeNew = ScrInfo.wAttributes; + ScreenData->AttributeOld = 0x00; + + ScreenData->FirstRow = ScreenData->ScreenInformation.NumberOfRows; + ScreenData->LastRow = 0; + + InitializeCriticalSection( &(ScreenData->CriticalSection) ); + + InitLineInfo( ScreenData ); + + return ScreenData; +} + + + + + +BOOL +InitLineInfo ( + PSCREEN_DATA ScreenData + ) +/*++ + +Routine Description: + + Initializes the LineInfo array. + +Arguments: + + ScreenData - Supplies pointer to screen data. + +Return Value: + + TRUE if initialized, false otherwise. + +--*/ +{ + + ROW Row; + COLUMN Cols; + PLINE_INFO LineInfo; + PCHAR_INFO CharInfo; + + + LineInfo = ScreenData->LineInfo; + CharInfo = ScreenData->ScreenBuffer; + Row = ScreenData->ScreenInformation.NumberOfRows; + Cols = ScreenData->ScreenInformation.NumberOfCols; + + while ( Row-- ) { + + // + // BUGBUG Temporary + // + // assert( LineInfo < (ScreenData->LineInfo + ScreenData->ScreenInformation.NumberOfRows)); + // assert( (CharInfo + Cols) <= (ScreenData->ScreenBuffer + ScreenData->MaxBufferSize) ); + + ResetLineInfo (LineInfo); + + LineInfo->Line = CharInfo; + + LineInfo++; + CharInfo += Cols; + + } + + return TRUE; +} + + + + + +PSCREEN +consoleNewScreen ( + void + ) +/*++ + +Routine Description: + + Creates a new screen. + +Arguments: + + None. + +Return Value: + + Pointer to screen data. + +--*/ +{ + PSCREEN_DATA ScreenData; // Screen data + HANDLE NewScreenHandle; + SMALL_RECT NewSize; + CONSOLE_SCREEN_BUFFER_INFO ScrInfo; // Screen buffer info. + CONSOLE_CURSOR_INFO CursorInfo; + + if ( !Initialized ) { + + // + // We have to initialize our global state. + // + if ( !InitializeGlobalState() ) { + return NULL; + } + } + + // + // Create a new screen buffer + // + NewScreenHandle = CreateConsoleScreenBuffer(GENERIC_WRITE | GENERIC_READ, + 0, + NULL, + CONSOLE_TEXTMODE_BUFFER, + NULL ); + + if (NewScreenHandle == INVALID_HANDLE_VALUE) { + // + // No luck + // + return NULL; + } + + // + // We want the new window to be the same size as the current one, so + // we resize it. + // + GetConsoleScreenBufferInfo( ActiveScreenData->ScreenHandle, + &ScrInfo ); + + NewSize.Left = 0; + NewSize.Top = 0; + NewSize.Right = ScrInfo.srWindow.Right - ScrInfo.srWindow.Left; + NewSize.Bottom = ScrInfo.srWindow.Bottom - ScrInfo.srWindow.Top; + + SetConsoleWindowInfo( NewScreenHandle, TRUE, &NewSize ); + + // + // Now we create a screen data structure for it. + // + if ( !(ScreenData = MakeScreenData(NewScreenHandle)) ) { + CloseHandle(NewScreenHandle); + return NULL; + } + + + CursorInfo.bVisible = TRUE; + ScreenData->CursorSize = CursorInfo.dwSize = 25; + + SetConsoleCursorInfo ( ScreenData->ScreenHandle, + &CursorInfo ); + + // + // We are all set. We return a pointer to the + // screen data. + // + return (PSCREEN)ScreenData; +} + + + + + +BOOL +consoleCloseScreen ( + PSCREEN pScreen + ) +/*++ + +Routine Description: + + Closes a screen. + +Arguments: + + pScreen - Supplies pointer to screen data. + +Return Value: + + TRUE if screen closed. + FALSE otherwise + +--*/ +{ + PSCREEN_DATA ScreenData = (PSCREEN_DATA)pScreen; + + // + // We cannot close the active screen + // + if ( !ScreenData || (ScreenData == ActiveScreenData) ) { + return FALSE; + } + + if (ScreenData->ScreenHandle != INVALID_HANDLE_VALUE) { + CloseHandle(ScreenData->ScreenHandle); + } + + FREE( ScreenData->LineInfo ); + FREE( ScreenData->ScreenBuffer ); + FREE( ScreenData ); + + return TRUE; +} + + + + + +PSCREEN +consoleGetCurrentScreen ( + void + ) +/*++ + +Routine Description: + + Returns the current screen. + +Arguments: + + none. + +Return Value: + + Pointer to currently active screen data. + +--*/ +{ + if ( !Initialized ) { + + // + // We have to initialize our global state. + // + if (!InitializeGlobalState()) { + return NULL; + } + } + + return (PSCREEN)ActiveScreenData; +} + + + + + +BOOL +consoleSetCurrentScreen ( + PSCREEN pScreen + ) +/*++ + +Routine Description: + + Sets the active screen. + +Arguments: + + pScreen - Supplies pointer to screen data. + +Return Value: + + TRUE if the active screen set + FALSE otherwise. + +--*/ +{ + BOOL ScreenSet = TRUE; + PSCREEN_DATA CurrentScreen = ActiveScreenData; + + + EnterCriticalSection( &(CurrentScreen->CriticalSection) ); + + ScreenSet = SetConsoleActiveScreenBuffer( ((PSCREEN_DATA)pScreen)->ScreenHandle); + + if (ScreenSet) { + ActiveScreenData = (PSCREEN_DATA)pScreen; + } + + LeaveCriticalSection( &(CurrentScreen->CriticalSection) ); + + return ScreenSet; +} + + + + + +BOOL +consoleGetScreenInformation ( + PSCREEN pScreen, + PSCREEN_INFORMATION pScreenInfo + ) +/*++ + +Routine Description: + + Sets the active screen. + +Arguments: + + pScreen - Supplies pointer to screen data. + pScreenInfo - Supplies pointer to screen info buffer + +Return Value: + + TRUE if the screen info returned + FALSE otherwise. + +--*/ +{ + + PSCREEN_DATA ScreenData = (PSCREEN_DATA)pScreen; + + if (!ScreenData) { + return FALSE; + } + + EnterCriticalSection( &(ScreenData->CriticalSection) ); + + memcpy(pScreenInfo, &(ScreenData->ScreenInformation), sizeof(SCREEN_INFORMATION)); + + LeaveCriticalSection( &(ScreenData->CriticalSection) ); + + return TRUE; +} + + + +BOOL +consoleSetScreenSize ( + PSCREEN pScreen, + ROW Rows, + COLUMN Cols + ) +/*++ + +Routine Description: + + Sets the screen size + +Arguments: + + pScreen - Supplies pointer to screen data. + Rows - Number of rows + Cols - Number of columns + +Return Value: + + TRUE if screen size changed successfully + FALSE otherwise. + +--*/ +{ + + PSCREEN_DATA ScreenData = (PSCREEN_DATA)pScreen; + CONSOLE_SCREEN_BUFFER_INFO ScreenBufferInfo; + SMALL_RECT ScreenRect; + COORD ScreenSize; + USHORT MinRows; + USHORT MinCols; + ULONG NewBufferSize; + BOOL WindowSet = FALSE; + BOOL Status = FALSE; + + // + // Won't attempt to resize larger than the largest window size + // + ScreenSize = GetLargestConsoleWindowSize( ScreenData->ScreenHandle ); + + if ( (Rows > (ROW)ScreenSize.Y) || (Cols > (COLUMN)ScreenSize.X) ) { + return FALSE; + } + + EnterCriticalSection( &(ScreenData->CriticalSection) ); + + // + // Obtain the current screen information. + // + if ( GetConsoleScreenBufferInfo( ScreenData->ScreenHandle, &ScreenBufferInfo ) ) { + + // + // If the desired buffer size is smaller than the current window + // size, we have to resize the current window first. + // + if ( ( Rows < (ROW) + (ScreenBufferInfo.srWindow.Bottom - + ScreenBufferInfo.srWindow.Top + 1) ) || + ( Cols < (COLUMN) + (ScreenBufferInfo.srWindow.Right - + ScreenBufferInfo.srWindow.Left + 1) ) ) { + + // + // Set the window to a size that will fit in the current + // screen buffer and that is no bigger than the size to + // which we want to grow the screen buffer. + // + MinRows = (USHORT)min( (int)Rows, (int)(ScreenBufferInfo.dwSize.Y) ); + MinCols = (USHORT)min( (int)Cols, (int)(ScreenBufferInfo.dwSize.X) ); + + ScreenRect.Top = 0; + ScreenRect.Left = 0; + ScreenRect.Right = (SHORT)MinCols - (SHORT)1; + ScreenRect.Bottom = (SHORT)MinRows - (SHORT)1; + + WindowSet = (BOOL)SetConsoleWindowInfo( ScreenData->ScreenHandle, TRUE, &ScreenRect ); + + if ( !WindowSet ) { + // + // ERROR + // + goto Done; + } + } + + // + // Set the screen buffer size to the desired size. + // + ScreenSize.X = (WORD)Cols; + ScreenSize.Y = (WORD)Rows; + + if ( !SetConsoleScreenBufferSize( ScreenData->ScreenHandle, ScreenSize ) ) { + + // + // ERROR + // + // + // Return the window to its original size. We ignore the return + // code because there is nothing we can do about it. + // + SetConsoleWindowInfo( ScreenData->ScreenHandle, TRUE, &(ScreenBufferInfo.srWindow) ); + + goto Done; + } + + // + // resize the screen buffer. Note that the contents of the screen + // buffer are not valid anymore. Someone else will have to update + // them. + // + NewBufferSize = Rows * Cols; + + if (ScreenData->MaxBufferSize < NewBufferSize ) { + ScreenData->ScreenBuffer = REALLOC( ScreenData->ScreenBuffer, NewBufferSize * sizeof(CHAR_INFO)); + ScreenData->MaxBufferSize = NewBufferSize; + ScreenData->LineInfo = REALLOC( ScreenData->LineInfo, Rows * sizeof( LINE_INFO ) ); + } + + // + // Set the Window Size. We know that we can grow the window to this size + // because we tested the size against the largest window size at the + // beginning of the function. + // + ScreenRect.Top = 0; + ScreenRect.Left = 0; + ScreenRect.Right = (SHORT)Cols - (SHORT)1; + ScreenRect.Bottom = (SHORT)Rows - (SHORT)1; + + WindowSet = (BOOL)SetConsoleWindowInfo( ScreenData->ScreenHandle, TRUE, &ScreenRect ); + + if ( !WindowSet ) { + // + // We could not resize the window. We will leave the + // resized screen buffer. + // + // ERROR + // + goto Done; + } + + // + // Update the screen size + // + ScreenData->ScreenInformation.NumberOfRows = Rows; + ScreenData->ScreenInformation.NumberOfCols = Cols; + + InitLineInfo( ScreenData ); + + // + // Done + // + Status = TRUE; + + } else { + + // + // ERROR + // + } + +Done: + // + // Invalidate the entire screen buffer + // + ScreenData->FirstRow = ScreenData->ScreenInformation.NumberOfRows; + ScreenData->LastRow = 0; + + LeaveCriticalSection( &(ScreenData->CriticalSection) ); + return Status; + +} + + + + +BOOL +consoleSetCursor ( + PSCREEN pScreen, + ROW Row, + COLUMN Col + ) +/*++ + +Routine Description: + + Moves the cursor to a certain position. + +Arguments: + + pScreen - Supplies pointer to screen data + Row - Supplies row coordinate + Col - Supplies column coordinate + +Return Value: + + TRUE if moved + FALSE otherwise. + +--*/ +{ + + PSCREEN_DATA ScreenData = (PSCREEN_DATA)pScreen; + COORD Position; + BOOL Moved = FALSE; + + + EnterCriticalSection( &(ScreenData->CriticalSection) ); + + if ((Row != ScreenData->ScreenInformation.CursorRow) || + (Col != ScreenData->ScreenInformation.CursorCol) ) { + + assert( Row < ScreenData->ScreenInformation.NumberOfRows); + assert( Col < ScreenData->ScreenInformation.NumberOfCols); + + Position.Y = (SHORT)Row; + Position.X = (SHORT)Col; + + if ( SetConsoleCursorPosition( ScreenData->ScreenHandle, + Position )) { + // + // Cursor moved, update the data + // + ScreenData->ScreenInformation.CursorRow = Row; + ScreenData->ScreenInformation.CursorCol = Col; + + Moved = TRUE; + } + } + + LeaveCriticalSection( &(ScreenData->CriticalSection) ); + + return Moved; +} + + + + +BOOL +consoleSetCursorStyle ( + PSCREEN pScreen, + ULONG Style + ) + +/*++ + +Routine Description7: + + Sets the cursor style. The two available styles are: underscrore and + box + +Arguments: + + Style - New cursor style + +Return Value: + + True if cursor style set + +--*/ + +{ + + PSCREEN_DATA ScreenData = (PSCREEN_DATA)pScreen; + CONSOLE_CURSOR_INFO CursorInfo; + + CursorInfo.bVisible = TRUE; + + if ( Style == CURSOR_STYLE_UNDERSCORE ) { + + CursorInfo.dwSize = 25; + + } else if ( Style == CURSOR_STYLE_BOX ) { + + CursorInfo.dwSize = 100; + + } else { + + return FALSE; + + } + + ScreenData->CursorSize = CursorInfo.dwSize; + + return SetConsoleCursorInfo ( ScreenData->ScreenHandle, + &CursorInfo ); + +} + + + + + +ULONG +consoleWriteLine ( + PSCREEN pScreen, + PVOID pBuffer, + ULONG BufferSize, + ROW Row, + COLUMN Col, + ATTRIBUTE Attribute, + BOOL Blank + ) +/*++ + +Routine Description7: + + Writes a buffer to the screen with the specified attribute and blanks + to end of row. + +Arguments: + + pScreen - Supplies pointer to screen data + pBuffer - Supplies pointer to buffer + BufferSize - Supplies the size of the buffer + Row - Supplies row coordinate + Col - Supplies column coordinate + Attr - Supplies the attribute + Blank - TRUE if we should blank to end of last row written. + +Return Value: + + Number of bytes written + +--*/ +{ + + PSCREEN_DATA ScreenData = (PSCREEN_DATA)pScreen; + PLINE_INFO LineInfo; + PCHAR_INFO CharInfo; + CHAR_INFO Char; + WORD Attr; + + char * p = (char *)pBuffer; + + COLUMN ColsLeft; // Available columns + COLUMN InfoCols; // Columns taken from buffer + COLUMN BlankCols; // Columns to be blanked + COLUMN Column; // Counter; + + // + // We will ignore writes outside of the screen buffer + // + if ( ( Row >= ScreenData->ScreenInformation.NumberOfRows ) || + ( Col >= ScreenData->ScreenInformation.NumberOfCols ) ) { + return TRUE; + } + + // + // Ignore trivial writes + // + + if (BufferSize == 0 && !Blank) + return TRUE; + + + EnterCriticalSection( &(ScreenData->CriticalSection) ); + + // + // We will truncate writes that are too long + // + if ( (Col + BufferSize) >= ScreenData->ScreenInformation.NumberOfCols ) { + BufferSize = ScreenData->ScreenInformation.NumberOfCols - Col; + } + + LineInfo = ScreenData->LineInfo + Row; + CharInfo = LineInfo->Line + Col; + + ColsLeft = ScreenData->ScreenInformation.NumberOfCols - Col; + InfoCols = min( BufferSize, ColsLeft ); + BlankCols = Blank ? (ColsLeft - InfoCols) : 0; + + // + // Set the attribute + // + if ( Attribute != ScreenData->AttributeOld ) { + ScreenData->AttributeOld = Attribute; + ScreenData->AttributeNew = GET_ATTRIBUTE(Attribute); + } + Attr = ScreenData->AttributeNew; + + // + // set up default attribute + // + + Char.Attributes = Attr; + + // + // set up number of columns to draw + // + + Column = InfoCols; + + // + // draw chars in all specified columns + // + + while ( Column-- ) { + + // + // use character from input string + // + + Char.Char.AsciiChar = *p++; + + // + // update change portions of line info + // + + if (CharInfo->Attributes != Char.Attributes || + CharInfo->Char.AsciiChar != Char.Char.AsciiChar) { + + LineInfo->colMinChanged = min (LineInfo->colMinChanged, CharInfo - LineInfo->Line); + LineInfo->colMaxChanged = max (LineInfo->colMaxChanged, CharInfo - LineInfo->Line); + LineInfo->Dirty = TRUE; + } + + // + // set up new character + // + + *CharInfo++ = Char; + } + + + // + // Blank to end of line + // + Char.Attributes = Attr; + Char.Char.AsciiChar = ' '; + Column = BlankCols; + while ( Column-- ) { + // + // update change portions of line info + // + + if (CharInfo->Attributes != Char.Attributes || + CharInfo->Char.AsciiChar != Char.Char.AsciiChar) { + + LineInfo->colMinChanged = min (LineInfo->colMinChanged, CharInfo - LineInfo->Line); + LineInfo->colMaxChanged = max (LineInfo->colMaxChanged, CharInfo - LineInfo->Line); + LineInfo->Dirty = TRUE; + } + + *CharInfo++ = Char; + } + + // + // Update row information + // + if ( Row < ScreenData->FirstRow ) { + ScreenData->FirstRow = Row; + } + if ( Row > ScreenData->LastRow ) { + ScreenData->LastRow = Row; + } + + LeaveCriticalSection( &(ScreenData->CriticalSection) ); + + return (ULONG)(InfoCols + BlankCols); +} + + + + + +BOOL +consoleShowScreen ( + PSCREEN pScreen + ) +/*++ + +Routine Description: + + Moves data from our screen buffer to the console screen buffer. + +Arguments: + + pScreen - Supplies pointer to screen data + +Return Value: + + TRUE if done + FALSE otherwise + +--*/ +{ + + PSCREEN_DATA ScreenData = (PSCREEN_DATA)pScreen; + CONSOLE_CURSOR_INFO CursorInfo; + PLINE_INFO LineInfo; + BOOL Shown = FALSE; + ROW FirstRow; + ROW LastRow; + COLUMN LastCol; + + COORD Position; + COORD Size; + SMALL_RECT Rectangle; + + EnterCriticalSection( &(ScreenData->CriticalSection) ); + + if ( ScreenData->FirstRow <= ScreenData->LastRow ) { + + Size.X = (SHORT)(ScreenData->ScreenInformation.NumberOfCols); + Size.Y = (SHORT)(ScreenData->ScreenInformation.NumberOfRows); + + FirstRow = ScreenData->FirstRow; + LineInfo = ScreenData->LineInfo + FirstRow; + + LastCol = ScreenData->ScreenInformation.NumberOfCols-1; + + // + // Find next dirty block + // + while ( (FirstRow <= ScreenData->LastRow) && !LineInfo->Dirty ) { + FirstRow++; + LineInfo++; + } + + while ( FirstRow <= ScreenData->LastRow ) { + + int colLeft, colRight; + + // + // Get the block + // + + LastRow = FirstRow; + + // + // set up for left/right boundary accrual + // + + colLeft = LastCol + 1; + colRight = -1; + + while ( (LastRow <= ScreenData->LastRow) && LineInfo->Dirty ) { + + // + // accrue smallest bounding right/left margins + // + + colLeft = min (colLeft, LineInfo->colMinChanged); + colRight = max (colRight, LineInfo->colMaxChanged); + + // + // reset line information + // + + ResetLineInfo (LineInfo); + + // + // advance to next row + // + + LastRow++; + LineInfo++; + } + LastRow--; + + + // + // Write the block + // + assert( FirstRow <= LastRow ); + + Position.X = (SHORT)colLeft; + Position.Y = (SHORT)FirstRow; + + Rectangle.Top = (SHORT)FirstRow; + Rectangle.Bottom = (SHORT)LastRow; + Rectangle.Left = (SHORT) colLeft; + Rectangle.Right = (SHORT) colRight; + + // + // Performance hack: making the cursor invisible speeds + // screen updates. + // + CursorInfo.bVisible = FALSE; + CursorInfo.dwSize = ScreenData->CursorSize; + SetConsoleCursorInfo ( ScreenData->ScreenHandle, + &CursorInfo ); + + Shown = WriteConsoleOutput( ScreenData->ScreenHandle, + ScreenData->ScreenBuffer, + Size, + Position, + &Rectangle ); + +#if defined (DEBUG) + if ( !Shown ) { + char DbgB[128]; + sprintf(DbgB, "MEP: WriteConsoleOutput Error %d\n", GetLastError() ); + OutputDebugString( DbgB ); + } +#endif + assert( Shown ); + + CursorInfo.bVisible = TRUE; + SetConsoleCursorInfo ( ScreenData->ScreenHandle, + &CursorInfo ); + + FirstRow = LastRow + 1; + + // + // Find next dirty block + // + while ( (FirstRow <= ScreenData->LastRow) && !LineInfo->Dirty ) { + FirstRow++; + LineInfo++; + } + } + + ScreenData->LastRow = 0; + ScreenData->FirstRow = ScreenData->ScreenInformation.NumberOfRows; + + } + + LeaveCriticalSection( &(ScreenData->CriticalSection) ); + + return Shown; + +} + + + + + +BOOL +consoleClearScreen ( + PSCREEN pScreen, + BOOL ShowScreen + ) +/*++ + +Routine Description: + + Clears the screen + +Arguments: + + pScreen - Supplies pointer to screen data + +Return Value: + + TRUE if screen cleared + FALSE otherwise + +--*/ +{ + PSCREEN_DATA ScreenData = (PSCREEN_DATA)pScreen; + ROW Rows; + BOOL Status = TRUE; + + EnterCriticalSection( &(ScreenData->CriticalSection) ); + + Rows = ScreenData->ScreenInformation.NumberOfRows; + + while ( Rows-- ) { + consoleWriteLine( pScreen, NULL, 0, Rows, 0, ScreenData->AttributeOld, TRUE ); + } + + if (ShowScreen) { + Status = consoleShowScreen( pScreen ); + } + + LeaveCriticalSection( &(ScreenData->CriticalSection) ); + + return Status; +} + + + + + + + +BOOL +consoleSetAttribute ( + PSCREEN pScreen, + ATTRIBUTE Attribute + ) +/*++ + +Routine Description: + + Sets the console attribute + +Arguments: + + pScreen - Supplies pointer to screen data + Attribute - Supplies the attribute + +Return Value: + + TRUE if Attribute set + FALSE otherwise + +--*/ +{ + + PSCREEN_DATA ScreenData = (PSCREEN_DATA)pScreen; + + EnterCriticalSection( &(ScreenData->CriticalSection) ); + + if (Attribute != ScreenData->AttributeOld) { + ScreenData->AttributeOld = Attribute; + ScreenData->AttributeNew = GET_ATTRIBUTE(Attribute); + } + + LeaveCriticalSection( &(ScreenData->CriticalSection) ); + + return TRUE; +} + + + + + + + + + +BOOL +consoleFlushInput ( + void + ) +/*++ + +Routine Description: + + Flushes input events. + +Arguments: + + None. + +Return Value: + + TRUE if success, FALSE otherwise + +--*/ +{ + EventBuffer.NumberOfEvents = 0; + + return FlushConsoleInputBuffer( hInput ); +} + + + + + + + +BOOL +consoleGetMode ( + PKBDMODE pMode + ) +/*++ + +Routine Description: + + Get current console mode. + +Arguments: + + pMode - Supplies a pointer to the mode flag variable + +Return Value: + + TRUE if success, FALSE otherwise. + +--*/ +{ + return GetConsoleMode( hInput, + pMode ); +} + + + + + + +BOOL +consoleSetMode ( + KBDMODE Mode + ) +/*++ + +Routine Description: + + Sets the console mode. + +Arguments: + + Mode - Supplies the mode flags. + +Return Value: + + TRUE if success, FALSE otherwise + +--*/ +{ + return SetConsoleMode( hInput, + Mode ); +} + + +BOOL +consoleIsKeyAvailable ( + void + ) +/*++ + +Routine Description: + + Returns TRUE if a key is available in the event buffer. + +Arguments: + + None. + +Return Value: + + TRUE if a key is available in the event buffer + FALSE otherwise + +--*/ + +{ + BOOL IsKey = FALSE; + PINPUT_RECORD pEvent; + DWORD Index; + + EnterCriticalSection( &(EventBuffer.CriticalSection) ); + + for ( Index = EventBuffer.EventIndex; Index < EventBuffer.NumberOfEvents; Index++ ) { + + pEvent = EventBuffer.EventBuffer + EventBuffer.EventIndex; + + if ( ((EVENT_TYPE(pEvent)) == KEY_EVENT) && + (PKEY_EVT(pEvent))->bKeyDown ) { + IsKey = TRUE; + break; + } + } + + LeaveCriticalSection( &(EventBuffer.CriticalSection) ); + + return IsKey; +} + + + + +BOOL +consoleDoWindow ( + void + ) + +/*++ + +Routine Description: + + Responds to a window event + +Arguments: + + None. + +Return Value: + + TRUE if window changed + FALSE otherwise + +--*/ + +{ + + PINPUT_RECORD pEvent; + + pEvent = NextEvent( NOADVANCE, NOWAIT ); + + if (( EVENT_TYPE(pEvent) ) == WINDOW_BUFFER_SIZE_EVENT) { + + pEvent = NextEvent( ADVANCE, WAIT ); + WindowEvent(PWINDOW_EVT(pEvent)); + } + + return FALSE; + +} + + + + + +BOOL +consolePeekKey ( + PKBDKEY Key + ) + +/*++ + +Routine Description: + + Gets the next key from the input buffer if the buffer is not empty. + + +Arguments: + + Key - Supplies a pointer to a key structure + +Return Value: + + TRUE if keystroke read, FALSE otherwise. + +--*/ + +{ + + PINPUT_RECORD pEvent; + BOOL Done = FALSE; + BOOL IsKey = FALSE; + + EnterCriticalSection(&(EventBuffer.PeekCriticalSection)); + + do { + + pEvent = NextEvent( NOADVANCE, NOWAIT ); + + if ( pEvent ) { + + switch ( EVENT_TYPE(pEvent) ) { + + case KEY_EVENT: + if (KeyEvent(PKEY_EVT(pEvent), Key)){ + IsKey = TRUE; + Done = TRUE; + } + break; + + case MOUSE_EVENT: + Done = TRUE; + break; + + + case WINDOW_BUFFER_SIZE_EVENT: + Done = TRUE; + break; + + default: + assert( FALSE ); + break; + } + + if ( !Done ) { + NextEvent( ADVANCE, NOWAIT ); + } + + } else { + Done = TRUE; + } + + } while ( !Done ); + + LeaveCriticalSection(&(EventBuffer.PeekCriticalSection)); + + return IsKey; + +} + + + + + + +BOOL +consoleGetKey ( + PKBDKEY Key, + BOOL fWait + ) +/*++ + +Routine Description: + + Gets the next key from the input buffer. + +Arguments: + + Key - Supplies a pointer to a key structure + fWait - Supplies a flag: + if TRUE, the function blocks until a key is ready. + if FALSE, the function returns immediately. + +Return Value: + + TRUE if keystroke read, FALSE otherwise. + +--*/ +{ + + PINPUT_RECORD pEvent; + + do { + pEvent = NextEvent( ADVANCE, fWait ); + + if (pEvent) { + + switch ( EVENT_TYPE(pEvent) ) { + + case KEY_EVENT: + if (KeyEvent(PKEY_EVT(pEvent), Key)) { + return TRUE; + } + break; + + case MOUSE_EVENT: + MouseEvent(PMOUSE_EVT(pEvent)); + break; + + case WINDOW_BUFFER_SIZE_EVENT: + WindowEvent(PWINDOW_EVT(pEvent)); + break; + + default: + break; + } + } + } while (fWait); + + return FALSE; +} + + +BOOL +consolePutKey ( + PKBDKEY Key + ) +/*++ + +Routine Description: + + Puts a key in the console's input buffer + +Arguments: + + Key - Supplies a pointer to a key structure + +Return Value: + + TRUE if key put, false otherwise + +--*/ +{ + + INPUT_RECORD InputRecord; + + InputRecord.EventType = KEY_EVENT; + + InputRecord.Event.KeyEvent.bKeyDown = FALSE; + InputRecord.Event.KeyEvent.wRepeatCount = 0; + InputRecord.Event.KeyEvent.wVirtualKeyCode = Key->Scancode; + InputRecord.Event.KeyEvent.wVirtualScanCode = 0; + InputRecord.Event.KeyEvent.uChar.UnicodeChar = Key->Unicode; + InputRecord.Event.KeyEvent.dwControlKeyState = Key->Flags; + + if ( PutEvent( &InputRecord )) { + InputRecord.Event.KeyEvent.bKeyDown = TRUE; + return PutEvent( &InputRecord ); + } + return FALSE; +} + + +BOOL +consolePutMouse( + ROW Row, + COLUMN Col, + DWORD MouseFlags + ) +/*++ + +Routine Description: + + Puts a mose event in the console's input buffer + +Arguments: + + Row - Supplies the row + Col - Supplies the column + MouseFlags - Supplies the flags + +Return Value: + + TRUE if key put, false otherwise + +--*/ +{ + + INPUT_RECORD InputRecord; + COORD Position; + DWORD Flags; + + InputRecord.EventType = MOUSE_EVENT; + + Position.Y = (WORD)(Row - 1); + Position.X = (WORD)(Col - 1); + + Flags = 0; + + + InputRecord.Event.MouseEvent.dwMousePosition = Position; + InputRecord.Event.MouseEvent.dwButtonState = Flags; + InputRecord.Event.MouseEvent.dwControlKeyState = 0; + InputRecord.Event.MouseEvent.dwEventFlags = 0; + + return PutEvent( &InputRecord ); +} + + + +BOOL +consoleIsBusyReadingKeyboard ( + ) +/*++ + +Routine Description: + + Determines if the console is busy reading the keyboard + +Arguments: + + None + +Return Value: + + TRUE if console is busy reading the keyboard. + +--*/ +{ + BOOL Busy; + + EnterCriticalSection(&(EventBuffer.CriticalSection)); + Busy = EventBuffer.BusyFlag; + LeaveCriticalSection(&(EventBuffer.CriticalSection)); + + return Busy; +} + + + +BOOL +consoleEnterCancelEvent ( + ) +{ + + INPUT_RECORD Record; + + Record.EventType = KEY_EVENT; + Record.Event.KeyEvent.bKeyDown = TRUE; + Record.Event.KeyEvent.wRepeatCount = 0; + Record.Event.KeyEvent.wVirtualKeyCode = VK_CANCEL; + Record.Event.KeyEvent.wVirtualScanCode = 0; + Record.Event.KeyEvent.uChar.AsciiChar = 0; + Record.Event.KeyEvent.dwControlKeyState = 0; + + return PutEvent( &Record ); +} + + +PINPUT_RECORD +NextEvent ( + BOOL fAdvance, + BOOL fWait + ) +/*++ + +Routine Description: + + Returns pointer to next event record. + +Arguments: + + fAdvance - Supplies a flag: + if TRUE: Advance to next event record + if FALSE: Do not advance to next event record + + fWait - Supplies a flag: + if TRUE, the blocks until an event is ready. + if FALSE, return immediately. + +Return Value: + + Pointer to event record, or NULL. + +--*/ +{ + PINPUT_RECORD pEvent; + BOOL Success; + + EnterCriticalSection(&(EventBuffer.CriticalSection)); + + // + // If the busy flag is set, then the buffer is in the process of + // being read. Only one thread should want to wait, so it is + // safe to simply return. + // + if ( EventBuffer.BusyFlag ) { + assert( !fWait ); + LeaveCriticalSection(&(EventBuffer.CriticalSection)); + return NULL; + } + + if (EventBuffer.NumberOfEvents == 0) { + + // + // No events in buffer, read as many as we can + // + DWORD NumberOfEvents; + + // + // If the buffer is too big, resize it + // + if ( EventBuffer.MaxEvents > MAX_EVENTS ) { + + EventBuffer.EventBuffer = REALLOC( EventBuffer.EventBuffer, + MAX_EVENTS * sizeof( INPUT_RECORD ) ); + + EventBuffer.MaxEvents = MAX_EVENTS; + assert( EventBuffer.EventBuffer ); + + //CleanExit( 1, 0 ); + } + + Success = PeekConsoleInput( hInput, + EventBuffer.EventBuffer, + EventBuffer.MaxEvents, + &NumberOfEvents); + + if ((!Success || (NumberOfEvents == 0)) && (!fWait)) { + // + // No events available and don't want to wait, + // return. + // + LeaveCriticalSection(&(EventBuffer.CriticalSection)); + return NULL; + } + + // + // Since we will block, we have to leave the critical section. + // We set the Busy flag to indicate that the buffer is being + // read. + // + EventBuffer.BusyFlag = TRUE; + LeaveCriticalSection(&(EventBuffer.CriticalSection)); + + Success = ReadConsoleInput (hInput, + EventBuffer.EventBuffer, + EventBuffer.MaxEvents, + &EventBuffer.NumberOfEvents); + + EnterCriticalSection(&(EventBuffer.CriticalSection)); + + EventBuffer.BusyFlag = FALSE; + + if (!Success) { +#if defined( DEBUG ) + OutputDebugString(" Error: Cannot read console events\n"); + assert( Success ); +#endif + EventBuffer.NumberOfEvents = 0; + } + EventBuffer.EventIndex = 0; + } + + pEvent = EventBuffer.EventBuffer + EventBuffer.EventIndex; + + // + // If Advance flag is set, we advance the pointer to the next + // record. + // + if (fAdvance) { + if (--(EventBuffer.NumberOfEvents)) { + + switch (EVENT_TYPE(pEvent)) { + + case KEY_EVENT: + case MOUSE_EVENT: + case WINDOW_BUFFER_SIZE_EVENT: + (EventBuffer.EventIndex)++; + break; + + default: +#if defined( DEBUG) + sprintf(DbgBuffer, "WARNING: unknown event type %X\n", EVENT_TYPE(pEvent)); + OutputDebugString(DbgBuffer); +#endif + (EventBuffer.EventIndex)++; + break; + } + } + } + + + LeaveCriticalSection(&(EventBuffer.CriticalSection)); + + return pEvent; +} + + + + + +void +MouseEvent ( + PMOUSE_EVENT_RECORD pEvent + ) +/*++ + +Routine Description: + + Processes mouse events. + +Arguments: + + pEvent - Supplies pointer to event record + +Return Value: + + None.. + +--*/ +{ + +} + + + + + +BOOL +WindowEvent ( + PWINDOW_BUFFER_SIZE_RECORD pEvent + ) +/*++ + +Routine Description: + + Processes window size change events. + +Arguments: + + pEvent - Supplies pointer to event record + +Return Value: + + None + +--*/ +{ + return TRUE; +} + + + + + +BOOL +KeyEvent ( + PKEY_EVENT_RECORD pEvent, + PKBDKEY pKey + ) +/*++ + +Routine Description: + + Processes key events. + +Arguments: + + pEvent - Supplies pointer to event record + pKey - Supplies pointer to key structure to fill out. + +Return Value: + + TRUE if key structured filled out, FALSE otherwise. + +--*/ +{ + // static BOOL AltPressed = FALSE; + + if (pEvent->bKeyDown) { + + WORD Scan = pEvent->wVirtualKeyCode; + + // + // Pressing the ALT key generates an event, but we filter this + // out. + // + if (Scan == VK_MENU) { + return FALSE; + } + + + if (Scan != VK_NUMLOCK && // NumLock + Scan != VK_CAPITAL && // Caps Lock + Scan != VK_SHIFT && // Shift + Scan != VK_CONTROL ) { // Ctrl + + pKey->Unicode = pEvent->uChar.UnicodeChar; + pKey->Scancode = pEvent->wVirtualKeyCode; + pKey->Flags = pEvent->dwControlKeyState; + +//#if defined (DEBUG) +// sprintf(DbgBuffer, " KEY: Scan %d '%c'\n", pKey->Scancode, pKey->Unicode ); +// OutputDebugString(DbgBuffer); +//#endif + return TRUE; + + } else { + + return FALSE; + + } + + } else { + + return FALSE; + + } +} + + +BOOL +PutEvent ( + PINPUT_RECORD InputRecord + ) +{ + + EnterCriticalSection(&(EventBuffer.CriticalSection)); + + // + // If no space at beginning of buffer, resize and shift right + // + if ( EventBuffer.EventIndex == 0 ) { + + EventBuffer.EventBuffer = REALLOC( EventBuffer.EventBuffer, + (EventBuffer.MaxEvents + EVENT_INCREMENT) * sizeof(INPUT_RECORD)); + + if ( !EventBuffer.EventBuffer ) { + //CleanExit(1, 0); + } + + memmove( EventBuffer.EventBuffer + EVENT_INCREMENT, + EventBuffer.EventBuffer , + EventBuffer.NumberOfEvents * sizeof(INPUT_RECORD) ); + + EventBuffer.EventIndex = EVENT_INCREMENT; + } + + // + // Add event + // + EventBuffer.EventIndex--; + EventBuffer.NumberOfEvents++; + + memcpy( EventBuffer.EventBuffer + EventBuffer.EventIndex, + InputRecord, + sizeof(INPUT_RECORD )); + + LeaveCriticalSection(&(EventBuffer.CriticalSection)); + + return TRUE; +} diff --git a/private/utils/mep/help/htest/cons.h b/private/utils/mep/help/htest/cons.h new file mode 100644 index 000000000..8dd1846e5 --- /dev/null +++ b/private/utils/mep/help/htest/cons.h @@ -0,0 +1,253 @@ +/*++ + +Copyright (c) 1990 Microsoft Corporation + +Module Name: + + console.h + +Abstract: + + Interface to the console-management functions for Win32 applications. + +Author: + + Ramon Juan San Andres (ramonsa) 30-Nov-1990 + + +Revision History: + + +--*/ + + + + +// +// Some common typedefs... +// +typedef ULONG ROW, *PROW; // row +typedef ULONG COLUMN, *PCOLUMN; // column +typedef DWORD KBDMODE, *PKBDMODE; // Keyboard mode +typedef DWORD ATTRIBUTE, *PATTRIBUTE; // Screen Attribute +typedef PVOID PSCREEN; // The screen + + + +// +// Console Input Mode flags. They are the same as the NT flags +// +#define CONS_ENABLE_LINE_INPUT ENABLE_LINE_INPUT +#define CONS_ENABLE_PROCESSED_INPUT ENABLE_PROCESSED_INPUT +#define CONS_ENABLE_ECHO_INPUT ENABLE_ECHO_INPUT +#define CONS_ENABLE_WINDOW_INPUT ENABLE_WINDOW_INPUT +#define CONS_ENABLE_MOUSE_INPUT ENABLE_MOUSE_INPUT + +// +// Cursor styles +// +#define CURSOR_STYLE_UNDERSCORE 0 +#define CURSOR_STYLE_BOX 1 + + +// +// The information about a screen is retrieved in the following +// structure: +// +typedef struct SCREEN_INFORMATION { + ROW NumberOfRows; // Number of rows + COLUMN NumberOfCols; // Number of columns + ROW CursorRow; // Cursor row position + COLUMN CursorCol; // Cursor column position +} SCREEN_INFORMATION, *PSCREEN_INFORMATION; + + + + +// +// The information about each keystroke is returned in +// the KBDKEY structure. +// +typedef struct KBDKEY { + WORD Unicode; // character unicode + WORD Scancode; // key scan code + DWORD Flags; // keyboard state flags +} KBDKEY, *PKBDKEY; + +// +// The following macros access particular fields within the +// KBDKEY structure. They exist to facilitate porting of OS/2 +// programs. +// +#define KBDKEY_ASCII(k) (UCHAR)((k).Unicode) +#define KBDKEY_SCAN(k) ((k).Scancode) +#define KBDKEY_FLAGS(k) ((k).Flags) + + +#define NEXT_EVENT_NONE 0 +#define NEXT_EVENT_KEY 1 +#define NEXT_EVENT_WINDOW 2 + +// +// ControlKeyState flags. They are the same as the NT status flags. +// +#define CONS_RIGHT_ALT_PRESSED RIGHT_ALT_PRESSED +#define CONS_LEFT_ALT_PRESSED LEFT_ALT_PRESSED +#define CONS_RIGHT_CTRL_PRESSED RIGHT_CTRL_PRESSED +#define CONS_LEFT_CTRL_PRESSED LEFT_CTRL_PRESSED +#define CONS_SHIFT_PRESSED SHIFT_PRESSED +#define CONS_NUMLOCK_PRESSED NUMLOCK_ON +#define CONS_SCROLLLOCK_PRESSED SCROLLLOCK_ON +#define CONS_CAPSLOCK_PRESSED CAPSLOCK_ON +#define CONS_ENHANCED_KEY ENHANCED_KEY + + + + + +// +// Screen Management functions +// +PSCREEN +consoleNewScreen ( + void + ); + +BOOL +consoleCloseScreen ( + PSCREEN pScreen + ); + +PSCREEN +consoleGetCurrentScreen ( + void + ); + +BOOL +consoleSetCurrentScreen ( + PSCREEN pScreen + ); + +BOOL +consoleGetScreenInformation ( + PSCREEN pScreen, + PSCREEN_INFORMATION pScreenInformation + ); + +BOOL +consoleSetScreenSize ( + PSCREEN Screen, + ROW Rows, + COLUMN Cols + ); + + + +// +// Cursor management +// +BOOL +consoleSetCursor ( + PSCREEN pScreen, + ROW Row, + COLUMN Col + ); + +// +// Cursor style +// +BOOL +consoleSetCursorStyle ( + PSCREEN pScreen, + ULONG Style + ); + + + +// +// Screen output functions +// +ULONG +consoleWriteLine ( + PSCREEN pScreen, + PVOID pBuffer, + ULONG BufferSize, + ROW Row, + COLUMN Col, + ATTRIBUTE Attribute, + BOOL Blank + ); + +BOOL +consoleShowScreen ( + PSCREEN pScreen + ); + +BOOL +consoleClearScreen ( + PSCREEN pScreen, + BOOL ShowScreen + ); + +BOOL +consoleSetAttribute ( + PSCREEN pScreen, + ATTRIBUTE Attribute + ); + + + + + + + +// +// Input functions +// +BOOL +consoleFlushInput ( + void + ); + +BOOL +consoleIsKeyAvailable ( + void + ); + +BOOL +consoleDoWindow ( + void + ); + +BOOL +consoleGetKey ( + PKBDKEY pKey, + BOOL fWait + ); + +BOOL +consolePutKey ( + PKBDKEY pKey + ); + +BOOL +consolePutMouse ( + ROW Row, + COLUMN Col, + DWORD MouseFlags + ); + +BOOL +consolePeekKey ( + PKBDKEY pKey + ); + +BOOL +consoleGetMode ( + PKBDMODE Mode + ); + +BOOL +consoleSetMode ( + KBDMODE Mode + ); diff --git a/private/utils/mep/help/htest/htest.c b/private/utils/mep/help/htest/htest.c new file mode 100644 index 000000000..76b4d8dce --- /dev/null +++ b/private/utils/mep/help/htest/htest.c @@ -0,0 +1,1441 @@ +/*** htest - help engine test harness +* +* Copyright <C> 1987, Microsoft Corporation +* +* Revision History: +* +* 15-Dec-1988 ln Added dump command +* [] 21-Oct-1988 LN New Version +* +*************************************************************************/ + +#include <io.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#if defined (OS2) +#define INCL_SUB +#define INCL_DOSMODULEMGR +#define INCL_DOSFILEMGR +#define INCL_DOSMISC +#include <ctype.h> +#include <os2.h> +#else +#include <windows.h> +#endif + +#include "cons.h" + +#include "help.h" +#include "helpfile.h" /* help file format definition */ +#include "helpsys.h" /* internal (help sys only) decl*/ + +#if defined (OS2) +#define HELPDLL_NAME "mshelp1.dll" +#define HELPDLL_BASE "mshelp1" +#else +#define HELPDLL_NAME "mshelp.dll" +#define HELPDLL_BASE "mshelp" +#endif +/* + * text color values + */ +#define BLACK 0 +#define BLUE 1 +#define GREEN 2 +#define CYAN 3 +#define RED 4 +#define MAGENTA 5 +#define BROWN 6 +#define WHITE 7 +#define GREY 8 +#define LIGHTBLUE 9 +#define LIGHTGREEN 10 +#define LIGHTCYAN 11 +#define LIGHTRED 12 +#define LIGHTMAGENTA 13 +#define YELLOW 14 +#define BRIGHTWHITE 15 + +#define BUFSIZE 128 /* text buffer size */ + +#define ISERROR(x) (((x).mh == 0L) && ((x).cn <= HELPERR_MAX)) +#define SETERROR(x,y) { (x).mh = 0L; (x).cn = y;} + +typedef void pascal (*void_F) (void); +typedef int pascal (*int_F) (void); +typedef ushort pascal (*ushort_F) (void); +typedef f pascal (*f_F) (void); +typedef char * pascal (*pchar_F) (void); +typedef nc pascal (*nc_F) (void); +typedef mh pascal (*mh_F) (void); + +#if !defined (HELP_HACK) + +#define HelpcLines ((int_F) (pEntry[P_HelpcLines ])) +#define HelpClose ((void_F) (pEntry[P_HelpClose ])) +#define HelpCtl ((void_F) (pEntry[P_HelpCtl ])) +#define HelpDecomp ((f_F) (pEntry[P_HelpDecomp ])) +#define HelpGetCells ((int_F) (pEntry[P_HelpGetCells ])) +#define HelpGetInfo ((inf_F) (pEntry[P_HelpGetInfo ])) +#define HelpGetLine ((ushort_F) (pEntry[P_HelpGetLine ])) +#define HelpGetLineAttr ((ushort_F) (pEntry[P_HelpGetLineAttr])) +#define HelpHlNext ((f_F) (pEntry[P_HelpHlNext ])) +#define HelpLook ((ushort_F) (pEntry[P_HelpLook ])) +#define HelpNc ((nc_F) (pEntry[P_HelpNc ])) +#define HelpNcBack ((nc_F) (pEntry[P_HelpNcBack ])) +#define HelpNcCb ((ushort_F) (pEntry[P_HelpNcCb ])) +#define HelpNcCmp ((nc_F) (pEntry[P_HelpNcCmp ])) +#define HelpNcNext ((nc_F) (pEntry[P_HelpNcNext ])) +#define HelpNcPrev ((nc_F) (pEntry[P_HelpNcPrev ])) +#define HelpNcRecord ((void_F) (pEntry[P_HelpNcRecord ])) +#define HelpNcUniq ((nc_F) (pEntry[P_HelpNcUniq ])) +#define HelpOpen ((nc_F) (pEntry[P_HelpOpen ])) +#define HelpShrink ((void_F) (pEntry[P_HelpShrink ])) +#define HelpSzContext ((f_F) (pEntry[P_HelpSzContext ])) +#define HelpXRef ((pchar_F) (pEntry[P_HelpXRef ])) +#define LoadFdb ((f_F) (pEntry[P_LoadFdb ])) +#define LoadPortion ((mh_F) (pEntry[P_LoadPortion ])) + +#endif + +enum { + P_HelpcLines, + P_HelpClose, + P_HelpCtl, + P_HelpDecomp, + P_HelpGetCells, + P_HelpGetInfo, + P_HelpGetLine, + P_HelpGetLineAttr, + P_HelpHlNext, + P_HelpLook, + P_HelpNc, + P_HelpNcBack, + P_HelpNcCb, + P_HelpNcCmp, + P_HelpNcNext, + P_HelpNcPrev, + P_HelpNcRecord, + P_HelpNcUniq, + P_HelpOpen, + P_HelpShrink, + P_HelpSzContext, + P_HelpXRef, + P_LoadFdb, + P_LoadPortion, + LASTENTRYPOINT + } ENTRYPOINTS; + +#define NUM_ENTRYPOINTS (LASTENTRYPOINT - P_HelpcLines) + + +typedef nc pascal (*PHF) (void); + + +/* + * Global Data + */ +char buf[BUFSIZ]; /* text buffer */ +char cell[2] = {' ',0x1f}; /* background clearing cell */ +#define ColorByte cell[1] +int curline; /* current line output */ +char *errTbl[] = { + "", + "help file not found", + "ReadHelpFile failed on header", + "to many open helpfiles", + "bad appeneded file", + "Not a help file", + "newer or incompatible help file", + "memory allocation failed" + }; +f fBoth = FALSE; /* both stdout & screen */ +f fEnable = FALSE; /* enable control lines in disp */ +int iNcCur; /* current index in ncTbl */ +int lastline; +int lLast; /* last starting line number disp*/ +mh mhTopicCur; /* mem handle for most recent */ +uchar mpAttr[] = { /* on-screen color map */ + 0x1f, /* 0: normal text */ + 0x1c, /* 1: bold */ + 0x1a, /* 2: italics */ + 0x1e, /* 3: bold italics */ + 0x7f, /* 4: underline */ + 0x7c, /* 5: bold ul */ + 0x7a, /* 6: italics ul */ + 0x7e /* 7: bold italics ul */ + }; +nc ncCur; /* most recently read in topic */ +nc ncTbl[MAXFILES]; /* table of open nc's */ +char far * pTopicCur; /* ptr to most recent topic */ +char *spaces = " \r\n"; + +#if defined (OS2) +HMODULE hModule; +#else +HANDLE hModule; +#endif + +PHF pEntry[NUM_ENTRYPOINTS] = {0}; +#if defined (OS2) +char * szEntryName[NUM_ENTRYPOINTS] = { + "_HelpcLines", + "_HelpClose", + "_HelpCtl", + "_HelpDecomp", + "_HelpGetCells", + "_HelpGetInfo", + "_HelpGetLine", + "_HelpGetLineAttr", + "_HelpHlNext", + "_HelpLook", + "_HelpNc", + "_HelpNcBack", + "_HelpNcCb", + "_HelpNcCmp", + "_HelpNcNext", + "_HelpNcPrev", + "_HelpNcRecord", + "_HelpNcUniq", + "_HelpOpen", + "_HelpShrink", + "_HelpSzContext", + "_HelpXRef", + "_LoadFdb", + "_LoadPortion", + }; + +#else +char * szEntryName[NUM_ENTRYPOINTS] = { + "HelpcLines", + "HelpClose", + "HelpCtl", + "HelpDecomp", + "HelpGetCells", + "HelpGetInfo", + "HelpGetLine", + "HelpGetLineAttr", + "HelpHlNext", + "HelpLook", + "HelpNc", + "HelpNcBack", + "HelpNcCb", + "HelpNcCmp", + "HelpNcNext", + "HelpNcPrev", + "HelpNcRecord", + "HelpNcUniq", + "HelpOpen", + "HelpShrink", + "HelpSzContext", + "HelpXRef", + "LoadFdb", + "LoadPortion", + }; + +#endif + +// rjsa VIOMODEINFO screen; + +/* + * Forward declarations + */ +#define ASSERTDOS(x) assertDos(x, __FILE__, __LINE__) +void pascal near assertDos (USHORT, CHAR *, USHORT); +void pascal near cls (void); +void pascal near dispCmd (int, int); +void pascal near dumpCmd (); +void pascal near dumpfileCmd ( char *); +void pascal near fileCmd (char *); +void pascal near helpCmd (void); +void pascal near lookupCmd (char *, int); +void pascal near outtext (char *, BYTE); +void pascal near outtextat (char *, int, int, BYTE); +uchar far * pascal near phrasecopy (uchar *, uchar far *); +void pascal near xrefCmd (char *); + +#undef HelpDealloc +#undef HelpLock +#undef HelpUnlock + +void pascal far HelpDealloc (mh); +void far * pascal far HelpLock (mh); +void pascal far HelpUnlock (mh); + +f pascal near LoadFdb (mh, fdb far *); +mh pascal near LoadPortion (USHORT, mh); +//char far * pascal near hfstrcpy(char far *, char far *); +//ushort pascal near hfstrlen(char far *); + + +void LoadTheDll(void); +USHORT WrtCellStr (PBYTE buf, int cb, int row, int col); +USHORT WrtLineAttr( PBYTE buf, lineattr* rgAttr, int cb, int row, int col ); +USHORT WrtCharStrAtt (PBYTE pText, int cb, int row, int col, PBYTE pcolor); + + +PSCREEN Scr; + +/*** main - main program +* +* Input: +* Standard C main, all ignored +* +* Output: +* Returns via exit() +* +*************************************************************************/ +void main( +USHORT argc, +char **argv +) { +char c; +nc ncNull = {0,0}; +SCREEN_INFORMATION ScrInfo; +/* + * parse any options + */ +if (argc > 1) + while ((** ++argv) == '-') { + c = *(++(*argv)); + switch (toupper(c)) { + case 'B': /* -b: both screen and stdout */ + fBoth = TRUE; + break; + default: + fputs ("Unknown switch ignored", stderr); + break; + } + } + +// InitializeGlobalState(); +Scr = consoleGetCurrentScreen(); + +// Load help engine DLL and initialize pointers to entry +// points. +// +LoadTheDll(); + +#if defined(CLEAR) +HelpInit(); +#endif + +/* + * Start by getting the current config & clearing screen. + */ +// rjsa screen.cb = sizeof(screen); +// rjsa assertDos (VioGetMode (&screen, 0)); +// rjsa lastline = screen.row-1; +consoleGetScreenInformation( Scr, &ScrInfo ); +lastline = ScrInfo.NumberOfRows-2; +// lastline = 22; +cls(); +helpCmd(); +/* + * main loop. Position at bottom of screen, and accept one command at at time + * from there. Interpret commands until done. + */ +do { + outtextat ("\r\n", lastline, 0, BRIGHTWHITE); + outtextat (spaces, lastline, 0, BRIGHTWHITE); + outtextat ("HTEST Command> ", lastline, 0, BRIGHTWHITE); + // rjsa VioSetCurPos (lastline, 15, 0); + consoleSetCursor(Scr, lastline, 16); + gets (buf); + cls (); + outtextat ("\r\n", lastline, 0, BRIGHTWHITE); + outtextat ("Processing: ", lastline, 0, LIGHTRED); + outtextat (buf, lastline, 12, BRIGHTWHITE); + outtextat ("\r\n", lastline, 0, BRIGHTWHITE); +/* + * ctrl on/off + */ + if (!strcmp (buf,"ctrl on")) { + fEnable = TRUE; + cls (); + outtextat ("Control Lines Displayed", 0, 0, BRIGHTWHITE); + } + else if (!strcmp (buf,"ctrl off")) { + fEnable = FALSE; + cls (); + outtextat ("Control Lines NOT Displayed", 0, 0, BRIGHTWHITE); + } +/* + * disp + */ + else if (!strcmp (buf,"disp")) + dispCmd (1,lastline); +/* + * down + */ + else if (!strcmp (buf,"down")) + dispCmd (lLast+1,lLast + lastline); +/* + * dump + */ + else if (!strncmp (buf, "dump ", 5)) + dumpfileCmd(buf+5); + else if (!strcmp (buf,"dump")) + dumpCmd (); +/* + * file newhelpfilename + */ + else if (!strncmp (buf,"file ", 5)) + fileCmd (buf+5); +/* + * help + */ + else if (!strcmp (buf,"help")) + helpCmd (); +/* + * look helpstring + */ + else if (!strncmp (buf,"look ", 5)) + lookupCmd (buf+5,0); +/* + * look + */ + else if (!strcmp (buf,"look")) + lookupCmd (NULL,0); +/* + * next + */ + else if (!strcmp (buf,"next")) + lookupCmd (NULL,1); +/* + * prev + */ + else if (!strcmp (buf,"prev")) + lookupCmd (NULL,-1); +/* + * up + */ + else if (!strcmp (buf,"up")) { + lLast = max (1, lLast-1); + dispCmd (lLast,lLast + lastline); + } +/* + * xref xrefnumber + */ + else if (!strncmp (buf,"xref", 4)) + xrefCmd (buf+4); +/* + * + page down + */ + else if (!strcmp (buf,"+")) { + lLast += lastline; + dispCmd (lLast,lLast + lastline); + } +/* + * - page up + */ + else if (!strcmp (buf,"-")) { + lLast = max (1, lLast - (lastline)); + dispCmd (lLast,lLast + lastline); + } + } +/* + * exit + */ +while (strncmp(buf,"exit",4)); +outtextat (spaces, lastline, 0, BRIGHTWHITE); +HelpClose (ncNull); + +/* end main */} + + + + + + +/*** dispCmd - display topic text +* +* displays the topic text on the screen. +* +* Input: +* lStart - starting line +* lEnd - ending line +* +* Output: +* Returns nothing +* +*************************************************************************/ +void pascal near dispCmd ( +int lStart, +int lEnd +) { +char buf[BUFSIZ*2]; +lineattr rgAttr[BUFSIZ]; +int cb; +int lineCur = 0; + + HelpCtl (pTopicCur, fEnable); + cls (); + lLast = lStart; + while (lStart<lEnd) { + if (!isatty(_fileno(stdout)) || fBoth) { + cb = (int)HelpGetLine (lStart, BUFSIZ*2, (char far *)buf, pTopicCur); + if (cb == 0) + lStart = lEnd; + buf[cb-1] = '\r'; + buf[cb] = '\n'; + buf[cb+1] = 0; + outtext (buf, BLACK); + buf[cb-1] = 0; + } + if (isatty(_fileno(stdout)) || fBoth) { + cb = HelpGetLine(lStart, BUFSIZ*2, (char far*)buf, pTopicCur ); + HelpGetLineAttr( lStart, BUFSIZ*sizeof(lineattr), rgAttr, pTopicCur ); + WrtLineAttr(buf, rgAttr, cb, lineCur++, 0 ); + } + + //if (isatty(fileno(stdout)) || fBoth) { + // cb = HelpGetCells (lStart, BUFSIZ*2, buf, pTopicCur, mpAttr); + // if (cb == -1) + // lStart = lEnd; + // else + // ASSERTDOS (WrtCellStr (buf, cb, lineCur++, 0)); + // } + + lStart++; + } + +/* end dispCmd */} + +static char *szHS[] = { "HS_INDEX", + "HS_CONTEXTSTRINGS", + "HS_CONTEXTMAP", + "HS_KEYPHRASE", + "HS_HUFFTREE", + "HS_TOPICS", + "unused (6)", + "unused (7)", + "HS_NEXT" }; + +/*** dumpCmd - process dump command +* +* Dumps the contents of the current help file +* +* NOTE: +* This function uses all sorts of "internal" knowledge and calls to +* do it's job. +* +* Input: +* +* Output: +* Returns nothing +* +*************************************************************************/ +void pascal near dumpCmd () { +char buf[BUFSIZ]; +int cbKeyPhrase; +fdb fdbLocal; /* local copy of fdb to use */ +uchar far *fpT; +ushort far *fpW; +int i; +nc ncNext; /* nc init of appended file */ +//uchar uc; + +cls(); +ncNext = ncCur; +while (ncNext.cn) { + if (LoadFdb (ncNext.mh, &fdbLocal)) { + sprintf (buf,"fhHelp %u\r\n", fdbLocal.fhHelp); + outtext (buf, BRIGHTWHITE); + sprintf (buf,"ncInit %08lx\r\n", fdbLocal.ncInit); + outtext (buf, BRIGHTWHITE); + for (i=0; i<HS_count; i++) { + sprintf (buf,"rgmhSections[%18s] %04x\r\n", szHS[i], fdbLocal.rgmhSections[i]); + outtext (buf, BRIGHTWHITE); + } + sprintf (buf,"ftype %02x\r\n", fdbLocal.ftype ); + outtext (buf, BRIGHTWHITE); + sprintf (buf,"fname %14s\r\n", fdbLocal.fname ); + outtext (buf, BRIGHTWHITE); + sprintf (buf,"foff %08lx\r\n", fdbLocal.foff ); + outtext (buf, BRIGHTWHITE); + sprintf (buf,"ncLink %08lx\r\n", fdbLocal.ncLink); + outtext (buf, BRIGHTWHITE); + + sprintf (buf,"hdr.wMagic %04x\r\n", fdbLocal.hdr.wMagic ); + outtext (buf, BRIGHTWHITE); + sprintf (buf,"hdr.wVersion %04x\r\n", fdbLocal.hdr.wVersion ); + outtext (buf, BRIGHTWHITE); + sprintf (buf,"hdr.wFlags %04x\r\n", fdbLocal.hdr.wFlags ); + outtext (buf, BRIGHTWHITE); + sprintf (buf,"hdr.appChar %04x\r\n", fdbLocal.hdr.appChar ); + outtext (buf, BRIGHTWHITE); + sprintf (buf,"hdr.cTopics %04x\r\n", fdbLocal.hdr.cTopics ); + outtext (buf, BRIGHTWHITE); + sprintf (buf,"hdr.cContexts %04x\r\n", fdbLocal.hdr.cContexts ); + outtext (buf, BRIGHTWHITE); + sprintf (buf,"hdr.cbWidth %04x\r\n", fdbLocal.hdr.cbWidth ); + outtext (buf, BRIGHTWHITE); + sprintf (buf,"hdr.cPreDef %04x\r\n", fdbLocal.hdr.cPreDef ); + outtext (buf, BRIGHTWHITE); + sprintf (buf,"hdr.fname %s\r\n", fdbLocal.hdr.fname ); + outtext (buf, BRIGHTWHITE); + sprintf (buf,"hdr.reserved[0] %04x\r\n", fdbLocal.hdr.reserved[0]); + outtext (buf, BRIGHTWHITE); + sprintf (buf,"hdr.reserved[1] %04x\r\n", fdbLocal.hdr.reserved[1]); + + for (i=0; i<HS_count; i++) { + sprintf (buf,"hdr.tbPos[%18s] %08lx\r\n", szHS[i], fdbLocal.hdr.tbPos[i]); + outtext (buf, BRIGHTWHITE); + } + outtext ("----- ----- -----\r\n", LIGHTGREEN); +/* + * Topic Index + * This is just a table of (long) offsets within the current file. We just + * report the values, and also calculate the size of each entry by looking + * at the position of the entry following. + */ + fpT = HelpLock (LoadPortion( HS_INDEX ,ncNext.mh)); + if (fpT) { + outtext ("Topic Index:\r\n", LIGHTRED); + for (i = 0; i < (int)fdbLocal.hdr.cTopics; i++) { + sprintf (buf, " %2d: %08lx, %ld bytes\r\n", i, ((long far *)fpT)[i], ((long far *)fpT)[i+1]-((long far *)fpT)[i]); + outtext (buf, BRIGHTWHITE); + } + outtext ("----- ----- -----\r\n", LIGHTGREEN); + } +/* + * context strings + * This is just a table of null terminated strings, in no particular order. + * We just list them out sequentially. + */ + fpT = HelpLock (LoadPortion( HS_CONTEXTSTRINGS ,ncNext.mh)); + if (fpT) { + outtext ("Context strings:\r\n", LIGHTRED); + for (i=0; i<(int)fdbLocal.hdr.cContexts; i++) { + + sprintf (buf, " %03d: ", i); + // rjsa hfstrcpy ((char far *)buf+7, fpT); + strcpy ((char far *)buf+7, fpT); + strcat (buf, "\r\n"); + outtext (buf, BRIGHTWHITE); + + // rjsa fpT += hfstrlen(fpT) +1; + fpT += strlen(fpT) +1; + } + outtext ("----- ----- -----\r\n", LIGHTGREEN); + } +/* + * Context Map + * This is the mapping of context strings to actual topic numbers. The context + * strings map one to one to the entries in this table, which in turn contains + * indexes into the topic index at the head of the file. We just dump this + * table sequentially. + */ + fpT = HelpLock (LoadPortion( HS_CONTEXTMAP ,ncNext.mh)); + if (fpT) { + outtext ("Context map:\r\n", LIGHTRED); + outtext (" Ctx Topic\r\n",BRIGHTWHITE); + outtext (" --- -----\r\n",BRIGHTWHITE); + for (i=0; i<(int)fdbLocal.hdr.cContexts; i++) { + sprintf (buf, " %03d: %04d\r\n", i, ((ushort far *)fpT)[i]); + outtext (buf, BRIGHTWHITE); + } + outtext ("----- ----- -----\r\n", LIGHTGREEN); + } +/* + * keyword table + * This is a table of byte-prefixed strings, which we output in order, + * synthesizing the tokens that they would be in the text as well. + */ + fpT = HelpLock (LoadPortion( HS_KEYPHRASE, ncNext.mh)); + if (fpT) { + cbKeyPhrase = 0; + for (i=HS_HUFFTREE; i<HS_count; i++) + if (fdbLocal.hdr.tbPos[i]) { + cbKeyPhrase = (ushort)(fdbLocal.hdr.tbPos[i] - fdbLocal.hdr.tbPos[HS_KEYPHRASE]); + break; + } + + outtext ("Keyphrase Table:\r\n", LIGHTRED); + outtext (" Token Phrase\r\n",BRIGHTWHITE); + outtext (" ----- ------\r\n",BRIGHTWHITE); + i = 0; + fpT += 1024 * sizeof (PVOID); + fpW = (ushort far *)(fpT + cbKeyPhrase); + while (fpT < (uchar far *)fpW) { + sprintf (buf, " %04x: ", i+(C_KEYPHRASE0 << 8)); + fpT = phrasecopy (buf+8, fpT); + strcat (buf, "\r\n"); + outtext (buf, BRIGHTWHITE); + i++; + } + outtext ("----- ----- -----\r\n", LIGHTGREEN); + } +/* + * huffman table + * here we try to get fancy and output some information about the table format + */ + fpW = HelpLock (LoadPortion( HS_HUFFTREE, ncNext.mh)); + if (fpW) { + outtext ("Huffman Tree:\r\n", LIGHTRED); + i = 0; + while (*fpW) { + sprintf (buf, " 0x%03x: 0x%04x, %s\r\n", i++, *fpW, *fpW & 0x8000 ? "Leaf" : "Node"); + fpW++; + outtext (buf, BRIGHTWHITE); + } + } + outtext ("===== ===== =====\r\n", YELLOW); + ncNext = fdbLocal.ncLink; + } + else { + sprintf(buf, "Cannot load fdb for %08lx\r\n",ncCur); + outtext (buf, LIGHTRED); + return; + } + } +/* end dumpCmd */} + +/*** dumpfileCmd - process dump command +* +* Dumps the contents of the current help file +* +* NOTE: +* This function uses all sorts of "internal" knowledge and calls to +* do it's job. +* +* Input: +* +* Output: +* Returns nothing +* +*************************************************************************/ +void pascal near dumpfileCmd (char *fname) { +char buf[BUFSIZ]; +int cbKeyPhrase; +fdb fdbLocal; /* local copy of fdb to use */ +uchar far *fpT; +ushort far *fpW; +int i; +nc ncNext; /* nc init of appended file */ +//uchar uc; + +FILE* fh = fopen(fname, "w"); +if (!fh) { + return; +} +ncNext = ncCur; +while (ncNext.cn) { + if (LoadFdb (ncNext.mh, &fdbLocal)) { + sprintf (buf,"fhHelp %u\r\n", fdbLocal.fhHelp); + fprintf( fh, buf ); + sprintf (buf,"ncInit %08lx\r\n", fdbLocal.ncInit); + fprintf( fh, buf ); + for (i=0; i<HS_count; i++) { + sprintf (buf,"rgmhSections[%18s] %04x\r\n", szHS[i], fdbLocal.rgmhSections[i]); + fprintf( fh, buf ); + } + sprintf (buf,"ftype %02x\r\n", fdbLocal.ftype ); + fprintf( fh, buf ); + sprintf (buf,"fname %14s\r\n", fdbLocal.fname ); + fprintf( fh, buf ); + fprintf( fh, buf ); + sprintf (buf,"foff %08lx\r\n", fdbLocal.foff ); + fprintf( fh, buf ); + sprintf (buf,"ncLink %08lx\r\n", fdbLocal.ncLink); + fprintf( fh, buf ); + + sprintf (buf,"hdr.wMagic %04x\r\n", fdbLocal.hdr.wMagic ); + fprintf( fh, buf ); + sprintf (buf,"hdr.wVersion %04x\r\n", fdbLocal.hdr.wVersion ); + fprintf( fh, buf ); + sprintf (buf,"hdr.wFlags %04x\r\n", fdbLocal.hdr.wFlags ); + fprintf( fh, buf ); + sprintf (buf,"hdr.appChar %04x\r\n", fdbLocal.hdr.appChar ); + fprintf( fh, buf ); + sprintf (buf,"hdr.cTopics %04x\r\n", fdbLocal.hdr.cTopics ); + fprintf( fh, buf ); + sprintf (buf,"hdr.cContexts %04x\r\n", fdbLocal.hdr.cContexts ); + fprintf( fh, buf ); + sprintf (buf,"hdr.cbWidth %04x\r\n", fdbLocal.hdr.cbWidth ); + fprintf( fh, buf ); + sprintf (buf,"hdr.cPreDef %04x\r\n", fdbLocal.hdr.cPreDef ); + fprintf( fh, buf ); + sprintf (buf,"hdr.fname %s\r\n", fdbLocal.hdr.fname ); + fprintf( fh, buf ); + sprintf (buf,"hdr.reserved[0] %04x\r\n", fdbLocal.hdr.reserved[0]); + fprintf( fh, buf ); + sprintf (buf,"hdr.reserved[1] %04x\r\n", fdbLocal.hdr.reserved[1]); + + for (i=0; i<HS_count; i++) { + sprintf (buf,"hdr.tbPos[%18s] %08lx\r\n", szHS[i], fdbLocal.hdr.tbPos[i]); + fprintf( fh, buf ); + } + fprintf( fh,"----- ----- -----\r\n" ); +/* + * Topic Index + * This is just a table of (long) offsets within the current file. We just + * report the values, and also calculate the size of each entry by looking + * at the position of the entry following. + */ + fpT = HelpLock (LoadPortion( HS_INDEX ,ncNext.mh)); + if (fpT) { + fprintf( fh,"Topic Index:\r\n" ); + for (i = 0; i < (int)fdbLocal.hdr.cTopics; i++) { + sprintf (buf, " %2d: %08lx, %ld bytes\r\n", i, ((long far *)fpT)[i], ((long far *)fpT)[i+1]-((long far *)fpT)[i]); + fprintf( fh, buf ); + } + fprintf( fh,"----- ----- -----\r\n" ); + } +/* + * context strings + * This is just a table of null terminated strings, in no particular order. + * We just list them out sequentially. + */ + fpT = HelpLock (LoadPortion( HS_CONTEXTSTRINGS ,ncNext.mh)); + if (fpT) { + fprintf( fh, "Context strings:\r\n" ); + for (i=0; i<(int)fdbLocal.hdr.cContexts; i++) { + + sprintf (buf, " %03d: ", i); + // rjsa hfstrcpy ((char far *)buf+7, fpT); + strcpy ((char far *)buf+7, fpT); + strcat (buf, "\r\n"); + fprintf( fh, buf ); + + // rjsa fpT += hfstrlen(fpT) +1; + fpT += strlen(fpT) +1; + } + fprintf( fh,"----- ----- -----\r\n" ); + } +/* + * Context Map + * This is the mapping of context strings to actual topic numbers. The context + * strings map one to one to the entries in this table, which in turn contains + * indexes into the topic index at the head of the file. We just dump this + * table sequentially. + */ + fpT = HelpLock (LoadPortion( HS_CONTEXTMAP ,ncNext.mh)); + if (fpT) { + fprintf( fh, "Context map:\r\n" ); + fprintf( fh, " Ctx Topic\r\n" ); + fprintf( fh, " --- -----\r\n" ); + for (i=0; i<(int)fdbLocal.hdr.cContexts; i++) { + sprintf (buf, " %03d: %04d\r\n", i, ((ushort far *)fpT)[i]); + fprintf( fh, buf ); + } + fprintf( fh, "----- ----- -----\r\n" ); + } +/* + * keyword table + * This is a table of byte-prefixed strings, which we output in order, + * synthesizing the tokens that they would be in the text as well. + */ + fpT = HelpLock (LoadPortion( HS_KEYPHRASE, ncNext.mh)); + if (fpT) { + cbKeyPhrase = 0; + for (i=HS_HUFFTREE; i<HS_count; i++) + if (fdbLocal.hdr.tbPos[i]) { + cbKeyPhrase = (ushort)(fdbLocal.hdr.tbPos[i] - fdbLocal.hdr.tbPos[HS_KEYPHRASE]); + break; + } + + fprintf( fh, "Keyphrase Table:\r\n" ); + fprintf( fh, " Token Phrase\r\n" ); + fprintf( fh, " ----- ------\r\n" ); + i = 0; + fpT += 1024 * sizeof (PVOID); + fpW = (ushort far *)(fpT + cbKeyPhrase); + while (fpT < (uchar far *)fpW) { + sprintf (buf, " %04x: ", i+(C_KEYPHRASE0 << 8)); + fpT = phrasecopy (buf+8, fpT); + strcat (buf, "\r\n"); + fprintf( fh, buf ); + i++; + } + fprintf( fh,"----- ----- -----\r\n" ); + } +/* + * huffman table + * here we try to get fancy and output some information about the table format + */ + fpW = HelpLock (LoadPortion( HS_HUFFTREE, ncNext.mh)); + if (fpW) { + fprintf( fh, "Huffman Tree:\r\n" ); + i = 0; + while (*fpW) { + sprintf (buf, " 0x%03x: 0x%04x, %s\r\n", i++, *fpW, *fpW & 0x8000 ? "Leaf" : "Node"); + fpW++; + fprintf( fh, buf ); + } + } + fprintf( fh, "===== ===== =====\r\n" ); + ncNext = fdbLocal.ncLink; + } + else { + sprintf(buf, "Cannot load fdb for %08lx\r\n",ncCur); + fprintf( fh, buf ); + fclose(fh); + return; + } + } +/* end dumpCmd */} + + +/*** fileCmd - process file command +* +* Opens the help file specified. +* +* Input: +* pName = name of help file to be added +* +* Output: +* Returns nothing +* +*************************************************************************/ +void pascal near fileCmd ( +char *pName +) { +char buf[BUFSIZ]; +int i; +nc ncInit; + +sprintf (buf,"Opening %s...\r\n",pName); +outtext (buf, BRIGHTWHITE); +/* + * search file table for available slot + */ +for (i=0; i<MAXFILES; i++) + if (!ncTbl[i].cn) + break; +if (i >= MAXFILES) { + sprintf(buf, "Cannot open %s: htest's open file limit exceeded\r\n",pName); + outtext (buf, LIGHTRED); + return; + } + +iNcCur = i; + +ncInit = HelpOpen(pName); + +for (i=0; i<MAXFILES; i++) + if ((ncTbl[i].mh == ncInit.mh) && (ncTbl[i].cn == ncInit.cn)) { + iNcCur = i; + sprintf (buf, "File #%d; Initial Context: 0x%04lx (file already open)\r\n",iNcCur,ncInit); + outtext (buf, BRIGHTWHITE); + return; + } + +if (ISERROR(ncInit)) { + sprintf(buf, "Cannot open %s: 0x%04lx, %s\r\n",pName,ncInit, errTbl[ncInit.cn]); + outtext (buf, LIGHTRED); + return; + } +/* + * output initial context, and the available memory + */ +ncCur = ncTbl[iNcCur] = ncInit; +sprintf (buf, "File #%d; Initial Context: 0x%04lx\r\n",iNcCur,ncInit.cn); +outtext (buf, BRIGHTWHITE); + +lookupCmd(NULL, 0); +/* end fileCmd */} + +/*** helpCmd - display help on commands +* +* Input: +* none +* +* Output: +* Returns nothing +* +*************************************************************************/ +void pascal near helpCmd () { + +outtext ("HTEST - Help Engine Test Harness\r\n", BRIGHTWHITE); +outtext ("\r\n", BRIGHTWHITE); +outtext ("Comands:\r\n", BRIGHTWHITE); +outtext ("\r\n", BRIGHTWHITE); +outtext ("ctrl on/off - turn on/off display of control lines\r\n", BRIGHTWHITE); +outtext ("disp - display first screen of most recently read topic\r\n", BRIGHTWHITE); +outtext ("down - move ahead one line in topic and display\r\n", BRIGHTWHITE); +outtext ("dump - dump file info (very large)\r\n", BRIGHTWHITE); +outtext ("exit - exit htest\r\n", BRIGHTWHITE); +outtext ("file x - open new help file, or make help file current\r\n", BRIGHTWHITE); +outtext ("help - display this screen\r\n", BRIGHTWHITE); +outtext ("look x - loop up context string & fetch topic\r\n", BRIGHTWHITE); +outtext ("next - fetch next physical topic\r\n", BRIGHTWHITE); +outtext ("prev - fetch previous physical topic\r\n", BRIGHTWHITE); +outtext ("up - move back one line in topic and display\r\n", BRIGHTWHITE); +outtext ("xref x - display all xrefs in current topic, or look up #x\r\n", BRIGHTWHITE); +outtext ("+ - move & redisplay one page down\r\n", BRIGHTWHITE); +outtext ("- - move & redisplay one page up\r\n", BRIGHTWHITE); +/* end helpCmd */} + +/*** lookupCmd - process file command +* +* Looks up the specified string in the current helpfile, or the next help +* topic. +* +* Input: +* pString = help string to look up +* dir = direction: 0= look up string, 1=get next, -1= get previous +* +* Output: +* Returns nothing +* +*************************************************************************/ +void pascal near lookupCmd ( +char *pString, +int dir +) { +char buf[BUFSIZ]; +unsigned cbCompressed; +unsigned cbUncompressed; +char far *pCompressed; +/* + * Start with the simple look up of the conetxt to get an nc. Report on + * failure. + */ +if (pString) + ncCur = HelpNc(pString,ncTbl[iNcCur]); +else if (dir>0) { + if (!ncCur.cn) + ncCur = ncTbl[iNcCur]; + else + ncCur = HelpNcNext(ncCur); + } +else if (dir<0) { + if (!ncCur.cn) + ncCur = ncTbl[iNcCur]; + else if (ncCur.cn != ncTbl[iNcCur].cn) + ncCur = HelpNcPrev(ncCur); + } +else + ncCur = ncTbl[iNcCur]; + +if (!ncCur.cn) { + outtext ("Lookup Failed: HelpNc/HelpNcNext/HelpNcPrev returned 0", LIGHTRED); + return; + } +/* + * It exists. Indicate what file we're looking in, what we found, and the + * nc that was returned + */ +sprintf (buf, "File #%d; Looking up:%s\r\n",iNcCur, + pString ? (*pString ? pString : "local context") + : (dir ? ((dir>0) ? "**NEXT**" : "**PREV**") + : "current")); +outtext (buf, BRIGHTWHITE); +sprintf (buf, "nc returned = %08lx\r\n",ncCur.cn); +outtext (buf, BRIGHTWHITE); +/* + * Free up memory for previously current topic + */ +if (mhTopicCur) + free(mhTopicCur); +/* + * Get the compressed memory size required, and report it. Alloc it. + */ +cbCompressed = HelpNcCb(ncCur); +sprintf (buf, "size of compressed topic = %d\r\n",cbCompressed); +outtext (buf, BRIGHTWHITE); +pCompressed = malloc(cbCompressed); +/* + * read in the compressed topic, getting the size required for the + * uncompressed results. Report that, and allocate it. + */ +cbUncompressed = HelpLook(ncCur,pCompressed); +sprintf (buf, "size of UNcompressed topic = %d\r\n",cbUncompressed); +outtext (buf, BRIGHTWHITE); +mhTopicCur = malloc(cbUncompressed); +//pTopicCur = MAKEP (mhTopicCur, 0); +pTopicCur = mhTopicCur; +/* + * Decompress the topic. + */ +HelpDecomp(pCompressed,pTopicCur,ncCur); +outtext ("Decompressed\r\n", BRIGHTWHITE); +/* + * exercise SzContext and cLines routines, reporting results + */ +HelpSzContext(buf,ncCur); +strcat (buf, "\r\n"); +outtext (buf, BRIGHTWHITE); +sprintf(buf,"%d lines\r\n", HelpcLines(pTopicCur)); +outtext (buf, BRIGHTWHITE); +/* + * Report the amount of available memory at this point, and then free up the + * compressed text + */ +free(pCompressed); + +/* end lookupCmd */} + +/*** xrefCmd - process xref command +* +* Display or execute cross reference +* +* Input: +* pText = pointer to ascii text which, if a non-zero number, indicates the +* xref to execute. If zero, display all +* +* Output: +* Returns nothing +* +*************************************************************************/ +void pascal near xrefCmd ( +char *pText +) { +hotspot hsCur; /* hot spot definition */ +int i; /* working counter */ +int iReq; /* request value */ +char *pT; /* temp pointer */ + +iReq = atoi (pText); +hsCur.line = hsCur.col = 1; +i = 1; +while (HelpHlNext(0,pTopicCur,&hsCur)) { +/* + * if not explicit request, then list as much as we can + */ + if (!iReq) { + sprintf (buf, "Xref [%d] @ line: %05d columns %02d to %02d = " + ,i + ,hsCur.line + ,hsCur.col + ,hsCur.ecol); + pT = buf + strlen(buf); + if (*hsCur.pXref) + while (*pT++ = *hsCur.pXref++); + else + sprintf(pT, "Local >> topic # 0x%04x ",*(ushort far *)(hsCur.pXref+1)); + strcat (buf, "\r\n"); + outtext (buf, LIGHTGREEN); + } + else if (i == iReq) { + pT = buf; + if (*hsCur.pXref) + while (*pT++ = *hsCur.pXref++); + else { + *pT++ = *hsCur.pXref++; + *pT++ = *hsCur.pXref++; + *pT++ = *hsCur.pXref++; + } + lookupCmd (buf, 0); + return; + } + ++i; + hsCur.col = hsCur.ecol+(ushort)1; + } +/* end xrefCmd */} + +/*** outtext - output text with specific colors +* +* sets the forground color and location as appropriate, and displays the +* desired text. Checks for redirection, and if redirected, just outputs the +* text to stdout. +* +* Input: +* ptext = pointer to text to output +* color = color to use +* +* Output: +* Returns +* +*************************************************************************/ +void pascal near outtext ( +char *pText, +BYTE color +) { +outtextat (pText, curline++, 0, color); +if (curline >= lastline) { + if (isatty(_fileno(stdout)) + && !fBoth) { + + outtextat ("More...", lastline, 0, BRIGHTWHITE); + // rjsa VioSetCurPos (lastline, 8, 0); +#if defined (OS2) + consoleSetCursor(lastline,8); +#else + consoleSetCursor(Scr,lastline,8); +#endif + gets (buf); + } + curline = 0; + cls (); + } + +/* end outtext */} + +/*** outtextat - put text with specific colors at a specific place +* +* sets the forground color and location as appropriate, and displays the +* desired text. Checks for redirection, and if redirected, just outputs the +* text to stdout. +* +* Input: +* ptext = pointer to text to output +* col = column to put into +* color = color to use +* +* Output: +* Returns +* +*************************************************************************/ +void pascal near outtextat ( +char *pText, +int line, +int col, +BYTE color +) { +char *pEol; /* ptr to nl, if present */ +int len; + +color |= (ColorByte & 0xf0); +if ((isatty(_fileno(stdout)) || fBoth) && (line <= lastline)) { + len = strlen(pText); + if (pEol = strchr (pText, '\r')) + *pEol = 0; + // rjsa VioWrtCharStrAtt (pText, strlen(pText), line, col, (PBYTE)&color, 0); + WrtCharStrAtt (pText, strlen(pText), line, col, (PBYTE)&color); + + if (pEol) + *pEol = '\r'; + } +if (!isatty(_fileno(stdout)) || fBoth) + printf ("%s",pText); +/* end outtextat */} + +/*** assertDos - asserts that a dos call returned a zero +* +* Just prints the number passed it if non-zero, and quits +* +* Input: +* Return code from a dos call +* +* Output: +* Returns only if zero passed in +* +*************************************************************************/ +void pascal near assertDos ( +USHORT rv, +CHAR * pFile, +USHORT LineNo +) { +if (rv) { + printf ("assertDos: %u (0x%04x) File %s, line %u\n", rv, rv, pFile, LineNo); + exit (1); + } +/* end assertDos*/} + +/*** cls - clear screen +* +* Clear screen to current backround color +* +* Input: +* none +* +* Output: +* Returns screen clear +* +*************************************************************************/ +void pascal near cls () { +curline = 0; +// rjsa VioScrollUp (0, 0, 0xffff, 0xffff, 0xffff, cell, 0); +consoleSetAttribute( Scr, 0x1f ); +consoleClearScreen(Scr, TRUE); +/* end cls */} + +/*** phrasecopy - copy a keyword phrase from the table +* +* Copies a byte-length-prefixed string from far memory to a null terminated +* string in near memory. +* +* Input: +* dst - near pointer to destination +* src - far pointer to source +* +* Output: +* Returns far pointer to byte following source string +* +*************************************************************************/ +uchar far * pascal near phrasecopy ( +uchar *dst, +uchar far *src +) { +register int i; + +if (i = (int)*src++) + while (i--) + *dst++ = *src++; +*dst = 0; +return src; +/* end phrasecopy */} + + + +void far * pascal HelpLock(mhCur) +mh mhCur; +{ +//return MAKEP(mhCur,0); +return mhCur; +} + +void pascal HelpUnlock(mhCur) +mh mhCur; +{ + mhCur; +} + +void pascal HelpDealloc(mhCur) +mh mhCur; +{ +if (mhCur) + free(mhCur); +} + + + + +USHORT WrtCellStr (PBYTE buf, int cb, int row, int col) { + int cl = col; + //consoleSetCursor(Scr,row,col); + while (cb) { + UCHAR c; + UCHAR attr; + + c = *buf++; + attr = *buf++; + + //consoleSetAttribute(Scr,attr); + //consoleWrite(Scr,&c,1); + + consoleWriteLine( Scr, &c, 1, row, cl, attr, FALSE ); + cl++; + + cb -= 2; + } + consoleShowScreen(Scr); + return 0; +} + + +USHORT WrtLineAttr ( PBYTE pText, + lineattr *rgAttr, + int cb, + int row, + int col + ) { + + lineattr *Attr = rgAttr; + char *p = pText; + int l = cb; + int len; + + consoleSetCursor(Scr, row, col ); + + while (cb > 0) { + + if ( Attr->cb == 0xFFFF || Attr->attr == 0xFFFF ) { + len = cb; + } else { + len = Attr->cb; + } + + outtextat (p, row, col, mpAttr[Attr->attr] ); + col += len; + p += len; + cb -= len; + Attr++; + + } + return (USHORT)l; +} + + + +USHORT WrtCharStrAtt (PBYTE pText, int cb, int row, int col, PBYTE pcolor) { + //consoleSetCursor(Scr,row,col); + //consoleSetAttribute(Scr,*pcolor); + //consoleWrite( Scr,pText, cb ); + consoleWriteLine( Scr, pText, cb, row, col, *pcolor, FALSE ); + consoleShowScreen(Scr); + return 0; +} + +/********************************************************************** + * + * LoadTheDll + * + * Loads the help engine dll (mshelp.dll) and initializes the + * pointers to the dll's entry points. + * + **********************************************************************/ + +void +LoadTheDll ( + void) { + + +#if defined (OS2) + USHORT rc; + CHAR szFullName[256]; + CHAR szErrorName[256]; + USHORT i; + + + strcpy(szFullName, HELPDLL_BASE); + strcpy(szErrorName, HELPDLL_NAME); + + ASSERTDOS(rc = DosLoadModule(szErrorName, + 256, + szFullName, + &hModule)); + + + for (i=0; i<LASTENTRYPOINT; i++) { + ASSERTDOS (rc = DosQueryProcAddr(hModule, + 0L, + szEntryName[i], + (PFN*)&(pEntry[i]))); + } +#else + +#if defined (HELP_HACK) + + //pEntry[0] = (PHF)HelpcLines; + //pEntry[1] = (PHF)HelpClose; + //pEntry[2] = (PHF)HelpCtl; + //pEntry[3] = (PHF)HelpDecomp; + //pEntry[4] = (PHF)HelpGetCells; + //pEntry[5] = (PHF)HelpGetInfo; + //pEntry[6] = (PHF)HelpGetLine; + //pEntry[7] = (PHF)HelpGetLineAttr; + //pEntry[8] = (PHF)HelpHlNext; + //pEntry[9] = (PHF)HelpLook; + //pEntry[10] = (PHF)HelpNc; + //pEntry[11] = (PHF)HelpNcBack; + //pEntry[12] = (PHF)HelpNcCb; + //pEntry[13] = (PHF)HelpNcCmp; + //pEntry[14] = (PHF)HelpNcNext; + //pEntry[15] = (PHF)HelpNcPrev; + //pEntry[16] = (PHF)HelpNcRecord; + //pEntry[17] = (PHF)HelpNcUniq; + //pEntry[18] = (PHF)HelpOpen; + //pEntry[19] = (PHF)HelpShrink; + //pEntry[20] = (PHF)HelpSzContext; + //pEntry[21] = (PHF)HelpXRef; + //pEntry[22] = (PHF)LoadFdb; + //pEntry[23] = (PHF)LoadPortion; + + + +#else + USHORT i; + hModule = LoadLibrary(HELPDLL_NAME); + for (i=0; i<LASTENTRYPOINT; i++) { + pEntry[i] = (PHF)GetProcAddress(hModule, (LPSTR)szEntryName[i]); + } +#endif + +#endif +} diff --git a/private/utils/mep/help/htest/makefile b/private/utils/mep/help/htest/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/utils/mep/help/htest/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/utils/mep/help/htest/sources b/private/utils/mep/help/htest/sources new file mode 100644 index 000000000..dbc302203 --- /dev/null +++ b/private/utils/mep/help/htest/sources @@ -0,0 +1,18 @@ +MAJORCOMP=sdktools +MINORCOMP=htest + +TARGETNAME=cons +TARGETPATH=obj +TARGETTYPE=LIBRARY + +INCLUDES=.;..\inc;..\..\inc;\nt\private\sdktools\ztools\inc + + +SOURCES=cons.c + + +UMAPPL=htest + +C_DEFINES=-D_OS2_20_=0 -DNO_EXT_KEYS -Dpascal= -Dfar= -DNOLANMAN -DNT -DHELP_HACK +UMTYPE=console +UMLIBS= obj\*\cons.lib ..\mshelp\obj\*\mshelp.lib ..\enginlib\obj\*\engine.lib \nt\private\sdktools\ztools\src\obj\*\ztools.lib |