mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 08:19:36 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			700 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			TeX
		
	
	
	
	
	
			
		
		
	
	
			700 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			TeX
		
	
	
	
	
	
%
 | 
						|
%   $Id$
 | 
						|
%   This file is part of the FPC documentation.
 | 
						|
%   Copyright (C) 1997, by Michael Van Canneyt
 | 
						|
%
 | 
						|
%   The FPC documentation is free text; you can redistribute it and/or
 | 
						|
%   modify it under the terms of the GNU Library General Public License as
 | 
						|
%   published by the Free Software Foundation; either version 2 of the
 | 
						|
%   License, or (at your option) any later version.
 | 
						|
%
 | 
						|
%   The FPC Documentation is distributed in the hope that it will be useful,
 | 
						|
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
						|
%   Library General Public License for more details.
 | 
						|
%
 | 
						|
%   You should have received a copy of the GNU Library General Public
 | 
						|
%   License along with the FPC documentation; see the file COPYING.LIB.  If not,
 | 
						|
%   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 | 
						|
%   Boston, MA 02111-1307, USA.
 | 
						|
%
 | 
						|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | 
						|
%
 | 
						|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | 
						|
% The Video unit
 | 
						|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | 
						|
\chapter{The VIDEO unit}
 | 
						|
\FPCexampledir{videoex}
 | 
						|
 | 
						|
The \file{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 \file{Video} is simple: After calling \seep{InitVideo},
 | 
						|
the array \var{VideoBuf} contains a representation of the video screen of
 | 
						|
size \var{ScreenWidth*ScreenHeight}, going from left to right and top to
 | 
						|
bottom when walking the array elements: \var{VideoBuf[0]} contains the 
 | 
						|
character and color code of the top-left character on the screen.
 | 
						|
\var{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
 | 
						|
\var{VideoBuf} array. Calling \seep{UpdateScreen} 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:
 | 
						|
\begin{description}
 | 
						|
\item[bits 0-3] The foreground color. Can be set using all color constants. 
 | 
						|
\item[bits 4-6] The background color. Can be set using a subset of the
 | 
						|
color constants.
 | 
						|
\item[bit 7] The blinking bit. If this bit is set, the character will appear
 | 
						|
blinking.
 | 
						|
\end{description}
 | 
						|
Each possible color has a constant associated with it, see page
 | 
						|
\pageref{vidcolorconst} for a list of constants.
 | 
						|
 | 
						|
The contents of the \var{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 \var{VideoBuf} array, calling \var{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 \seep{LockScreenUpdate} function can be used: This will
 | 
						|
increment an internal counter. As long as the counter differs from zero,
 | 
						|
calling \seep{UpdateScreen} will not do anything. The counter can be
 | 
						|
lowered with \seep{UnlockScreenUpdate}. When it reaches zero, the next call
 | 
						|
to \seep{UpdateScreen} 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 \seef{SetVideoDriver} call. The current video driver can
 | 
						|
be retrieved using the \seep{GetVideoDriver} call.
 | 
						|
 | 
						|
\begin{remark}
 | 
						|
The video unit should {\em not} be used together with the \file{crt} unit.
 | 
						|
Doing so will result in very strange behaviour, possibly program crashes.
 | 
						|
\end{remark}
 | 
						|
 | 
						|
\section{Constants, Type and variables }
 | 
						|
 | 
						|
\subsection{Constants}
 | 
						|
\label{vidcolorconst}
 | 
						|
The following constants describe colors that can be used as 
 | 
						|
foreground and background colors.
 | 
						|
\begin{verbatim}
 | 
						|
Black         = 0;
 | 
						|
Blue          = 1;
 | 
						|
Green         = 2;
 | 
						|
Cyan          = 3;
 | 
						|
Red           = 4;
 | 
						|
Magenta       = 5;
 | 
						|
Brown         = 6;
 | 
						|
LightGray     = 7;
 | 
						|
\end{verbatim}
 | 
						|
The following color constants can be used as foreground colors only:
 | 
						|
\begin{verbatim}
 | 
						|
DarkGray      = 8;
 | 
						|
LightBlue     = 9;
 | 
						|
LightGreen    = 10;
 | 
						|
LightCyan     = 11;
 | 
						|
LightRed      = 12;
 | 
						|
LightMagenta  = 13;
 | 
						|
Yellow        = 14;
 | 
						|
White         = 15;
 | 
						|
\end{verbatim}
 | 
						|
The foreground and background color can be combined to a color attribute
 | 
						|
with the following code:
 | 
						|
\begin{verbatim}
 | 
						|
Attr:=ForeGroundColor + (BackGroundColor shl 4);
 | 
						|
\end{verbatim}
 | 
						|
The color attribute can be logically or-ed with the blink attribute to
 | 
						|
produce a blinking character:
 | 
						|
\begin{verbatim}
 | 
						|
Blink         = 128;
 | 
						|
\end{verbatim}
 | 
						|
But not all drivers may support this.
 | 
						|
 | 
						|
The following constants describe the capabilities of a certain video mode:
 | 
						|
\begin{verbatim}
 | 
						|
cpUnderLine     = $0001;
 | 
						|
cpBlink         = $0002;
 | 
						|
cpColor         = $0004;
 | 
						|
cpChangeFont    = $0008;
 | 
						|
cpChangeMode    = $0010;
 | 
						|
cpChangeCursor  = $0020;
 | 
						|
\end{verbatim}
 | 
						|
The following constants describe the various supported cursor modes:
 | 
						|
\begin{verbatim}
 | 
						|
crHidden        = 0;
 | 
						|
crUnderLine     = 1;
 | 
						|
crBlock         = 2;
 | 
						|
crHalfBlock     = 3;
 | 
						|
\end{verbatim}
 | 
						|
When a video function needs to report an error condition, the following
 | 
						|
constants are used:
 | 
						|
\begin{verbatim}
 | 
						|
vioOK              = 0;
 | 
						|
errVioBase         = 1000;
 | 
						|
errVioInit         = errVioBase + 1; { Initialization error}
 | 
						|
errVioNotSupported = errVioBase + 2; { Unsupported function }
 | 
						|
errVioNoSuchMode   = errVioBase + 3; { No such video mode }
 | 
						|
\end{verbatim}
 | 
						|
The following constants can be read to get some information about the
 | 
						|
current screen:
 | 
						|
\begin{verbatim}
 | 
						|
ScreenWidth     : Word = 0;  { Width of the screen, in characters  }
 | 
						|
ScreenHeight    : Word = 0;  { Height of the screen, in characters }
 | 
						|
LowAscii        : Boolean = true;
 | 
						|
NoExtendedFrame : Boolean = false;
 | 
						|
FVMaxWidth      = 132; 
 | 
						|
\end{verbatim}
 | 
						|
The error-handling code uses the following constants:
 | 
						|
\begin{verbatim}
 | 
						|
errOk              = 0;
 | 
						|
ErrorCode: Longint = ErrOK;
 | 
						|
ErrorInfo: Pointer = nil;
 | 
						|
ErrorHandler: TErrorHandler = DefaultErrorHandler;
 | 
						|
\end{verbatim}
 | 
						|
The \var{ErrorHandler} variable can be set to a custom-error handling
 | 
						|
function. It is set by default to the \seep{DefaultErrorHandler} function.
 | 
						|
 | 
						|
\subsection{Types}
 | 
						|
The \var{TVideoMode} record describes a videomode. Its fields are
 | 
						|
self-explaining: \var{Col,Row} describe the number of columns and 
 | 
						|
rows on the screen for this mode. \var{Color} is \var{True} if this mode
 | 
						|
supports colors, or \var{False} if not.
 | 
						|
\begin{verbatim}
 | 
						|
  PVideoMode = ^TVideoMode;
 | 
						|
  TVideoMode = record
 | 
						|
    Col,Row : Word;
 | 
						|
    Color   : Boolean;
 | 
						|
  end;
 | 
						|
\end{verbatim}
 | 
						|
\var{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.
 | 
						|
\begin{verbatim}
 | 
						|
TVideoCell = Word;
 | 
						|
PVideoCell = ^TVideoCell;
 | 
						|
\end{verbatim}
 | 
						|
The \var{TVideoBuf} and \var{PVideoBuf} are two types used to represent the
 | 
						|
screen.
 | 
						|
\begin{verbatim}
 | 
						|
TVideoBuf = array[0..32759] of TVideoCell;
 | 
						|
PVideoBuf = ^TVideoBuf;
 | 
						|
\end{verbatim}
 | 
						|
The following type is used when reporting error conditions:
 | 
						|
\begin{verbatim}
 | 
						|
TErrorHandlerReturnValue = (errRetry, errAbort, errContinue);
 | 
						|
\end{verbatim}
 | 
						|
Here, \var{errRetry} means retry the operation, \var{errAbort}
 | 
						|
abort and return error code and \var{errContinue} means abort
 | 
						|
without returning an errorcode.
 | 
						|
 | 
						|
The \var{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.
 | 
						|
\begin{verbatim}
 | 
						|
TErrorHandler = 
 | 
						|
  function (Code: Longint; Info: Pointer): TErrorHandlerReturnValue;
 | 
						|
\end{verbatim}
 | 
						|
\var{Code} should contain the error code for the error condition, 
 | 
						|
and the \var{Info} parameter may contain any data type specific to 
 | 
						|
the error code passed to the function.
 | 
						|
 | 
						|
The \var{TVideoDriver} record can be used to install a custom video
 | 
						|
driver, with the \seef{SetVideoDriver} call:
 | 
						|
\begin{verbatim}
 | 
						|
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;
 | 
						|
\end{verbatim}
 | 
						|
 | 
						|
\subsection{Variables}
 | 
						|
The following variables contain information about the current screen
 | 
						|
status:
 | 
						|
\begin{verbatim}
 | 
						|
ScreenColor      : Boolean;
 | 
						|
CursorX, CursorY : Word;
 | 
						|
\end{verbatim}
 | 
						|
\var{ScreenColor} indicates whether the current screen supports colors.
 | 
						|
\var{CursorX,CursorY} contain the current cursor position.
 | 
						|
 | 
						|
The following variable forms the heart of the \file{Video} unit: The
 | 
						|
\var{VideoBuf} array represents the physical screen. Writing to this
 | 
						|
array and calling \seep{UpdateScreen} will write the actual characters
 | 
						|
to the screen. 
 | 
						|
\begin{verbatim}
 | 
						|
VideoBuf     : PVideoBuf;
 | 
						|
OldVideoBuf  : PVideoBuf;
 | 
						|
VideoBufSize : Longint;
 | 
						|
\end{verbatim}
 | 
						|
The \var{OldVideoBuf} contains the state of the video screen after the last
 | 
						|
screen update. The \seep{UpdateScreen} function uses this array to decide
 | 
						|
which characters on screen should be updated, and which not. 
 | 
						|
 | 
						|
Note that the \var{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. 
 | 
						|
 | 
						|
\section{Functions and Procedures}
 | 
						|
 | 
						|
The examples in this section make use of the unit \file{vidutil}, which 
 | 
						|
contains the \var{TextOut} function. This function writes a text to the
 | 
						|
screen at a given location. It looks as follows:
 | 
						|
 | 
						|
\FPCexample{vidutil}
 | 
						|
 | 
						|
\begin{procedure}{ClearScreen}
 | 
						|
\Declaration
 | 
						|
procedure ClearScreen; 
 | 
						|
\Description
 | 
						|
\var{ClearScreen} clears the entire screen, and calls \seep{UpdateScreen}
 | 
						|
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).
 | 
						|
\Errors
 | 
						|
None.
 | 
						|
\SeeAlso
 | 
						|
\seep{InitVideo}, \seep{UpdateScreen}
 | 
						|
\end{procedure}
 | 
						|
 | 
						|
\FPCexample{ex3}
 | 
						|
 | 
						|
\begin{procedure}{DefaultErrorHandler}
 | 
						|
\Declaration
 | 
						|
function  DefaultErrorHandler(AErrorCode: Longint; AErrorInfo: Pointer): TErrorHandlerReturnValue; 
 | 
						|
\Description
 | 
						|
\var{DefaultErrorHandler} is the default error handler used by the video
 | 
						|
driver. It simply sets the error code \var{AErrorCode} and \var{AErrorInfo} 
 | 
						|
in the global variables \var{ErrorCode} and \var{ErrorInfo} and returns 
 | 
						|
\var{errContinue}.
 | 
						|
\Errors
 | 
						|
None.
 | 
						|
\SeeAlso
 | 
						|
\end{procedure}
 | 
						|
 | 
						|
\begin{procedure}{DoneVideo}
 | 
						|
\Declaration
 | 
						|
procedure DoneVideo; 
 | 
						|
\Description
 | 
						|
\var{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
 | 
						|
\var{InitVideo} was called. Particularly, the \var{VideoBuf} and
 | 
						|
\var{OldVideoBuf} arrays are no longer valid after a call to 
 | 
						|
\var{DoneVideo}.
 | 
						|
 | 
						|
The \var{DoneVideo} should always be called if \var{InitVideo} was called.
 | 
						|
Failing to do so may leave the screen in an unusable state after the program
 | 
						|
exits.
 | 
						|
\Errors
 | 
						|
Normally none. If the driver reports an error, this is done through the
 | 
						|
\var{ErrorCode} variable.
 | 
						|
\SeeAlso
 | 
						|
\seep{InitVideo}
 | 
						|
\end{procedure}
 | 
						|
 | 
						|
For an example, see most other functions.
 | 
						|
 | 
						|
\begin{function}{GetCapabilities}
 | 
						|
\Declaration
 | 
						|
function GetCapabilities: Word; 
 | 
						|
\Description
 | 
						|
\var{GetCapabilities} returns the capabilities of the current driver.
 | 
						|
It is an or-ed combination of the following constants:
 | 
						|
\begin{description}
 | 
						|
\item[cpUnderLine] The driver supports underlined characters.
 | 
						|
\item[cpBlink] The driver supports blinking characters.
 | 
						|
\item[cpColor] The driver supports colors.
 | 
						|
\item[cpChangeFont] The driver supports the setting of a screen font.
 | 
						|
Note, however, that a font setting API is not supported by the video unit.
 | 
						|
\item[cpChangeMode] The driver supports the setting of screen modes. 
 | 
						|
\item[cpChangeCursor] The driver supports changing the cursor shape.
 | 
						|
\end{description}
 | 
						|
Note that the video driver should not yet be initialized to use this
 | 
						|
function. It is a property of the driver.
 | 
						|
\Errors
 | 
						|
None.
 | 
						|
\SeeAlso
 | 
						|
\seef{GetCursorType}, \seep{GetVideoDriver}
 | 
						|
\end{function}
 | 
						|
 | 
						|
\FPCexample{ex4}
 | 
						|
 | 
						|
\begin{function}{GetCursorType}
 | 
						|
\Declaration
 | 
						|
function GetCursorType: Word; 
 | 
						|
\Description
 | 
						|
\var{GetCursorType} returns the current cursor type. It is one of the
 | 
						|
following values: 
 | 
						|
\begin{description}
 | 
						|
\item[crHidden] The cursor is currently hidden.
 | 
						|
\item[crUnderLine] The cursor is currently the underline character.
 | 
						|
\item[crBlock] The cursor is currently the block character.
 | 
						|
\item[crHalfBlock] The cursur is currently a block with height of half the
 | 
						|
character cell height.
 | 
						|
\end{description}
 | 
						|
Note that not all drivers support all types of cursors.
 | 
						|
\Errors
 | 
						|
None.
 | 
						|
\SeeAlso
 | 
						|
\seep{SetCursorType}, \seef{GetCapabilities}
 | 
						|
\end{function}
 | 
						|
 | 
						|
\FPCexample{ex5}
 | 
						|
 | 
						|
\begin{function}{GetLockScreenCount}
 | 
						|
\Declaration
 | 
						|
Function GetLockScreenCount : integer;
 | 
						|
\Description
 | 
						|
\var{GetLockScreenCount} returns the current lock level. When the lock
 | 
						|
level is zero, a call to \seep{UpdateScreen} will actually update the
 | 
						|
screen.
 | 
						|
\Errors
 | 
						|
None.
 | 
						|
\SeeAlso
 | 
						|
\seep{LockScreenUpdate}, \seep{UnlockScreenUpdate}, \seep{UpdateScreen}
 | 
						|
\end{function}
 | 
						|
 | 
						|
\FPCexample{ex6}
 | 
						|
 | 
						|
\begin{procedure}{GetVideoDriver}
 | 
						|
\Declaration
 | 
						|
Procedure GetVideoDriver (Var Driver : TVideoDriver);
 | 
						|
\Declaration
 | 
						|
\var{GetVideoDriver} retrieves the current videodriver and returns it in
 | 
						|
\var{Driver}. This can be used to chain video drivers.
 | 
						|
\Errors
 | 
						|
None.
 | 
						|
\SeeAlso
 | 
						|
\seef{SetVideoDriver}
 | 
						|
\end{procedure}
 | 
						|
 | 
						|
For an example, see the section on writing a custom video driver.
 | 
						|
 | 
						|
\begin{procedure}{GetVideoMode}
 | 
						|
\Declaration
 | 
						|
procedure GetVideoMode(var Mode: TVideoMode); 
 | 
						|
\Description
 | 
						|
\var{GetVideoMode} returns the settings of the currently active video mode.
 | 
						|
The \var{row,col} fields indicate the dimensions of the current video mode,
 | 
						|
and \var{Color} is true if the current video supports colors.
 | 
						|
\Errors
 | 
						|
None.
 | 
						|
\SeeAlso
 | 
						|
\seef{SetVideoMode}, \seef{GetVideoModeData}
 | 
						|
\end{procedure}
 | 
						|
 | 
						|
\FPCexample{ex7}
 | 
						|
 | 
						|
\begin{function}{GetVideoModeCount}
 | 
						|
\Declaration
 | 
						|
Function GetVideoModeCount : Word;
 | 
						|
\Description
 | 
						|
\var{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 \seef{GetVideoModeData}
 | 
						|
function to retrieve data for the supported video modes.
 | 
						|
\Errors
 | 
						|
None.
 | 
						|
\SeeAlso
 | 
						|
\seef{GetVideoModeData}, \seep{GetVideoMode}
 | 
						|
\end{function}
 | 
						|
 | 
						|
\FPCexample{ex8}
 | 
						|
 | 
						|
\begin{function}{GetVideoModeData}
 | 
						|
\Declaration
 | 
						|
Function GetVideoModeData(Index : Word; Var Data: TVideoMode) : Boolean;  
 | 
						|
\Description
 | 
						|
\var{GetVideoModeData} returns the characteristics of the \var{Index}-th
 | 
						|
video mode in \var{Data}. \var{Index} is zero based, and has a maximum value of
 | 
						|
\var{GetVideoModeCount-1}. If the current driver does not support setting of
 | 
						|
modes (\var{GetVideoModeCount=1}) and \var{Index} is zero, the current mode 
 | 
						|
is returned.
 | 
						|
 | 
						|
The function returns \var{True} if the mode data was retrieved succesfully,
 | 
						|
\var{False} otherwise.
 | 
						|
\Errors
 | 
						|
In case \var{Index} has a wrong value, \var{False} is returned.
 | 
						|
\SeeAlso
 | 
						|
\seef{GetVideoModeCount}, \seef{SetVideoMode}, \seep{GetVideoMode}
 | 
						|
\end{function}
 | 
						|
 | 
						|
For an example, see \seef{GetVideoModeCount}.
 | 
						|
 | 
						|
\begin{procedure}{InitVideo}
 | 
						|
\Declaration
 | 
						|
procedure InitVideo; 
 | 
						|
\Description
 | 
						|
\var{InitVideo} Initializes the video subsystem. If the video system was
 | 
						|
already initialized, it does nothing. 
 | 
						|
After the driver has been initialized, the \var{VideoBuf} and \var{OldVideoBuf} 
 | 
						|
pointers are initialized, based on the \var{ScreenWidth} and
 | 
						|
\var{ScreenHeight} variables. When this is done, the screen is cleared.
 | 
						|
\Errors
 | 
						|
if the driver fails to initialize, the \var{ErrorCode} variable is set.
 | 
						|
\SeeAlso
 | 
						|
\seep{DoneVideo}
 | 
						|
\end{procedure}
 | 
						|
 | 
						|
For an example, see most other functions.
 | 
						|
 | 
						|
\begin{procedure}{LockScreenUpdate}
 | 
						|
\Declaration
 | 
						|
Procedure LockScreenUpdate;
 | 
						|
\Description
 | 
						|
\var{LockScreenUpdate} increments the screen update lock count with one.
 | 
						|
As long as the screen update lock count is not zero, \seep{UpdateScreen}
 | 
						|
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
 | 
						|
\var{LockScreenUpdate} before the drawing, and \seep{UnlockScreenUpdate}
 | 
						|
after the drawing, followed by a \seep{UpdateScreen} call, all writing will
 | 
						|
be shown on screen at once.
 | 
						|
\Errors
 | 
						|
None.
 | 
						|
\SeeAlso
 | 
						|
\seep{UpdateScreen}, \seep{UnlockScreenUpdate}, \seef{GetLockScreenCount}
 | 
						|
\end{procedure}
 | 
						|
 | 
						|
For an example, see \seef{GetLockScreenCount}.
 | 
						|
 | 
						|
\begin{procedure}{SetCursorPos}
 | 
						|
\Declaration
 | 
						|
procedure SetCursorPos(NewCursorX, NewCursorY: Word); 
 | 
						|
\Description
 | 
						|
\var{SetCursorPos} positions the cursor on the given position: Column 
 | 
						|
\var{NewCursorX} and row \var{NewCursorY}. The origin of the screen is the
 | 
						|
upper left corner, and has coordinates \var{(0,0)}.
 | 
						|
 | 
						|
The current position is stored in the \var{CursorX} and \var{CursorY}
 | 
						|
variables.
 | 
						|
\Errors
 | 
						|
None.
 | 
						|
\SeeAlso
 | 
						|
\seep{SetCursorType}
 | 
						|
\end{procedure}
 | 
						|
 | 
						|
\FPCexample{ex2}
 | 
						|
 | 
						|
\begin{procedure}{SetCursorType}
 | 
						|
\Declaration
 | 
						|
procedure SetCursorType(NewType: Word); 
 | 
						|
\Description
 | 
						|
\var{SetCursorType} sets the cursor to the type specified in \var{NewType}.
 | 
						|
\begin{description}
 | 
						|
\item[crHidden] the cursor is not visible.
 | 
						|
\item[crUnderLine] the cursor is a small underline character (usually 
 | 
						|
denoting insert mode).
 | 
						|
\item[crBlock] the cursor is a block the size of a screen cell (usually
 | 
						|
denoting overwrite mode).
 | 
						|
\item[crHalfBlock] the cursor is a block half the size of a screen cell.
 | 
						|
\end{description}
 | 
						|
\Errors
 | 
						|
None.
 | 
						|
\SeeAlso
 | 
						|
\seep{SetCursorPos}
 | 
						|
\end{procedure}
 | 
						|
 | 
						|
\begin{function}{SetVideoDriver}
 | 
						|
\Declaration
 | 
						|
Function SetVideoDriver (Const Driver : TVideoDriver) : Boolean;
 | 
						|
\Description
 | 
						|
\var{SetVideoDriver} sets the videodriver to be used to \var{Driver}. If
 | 
						|
the current videodriver is initialized (after a call to \var{InitVideo})
 | 
						|
then it does nothing and returns \var{False}.
 | 
						|
 | 
						|
A new driver can only be installed if the previous driver was not yet
 | 
						|
activated (i.e. before a call to \seep{InitVideo}) or after it was
 | 
						|
deactivated (i.e after a call to \var{DoneVideo}).
 | 
						|
 | 
						|
For more information about installing a videodriver, see \sees{viddriver}.
 | 
						|
\Errors
 | 
						|
If the current driver is initialized, then \var{False} is returned.
 | 
						|
\SeeAlso
 | 
						|
The example video driver in \sees{viddriver}
 | 
						|
\end{function}
 | 
						|
 | 
						|
For an example, see the section on writing a custom video driver.
 | 
						|
 | 
						|
\begin{function}{SetVideoMode}
 | 
						|
\Declaration
 | 
						|
Function SetVideoMode(Mode: TVideoMode) : Boolean;
 | 
						|
\Description
 | 
						|
\var{SetVideoMode} sets the video mode to the mode specified in \var{Mode}:
 | 
						|
\begin{verbatim}
 | 
						|
  TVideoMode = record
 | 
						|
    Col,Row : Word;
 | 
						|
    Color   : Boolean;
 | 
						|
  end;
 | 
						|
\end{verbatim}
 | 
						|
If the call was succesful, then the screen will have \var{Col} columns and
 | 
						|
\var{Row} rows, and will be displaying in color if \var{Color} is
 | 
						|
\var{True}. 
 | 
						|
 | 
						|
The function returns \var{True} if the mode was set succesfully, \var{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 \seep{InitVideo} 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
 | 
						|
\var{InitVideo} will clear the stored video mode.
 | 
						|
 | 
						|
To know which modes are valid, use the \seef{GetVideoModeCount} and
 | 
						|
\seef{GetVideoModeData} functions. To retrieve the current video mode, 
 | 
						|
use the \seep{GetVideoMode} procedure.
 | 
						|
\Errors
 | 
						|
If the specified mode cannot be set, then \var{errVioNoSuchMode} may be set
 | 
						|
in \var{ErrorCode}
 | 
						|
\SeeAlso
 | 
						|
\seef{GetVideoModeCount}
 | 
						|
\seef{GetVideoModeData}
 | 
						|
\seep{GetVideoMode}
 | 
						|
\end{function}
 | 
						|
 | 
						|
\begin{procedure}{UnlockScreenUpdate}
 | 
						|
\Declaration
 | 
						|
Procedure UnlockScreenUpdate;
 | 
						|
\Description
 | 
						|
\var{UnlockScreenUpdate} decrements the screen update lock count with one if
 | 
						|
it is larger than zero. When the lock count reaches zero, the 
 | 
						|
\seep{UpdateScreen} 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 \seep{LockScreenUpdate} is
 | 
						|
matched by exactly one call to \var{UnlockScreenUpdate}
 | 
						|
\Errors
 | 
						|
None.
 | 
						|
\SeeAlso
 | 
						|
\seep{LockScreenUpdate}, \seef{GetLockScreenCount}, \seep{UpdateScreen}
 | 
						|
\end{procedure}
 | 
						|
 | 
						|
For an example, see \seef{GetLockScreenCount}.
 | 
						|
 | 
						|
\begin{procedure}{UpdateScreen}
 | 
						|
\Declaration
 | 
						|
procedure UpdateScreen(Force: Boolean); 
 | 
						|
\Description
 | 
						|
\var{UpdateScreen} synchronizes the actual screen with the contents
 | 
						|
of the \var{VideoBuf} internal buffer. The parameter \var{Force}
 | 
						|
specifies whether the whole screen has to be redrawn (\var{Force=True})
 | 
						|
or only parts that have changed since the last update of the screen.
 | 
						|
 | 
						|
The \var{Video} unit keeps an internal copy of the screen as it last 
 | 
						|
wrote it to the screen (in the \var{OldVideoBuf} array). The current 
 | 
						|
contents of \var{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.
 | 
						|
\Errors
 | 
						|
None.
 | 
						|
\SeeAlso
 | 
						|
\seep{ClearScreen}
 | 
						|
\end{procedure}
 | 
						|
 | 
						|
For an example, see most other functions.
 | 
						|
 | 
						|
\section{Writing a custom video driver}
 | 
						|
\label{se:viddriver}
 | 
						|
Writing a custom video driver is not difficult, and generally means
 | 
						|
implementing a couple of functions, which whould be registered with
 | 
						|
the \seef{SetVideoDriver} function. The various functions that can be
 | 
						|
implemented are located in the \var{TVideoDriver} record:
 | 
						|
\begin{verbatim}
 | 
						|
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;
 | 
						|
\end{verbatim}
 | 
						|
Not all of these functions must be implemented. In fact, the only absolutely
 | 
						|
necessary function to write a functioning driver is the \var{UpdateScreen} 
 | 
						|
function. The general calls in the \file{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.
 | 
						|
\begin{description}
 | 
						|
\item[InitDriver] Called by \var{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 \var{DoneVideo}. The variables
 | 
						|
\var{ScreenWidth} and \var{ScreenHeight} should be initialized correctly
 | 
						|
after a call to this function, as the \var{InitVideo} call will initialize
 | 
						|
the \var{VideoBuf} and \var{OldVideoBuf} arrays based on their values.
 | 
						|
\item[DoneDriver] This should clean up any structures that have been
 | 
						|
initialized in the \var{InitDriver} function. It should possibly also
 | 
						|
restore the screen as it was before the driver was initialized. The VideoBuf
 | 
						|
and \var{OldVideoBuf} arrays will be disposed of by the general \var{DoneVideo}
 | 
						|
call.
 | 
						|
\item[UpdateScreen] This is the only required function of the driver. It
 | 
						|
should update the screen based on the \var{VideoBuf} array's contents. It
 | 
						|
can optimize this process by comparing the values with values in the
 | 
						|
\var{OldVideoBuf} array. After updating the screen, the \var{UpdateScreen}
 | 
						|
procedure should update the \var{OldVideoBuf} by itself. If the \var{Force}
 | 
						|
parameter is \var{True}, the whole screen should be updated, not just the
 | 
						|
changed values.
 | 
						|
\item[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 \var{UpdateScreen(True)}.
 | 
						|
\item[SetVideoMode] Should set the desired video mode, if available. It
 | 
						|
should return \var{True} if the mode was set, \var{False} if not.
 | 
						|
\item[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)
 | 
						|
\item[GetVideoModeData] Should return the data for the \var{Index}-th mode;
 | 
						|
\var{Index} is zero based. The function should return true if the data was
 | 
						|
returned correctly, false if \var{Index} contains an invalid index.
 | 
						|
If this is not implemented, then the general routine will return the current 
 | 
						|
video mode when \var{Index} equals 0.
 | 
						|
\item[GetCapabilities] If this function is not implemented, zero (i.e.
 | 
						|
no capabilities) will be returned by the general function.
 | 
						|
\end{description}
 | 
						|
 | 
						|
The following unit shows how to override a video driver, with a driver
 | 
						|
that writes debug information to a file.
 | 
						|
 | 
						|
\FPCexample{viddbg}
 | 
						|
 | 
						|
The unit can be used in any of the demonstration programs, by simply
 | 
						|
including it in the \var{uses} clause. Setting \var{DetailedVideoLogging} to
 | 
						|
\var{True} will create a more detailed log (but will also slow down
 | 
						|
functioning) |