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
Only use low ascii characters
Disable transformation of control characters on unix terminals
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
Get a copy of the current video driver.
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.
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.

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: