Terminal Emulation  
 

The Terminal Emulation library provides a virtual terminal interface for emulating an ANSI or DEC VT-220 compatible character-based terminal. It can be used in conjunction with the Telnet API or the Remote Command API to display the output of commands executed on a server. It can also be used independently of any other networking library, such as providing emulation services for a serial connection.

The first step your application must take is to initialize the library, and then create a virtual display which is attached to a window. The following functions are available for use by your application:

NvtInitialize
Initialize the library for the current process. This must be the first function call the application makes before calling the other emulator API functions.

NvtCreateDisplay
Creates a new virtual display and returns a handle which can be used to reference that display. When creating the display, you provide a handle to a window the display will draw on, a handle to a font that will be used to display text characters, the type of emulation and the size of the display.

NvtDestroyDisplay
Destroy the virtual display, releasing the memory allocated for the handle. After this function returns, the display handle is no longer valid.

NvtUninitialize
Release any resources that have been allocated for the current process. This is the last function call the application should make prior to terminating.

Display Management

The library provides functions to manage and update the virtual display, including a number of lower level functions that provide direct access to the display buffer. The most commonly used functions are:

NvtWriteDisplay
This is the most commonly used method of writing to the display. This function will automatically parse the data being written for escape sequences and update the display appropriately.

NvtUpdateDisplay
This function updates the window attached to the virtual display. This function should be called whenever a WM_PAINT message is received for that window, indicating that it needs to be redrawn. The window pain message can be handled in one of two general ways. The simplest is to just call NvtUpdateDisplay and return. The function will automatically acquire a device context for the window, redraw the portions of the window that need to be updated, and then release the device context. If you use this method, you should not call BeginPaint or EndPaint, since that is being done for you. If you wish to acquire the device context yourself by calling BeginPaint, then you must call NvtSetDisplayDC to attach the device context to the virtual display. When NvtUpdateDisplay is called, it will use that device context rather than acquiring one itself. After the display has been updated and you've called EndPaint, you should call NvtSetDisplayDC again, passing the function a null handle to detach the display from the device context that you've created.

NvtRefreshDisplay
Refresh the virtual display, updating the current cursor position and caret. The library will periodically refresh the display automatically based on its own internal state, but the application can call this if it wishes to force the display to refresh at that time.

NvtSetDisplayEmulation
This function can be used to change the emulation used by the library. Supported emulation types are standard ANSI, DEC VT-100 and VT-200. It is also possible to specify that no emulation should be used, in which case the application is responsible for handling any control or escape sequences in the data being written to the display.

NvtResetDisplay
This function can be used to change the handle of the window associated with the display, the font being used and the size of the display. Resetting the display causes the contents of the display to be cleared.

NvtSetDisplayFont
This function sets the font which is used by the library to draw text on the display window. If you wish to specify a font name and point size instead of creating a font handle, use the NvtSetDisplayFontName function instead.

NvtSetDisplayMode
The emulation library has a number of modes which determines how the data is displayed, as well as controlling aspects of the window itself. This function can be used to enable or disable those modes as necessary. For the list of available modes, please consult the Technical Reference.

NvtSetDisplayColor
This function controls what colors are used when drawing the background of the display window as well as the default color of the text. In ANSI and VT-220 emulation, the color of individual characters can be specified by using escape sequences. Those colors can be modified by changing the display color map.

NvtSetDisplayColorMap
This function changes the default colors which are used when escape sequences are used to change the foreground or background color of a character cell. In most cases the default color map will be appropriate, but applications can change the RGB values associated with an entry in the color map if needed. For example, the default value for the color gray is at position 8 in the color map index with an RGB value of 192,192,192. If you wanted to use a darker color, you could change the RGB value 128,128,128.

Cursor Control

There are a number of lower level functions which enable an application to have direct control over cursor positioning, clearing the display and so on. In most cases these functions are called automatically by the library as the result of processing the control and escape sequences found in the data being written to the display. However, an application can call these functions directly in order to manage the display itself. One important thing to keep in mind is that the X,Y positions used by these functions refer to the cursor position in the virtual display and correspond to columns and rows, not pixels.

There is also a slight difference in terminology that you should be aware of when reading the technical reference documentation. In Windows, the term "cursor" is typically used to refer to the mouse pointer, while "caret" is used to refer to the blinking marker that is displayed at the current position in the display. In the documentation for the emulator API, the term "cursor" is used in the same way that it is used for character based terminals, as the marker for the current position in the display. Therefore, in terms of the emulation API, you can think of the cursor and the caret as being synonymous.

NvtGetCursorPos
Return the current position of the cursor in the virtual display.

NvtSetCursorPos
Change the current position of the cursor in the virtual display. This function will normalize the X,Y values to be bound by the size of the display. If a scrolling region has been set, the coordinates will be bound by that region. The upper left corner of the display is 0,0.

NvtSaveCursor
Saves the current position of the cursor. The cursor position can be restored by calling the NvtRestoreCursor function.

NvtClearDisplay
Clear the contents of the display. You can clear from the start of the display to the current cursor position, from the current position to the end of the display or the entire display.

NvtDeleteChar
This function deletes a character from the current cursor position, shifting the remaining characters on the line to the left.

NvtDeleteLine
This function deletes the line at the current cursor position, shifting the remaining lines in the display up.

NvtEraseChar
This function erases a character at the current cursor position without affecting the characters that follow it on the line.

NvtEraseLine
This function erases the line at the current cursor position without affecting the lines that follow it.

NvtInsertChar
Insert a character at the current cursor position, shifting the following characters to the right.

NvtInsertLine
Insert a blank line at the current cursor position, shifting the following lines down.

NvtGetDisplayAttributes
Return the current attributes which have been enabled. Possible attributes are reverse, bold, dim, underline, hidden and protected. These correspond to the attributes that are commonly used with character based terminals.

NvtSetDisplayAttributes
Set the default attributes which are used when characters are written to the display. For example, setting the attribute NVT_ATTRIBUTE_REVERSE would cause all subsequent characters to be displayed with the foreground and background colors reversed. This would continue until the display attributes were set back to NVT_ATTRIBUTE_NORMAL.

Function Key Mapping

Another aspect of terminal emulation is how function keys and other special keys are handled by the application. The emulation library provides functions which will convert Windows virtual key codes into the escape sequences that are generated by character based terminals.

NvtTranslateMappedKey
This function translates a virtual key code into the escape sequence which should be sent to the server to emulate pressing that key. For example, if the user presses the F1 key on the keyboard, this will generate a WM_KEYDOWN event with VK_F1 as the virtual key code. This function will translate that key code into the three characters escape sequence ESC O P (the ASCII codes 27, 79, 80). That sequence of characters should be sent to the server, which will recognize it as the F1 function key being pressed. It is important to note that the different emulation types have different key mappings. Therefore, the server must be set to recognize the same type of terminal that you are emulating. If you have the emulation set as VT-220 but the server thinks that you are emulating a VT-100, it will not recognize some of the escape sequences correctly.

NvtGetMappedKey
Returns the escape sequence associated with a specific function key or special key. There are a total of 50 special keys recognized by the emulator. They consist of the F1 through F12 function keys, the function keys when they are in a shift state, the arrow keys and the keypad keys. Refer to the technical reference for the complete list.

NvtSetMappedKey
Change the escape sequence associated with a specific function key or special key. Changing this value will cause NvtTranslateMappedKey to return the new escape sequence when that key is pressed. This function can also be used to restore the default mapping for a key.

Windows Messages

Because the emulation library is closely tied to a display window, it is important to understand how Windows messages should be handled. If you are not familiar with how Windows processes messages at the API level, it is recommended that you review the technical reference material available from Microsoft on user interface programming. Another excellent resource is "Programming Windows" by Charles Petzold. If you are a C++ programmer, the equivalent MFC virtual functions will also be listed here.

WM_CREATE
This message is sent when the window is being created, but before it is displayed. This is typically a good point to call the NvtCreateDisplay function to create the virtual display and attach it to the window. You can also call NvtSetDisplayMode to set the various display modes, such as whether you want scrollbars to be shown, what kind of caret should be used and so on. In MFC, this can be done in the Create method for the window.

WM_DESTROY
This message is sent when a window is being destroyed. The application should call NvtDestroyDisplay at this point, since the window will no longer exist after the event handler returns.

WM_PAINT
This message is sent when the window needs to be redrawn. This is where the NvtUpdateDisplay function should be called. If you are using MFC, the code should be placed in the OnPaint method.

WM_HSCROLL and WM_VSCROLL
This message is sent when the user interacts with the window's scrollbars. An application should call the NvtSetDisplayScrollPos function to update the scroll position in the virtual display. In MFC, this code should be implemented in the OnHScroll and OnVScroll methods.

WM_KEYDOWN
This message is sent when the user presses a key. To determine if the key is mapped to a special escape sequence that should be sent to the server, call the NvtTranslateMappedKey function. In MFC, this code should be implemented in the OnKeyDown method.

WM_SETFOCUS and WM_KILLFOCUS
This message is sent when the window acquires or loses focus. You should call NvtSetDisplayFocus so that the library knows that the input focus has changed. In MFC, this code should be implemented in the OnSetFocus and OnKillFocus methods.

WM_SIZE
This message is sent when the window size changes. The application should call the NvtResizeDisplay function so that the virtual display is aware that the window size has changed. In MFC, this code should be implemented in the OnSize method.

When writing a terminal emulation program, it will also be necessary to handle other Windows messages such as WM_CHAR to process keys pressed by the user, which should be sent to the server. It is recommended that you refer to the Terminal sample program which demonstrates how these messages can be handled by an application. It also serves as a good example of how the Terminal Emulation API can be used in conjunction with the Telnet API.