Screen handling unit

The Video unit implements a screen access layer which is system independent. It can be used to write on the screen in a system-independent way, which should be optimal on all platforms for which the unit is implemented.

The working of the Video is simple: After calling , the array VideoBuf contains a representation of the video screen of size ScreenWidth*ScreenHeight, going from left to right and top to bottom when walking the array elements: VideoBuf[0] contains the character and color code of the top-left character on the screen. VideoBuf[ScreenWidth] contains the data for the character in the first column of the second row on the screen, and so on.

To write to the 'screen', the text to be written should be written to the VideoBuf array. Calling will then cp the text to the screen in the most optimal way. (an example can be found further on).

The color attribute is a combination of the foreground and background color, plus the blink bit. The bits describe the various color combinations:

bits 0-3
The foreground color. Can be set using all color constants.
bits 4-6
The background color. Can be set using a subset of the color constants.
bit 7
The blinking bit. If this bit is set, the character will appear blinking.

Each possible color has a constant associated with it, see the constants section for a list of constants.

The foreground and background color can be combined to a color attribute with the following code:

Attr:=ForeGroundColor + (BackGroundColor shl 4);

The color attribute can be logically or-ed with the blink attribute to produce a blinking character:

Atrr:=Attr or blink;

But not all drivers may support this.

The contents of the VideoBuf array may be modified: This is 'writing' to the screen. As soon as everything that needs to be written in the array is in the VideoBuf array, calling UpdateScreen will copy the contents of the array screen to the screen, in a manner that is as efficient as possible.

The updating of the screen can be prohibited to optimize performance; To this end, the function can be used: This will increment an internal counter. As long as the counter differs from zero, calling will not do anything. The counter can be lowered with . When it reaches zero, the next call to will actually update the screen. This is useful when having nested procedures that do a lot of screen writing.

The video unit also presents an interface for custom screen drivers, thus it is possible to override the default screen driver with a custom screen driver, see the call. The current video driver can be retrieved using the call.

The video unit should not be used together with the crt unit. Doing so will result in very strange behaviour, possibly program crashes.
Black color attribute Blue color attribute Green color attribute Cyan color attribute Red color attribute Magenta color attribute Brown color attribute Light gray color attribute Dark gray color attribute Light Blue color attribute Light green color attribute Light cyan color attribute Light red color attribute Light magenta color attribute Yellow color attribute White color attribute Blink attribute Video driver supports underline attribute Video driver supports blink attribute Video driver supports color Video driver supports changing screen font. Video driver supports changing mode Video driver supports changing cursor shape. Hide cursor Underline cursor Block cursor Half block cursor No errors occurred Base value for video errors No error Video driver initialization error. Unsupported video function Invalid video mode Current screen Width Current screen height Low 32 ASCII character availability

On some systems, the low 32 values of the DOS code page are necessary for the ASCII control codes and cannot be displayed by programs. If LowAscii is true, you can use the low 32 ASCII values. If it is false, you must avoid using them.

LowAscii can be implemented either through a constant, variable or property. You should under no circumstances assume that you can write to LowAscii, or take its address.

Disable transformation of control characters on unix terminals

The VT100 character set only has line drawing characters consisting of a single line. If this value is true, the line drawing characters with two lines will be automatically converted to single lines.

NoExtendedFrame can be implemented either through a constant, variable or property. You should under no circumstances assume that you can write to NoExtendedFrame, or take its address.

Maximum screen buffer width. Error code returned by the last operation. Pointer to extended error information. Error handler routine The ErrorHandler variable can be set to a custom-error handling function. It is set by default to the function. The TVideoMode record describes a videomode. Its fields are self-explaining: Col,Row describe the number of columns and rows on the screen for this mode. Color is True if this mode supports colors, or False if not. Pointer to record. Video mode selection callback prototype. One cell (=screen position) in the video buffer TVideoCell describes one character on the screen. One of the bytes contains the color attribute with which the character is drawn on the screen, and the other byte contains the ASCII code of the character to be drawn. The exact position of the different bytes in the record is operating system specific. On most little-endian systems, the high byte represents the color attribute, while the low-byte represents the ASCII code of the character to be drawn. Pointer type to Screen array type The TVideoBuf type represents the screen. Pointer type to Type used to report and respond to error conditions retry the operation abort and return error code abort without returning an errorcode. Error handler prototype

The TErrorHandler function is used to register an own error handling function. It should be used when installing a custom error handling function, and must return one of the above values.

Code should contain the error code for the error condition, and the Info parameter may contain any data type specific to the error code passed to the function.

Video driver record

TVideoDriver record can be used to install a custom video driver, with the call.

An explanation of all fields can be found there.

Indicate whether current screen supports colors ScreenColor indicates whether the current screen supports colors. Current write cursor X position. Current horizontal position in the screen where items will be written. Current write cursor Y position. Current vertical position in the screen where items will be written. Current screen image. VideoBuf forms the heart of the Video unit: This variable represents the physical screen. Writing to this array and calling will write the actual characters to the screen. Last written screen image.

The OldVideoBuf contains the state of the video screen after the last screen update. The function uses this array to decide which characters on screen should be updated, and which not.

Note that the OldVideoBuf array may be ignored by some drivers, so it should not be used. The Array is in the interface section of the video unit mainly so drivers that need it can make use of it.

Size of the screen image. Current size of the video buffer pointed to by Clear the video screen. ClearScreen clears the entire screen, and calls after that. This is done by writing spaces to all character cells of the video buffer in the default color (lightgray on black, color attribute \$07). None. Default error handling routine. DefaultErrorHandler is the default error handler used by the video driver. It simply sets the error code AErrorCode and AErrorInfo in the global variables ErrorCode and ErrorInfo and returns errContinue. None. Disable video driver.

DoneVideo disables the Video driver if the video driver is active. If the videodriver was already disabled or not yet initialized, it does nothing. Disabling the driver means it will clean up any allocated resources, possibly restore the screen in the state it was before InitVideo was called. Particularly, the VideoBuf and OldVideoBuf arrays are no longer valid after a call to DoneVideo.

The DoneVideo should always be called if InitVideo was called. Failing to do so may leave the screen in an unusable state after the program exits.

For an example, see most other functions.

Normally none. If the driver reports an error, this is done through the ErrorCode variable.
Get current driver capabilities.

GetCapabilities returns the capabilities of the current driver. It is an or-ed combination of the following constants:

cpUnderLine
cpBlink
cpColor
cpChangeFont
cpChangeMode
cpChangeCursor

Note that the video driver should not yet be initialized to use this function. It is a property of the driver.

None.
Get screen cursor type

GetCursorType returns the current cursor type. It is one of the following values:

crHidden
crUnderLine
crBlock
crHalfBlock

Note that not all drivers support all types of cursors.

None.
Get the screen lock update count. GetLockScreenCount returns the current lock level. When the lock level is zero, a call to will actually update the screen. None. Return current video mode GetVideoMode returns the settings of the currently active video mode. The row,col fields indicate the dimensions of the current video mode, and Color is true if the current video supports colors. Get a copy of the current video driver. GetVideoDriver returns the currently active video driver record in Driver. It can be used to clone the current video driver, or to override certain parts of it using the call. None. Get the number of video modes supported by the driver.

GetVideoModeCount returns the number of video modes that the current driver supports. If the driver does not support switching of modes, then 1 is returned.

This function can be used in conjunction with the function to retrieve data for the supported video modes.

None.
Get the specifications for a video mode

GetVideoModeData returns the characteristics of the Index-th video mode in Data. Index is zero based, and has a maximum value of GetVideoModeCount-1. If the current driver does not support setting of modes (GetVideoModeCount=1) and Index is zero, the current mode is returned.

The function returns True if the mode data was retrieved succesfully, False otherwise.

For an example, see .

In case Index has a wrong value, False is returned.
Initialize video driver.

InitVideo Initializes the video subsystem. If the video system was already initialized, it does nothing. After the driver has been initialized, the VideoBuf and OldVideoBuf pointers are initialized, based on the ScreenWidth and ScreenHeight variables. When this is done, the screen is cleared.

For an example, see most other functions.

if the driver fails to initialize, the ErrorCode variable is set.
Prevent further screen updates.

LockScreenUpdate increments the screen update lock count with one. As long as the screen update lock count is not zero, will not actually update the screen.

This function can be used to optimize screen updating: If a lot of writing on the screen needs to be done (by possibly unknown functions), calling LockScreenUpdate before the drawing, and after the drawing, followed by a call, all writing will be shown on screen at once.

For an example, see .

None.
Set write cursor position.

SetCursorPos positions the cursor on the given position: Column NewCursorX and row NewCursorY. The origin of the screen is the upper left corner, and has coordinates (0,0).

The current position is stored in the CursorX and CursorY variables.

None.
Set cursor type

SetCursorType sets the cursor to the type specified in NewType.

crHidden
crUnderLine
crBlock
crHalfBlock
None.
Install a new video driver.

SetVideoDriver sets the videodriver to be used to Driver. If the current videodriver is initialized (after a call to InitVideo) then it does nothing and returns False.

A new driver can only be installed if the previous driver was not yet activated (i.e. before a call to ) or after it was deactivated (i.e after a call to DoneVideo).

For more information about installing a videodriver, see .

For an example, see the section on writing a custom video driver.

If the current driver is initialized, then False is returned.
Record type descrbing a video mode. Number of columns for display Number of rows for display Color support Set current video mode.

SetVideoMode sets the video mode to the mode specified in Mode:

If the call was succesful, then the screen will have Col columns and Row rows, and will be displaying in color if Color is True.

The function returns True if the mode was set succesfully, False otherwise.

Note that the video mode may not always be set. E.g. a console on Linux or a telnet session cannot always set the mode. It is important to check the error value returned by this function if it was not succesful.

The mode can be set when the video driver has not yet been initialized (i.e. before was called) In that case, the video mode will be stored, and after the driver was initialized, an attempt will be made to set the requested mode. Changing the video driver before the call to InitVideo will clear the stored video mode.

To know which modes are valid, use the and functions. To retrieve the current video mode, use the procedure.

If the specified mode cannot be set, then errVioNoSuchMode may be set in ErrorCode
Unlock screen update.

UnlockScreenUpdate decrements the screen update lock count with one if it is larger than zero. When the lock count reaches zero, the will actually update the screen. No screen update will be performed as long as the screen update lock count is nonzero. This mechanism can be used to increase screen performance in case a lot of writing is done.

It is important to make sure that each call to is matched by exactly one call to UnlockScreenUpdate

For an example, see .

None.
Update physical screen with internal screen image.

UpdateScreen synchronizes the actual screen with the contents of the VideoBuf internal buffer. The parameter Force specifies whether the whole screen has to be redrawn (Force=True) or only parts that have changed since the last update of the screen.

The Video unit keeps an internal copy of the screen as it last wrote it to the screen (in the OldVideoBuf array). The current contents of VideoBuf are examined to see what locations on the screen need to be updated. On slow terminals (e.g. a linux telnet session) this mechanism can speed up the screen redraw considerably.

On platforms where mouse cursor visibility is not guaranteed to be preserved during screen updates this routine has to restore the mouse cursor after the update (usually by calling HideMouse from unit Mouse before the real update and ShowMouse afterwards).

For an example, see most other functions.

None.
Writing a custom video driver

Writing a custom video driver is not difficult, and generally means implementing a couple of functions, which whould be registered with the function. The various functions that can be implemented are located in the record:

TVideoDriver = Record InitDriver : Procedure; DoneDriver : Procedure; UpdateScreen : Procedure(Force : Boolean); ClearScreen : Procedure; SetVideoMode : Function (Const Mode : TVideoMode) : Boolean; GetVideoModeCount : Function : Word; GetVideoModeData : Function(Index : Word; Var Data : TVideoMode) : Boolean; SetCursorPos : procedure (NewCursorX, NewCursorY: Word); GetCursorType : function : Word; SetCursorType : procedure (NewType: Word); GetCapabilities : Function : Word; end;

Not all of these functions must be implemented. In fact, the only absolutely necessary function to write a functioning driver is the UpdateScreen function. The general calls in the Video unit will check which functionality is implemented by the driver.

The functionality of these calls is the same as the functionality of the calls in the video unit, so the expected behaviour can be found in the previous section. Some of the calls, however, need some additional remarks.

InitDriver
Called by InitVideo, this function should initialize any data structures needed for the functionality of the driver, maybe do some screen initializations. The function is guaranteed to be called only once; It can only be called again after a call to DoneVideo. The variables ScreenWidth and ScreenHeight should be initialized correctly after a call to this function, as the InitVideo call will initialize the VideoBuf and OldVideoBuf arrays based on their values.
DoneDriver
This should clean up any structures that have been initialized in the InitDriver function. It should possibly also restore the screen as it was before the driver was initialized. The VideoBuf and OldVideoBuf arrays will be disposed of by the general DoneVideo call.
UpdateScreen
This is the only required function of the driver. It should update the screen based on the VideoBuf array's contents. It can optimize this process by comparing the values with values in the OldVideoBuf array. After updating the screen, the UpdateScreen procedure should update the OldVideoBuf by itself. If the Force parameter is True, the whole screen should be updated, not just the changed values.
ClearScreen
If there is a faster way to clear the screen than to write spaces in all character cells, then it can be implemented here. If the driver does not implement this function, then the general routines will write spaces in all video cells, and will call UpdateScreen(True).
SetVideoMode
Should set the desired video mode, if available. It should return True if the mode was set, False if not.
GetVideoModeCount
Should return the number of supported video modes. If no modes are supported, this function should not be implemented; the general routines will return 1. (for the current mode)
GetVideoModeData
Should return the data for the Index-th mode; Index is zero based. The function should return true if the data was returned correctly, false if Index contains an invalid index. If this is not implemented, then the general routine will return the current video mode when Index equals 0.
GetCapabilities
If this function is not implemented, zero (i.e. no capabilities) will be returned by the general function.

The following unit shows how to override a video driver, with a driver that writes debug information to a file. The unit can be used in any of the demonstration programs, by simply including it in the uses clause. Setting DetailedVideoLogging to True will create a more detailed log (but will also slow down functioning)

Examples utility unit The examples in this section make use of the unit vidutil, which contains the TextOut function. This function writes a text to the screen at a given location. It looks as follows: Currently visible scanlines of cursor.

CursorLines is a bitmask which determines which cursor lines are visible and which are not. Each set bit corresponds to a cursorline being shown.

This variable is not supported on all platforms, so it should be used sparingly.

Initializes the driver Finalizes the driver (used for cleanup) Force an update of the screen Clear the screen Set the video mode Get number of supported video modes Return data for the selected video mode Set the cursos position. Get the current cursor type. Set the current cursos type. Get the capabilities of the driver. Various encodings of the input and output descriptors This type is available under Unix-like operating systems only. Codepage 437 Codepage 850 Codepage 852 Codepage 866 KOI8-R codepage ISO 8859-1 ISO 8859-2 ISO 8859-3 ISO 8859-4 ISO 8859-5 ISO 8859-6 ISO 8859-7 ISO 8859-8 ISO 8859-9 ISO 8859-10 ISO 8859-13 ISO 8859-14 ISO 8859-15 UTF-8 encoding Set of code pages that are a normal VGA codepage vga_codepages is a set containing all code pages that can be considered a normal vga font (as in use on early VGA cards) Note that KOI8-R has line drawing characters in wrong place. Set of code pages that use a ISO encoding iso_codepages is a set containing all code pages that use an ISO encoding. Internal codepage used by the video system This variable is for internal use only and should not be used. Codepage used by the terminal. This variable is for internal use only and should not be used.