%
%   $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.

\section{Constants, Type and variables }

\subsection{Constants}
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 only as foreground colors:
\begin{verbatim}
DarkGray      = 8;
LightBlue     = 9;
LightGreen    = 10;
LightCyan     = 11;
LightRed      = 12;
LightMagenta  = 13;
Yellow        = 14;
White         = 15;
\end{verbatim}
The foreground color can be logically or-ed with the blink attribute:
\begin{verbatim}
Blink         = 128;
\end{verbatim}
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;
ScreenHeight    : Word = 0;
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 \seef{DefaultErrorHandler} function.

The \var{Modes} list contains the list of supported video modes:
\begin{verbatim}
Modes: PVideoModeList = nil;
\end{verbatim}

\subsection{Types}
The \var{TVideoMode} record describes a videomode. Its fields are
self-explaining. The \var{TVideoModeSelector} procedural variable
is used to select a video mode.
\begin{verbatim}
  PVideoMode = ^TVideoMode;
  TVideoMode = record
    Col,Row : Word;
    Color   : Boolean;
  end;
  TVideoModeSelector = function (const VideoMode: TVideoMode; Params: Longint): Boolean;
\end{verbatim}
\var{TVideoCell} describes one character on the screen. The high byte
contains the color attribute with which the character is drawn on the screen,
and the low byte contains 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}
When registering video modes, the following typed are used to store the
registered modes:
\begin{verbatim}
PVideoModeList = ^TVideoModeList;
TVideoModeList = record
  Col, Row: Word;
  Color: Boolean;
  VideoModeSelector: TVideoModeSelector;
  Params: Longint;
  Next: PVideoModeList;
end;
\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.

\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 \var{LockUpdateScreen} variable can be incremented to prevent the 
\seep{UpdateScreen} procedure from actually updating the screen. The 
\var{UpdateScreen} procedure will only update the screen when the
\var{LockUpdateScreen} variable is zero. This mechanism can be used
to optimize the screen updating routines when various updates are 
performed at once.
\begin{verbatim}
LockUpdateScreen : Word;
CursorLines  : Byte;
\end{verbatim}
The following variables form 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. \var{VideoBufSize} contains the actual screen size, and is
equal to the product of the number of columns times the number of lines 
on the screen (\var{ScreenWidth*ScreenHeight}).
\begin{verbatim}
VideoBuf     : PVideoBuf;
VideoBufSize : Longint;
\end
\end{verbatim}

\section{Functions and Procedures}

\begin{procedure}{ClearScreen}
\Declaration
procedure ClearScreen; 
\Description
\var{ClearScreen} clears the entire screen, and calls \seep{UpdateScreen}
after that.
\Errors
None.
\SeeAlso
\seep{InitVideo}, \seep{UpdateScreen}
\end{procedure}

\begin{procedure}{DefaultErrorHandler}
\Declaration
function  DefaultErrorHandler(AErrorCode: Longint; AErrorInfo: Pointer): TErrorHandlerReturnValue; 
\Description
{ Default error handler, simply sets error code, and returns errContinue }
\Errors
\SeeAlso
\end{procedure}

\begin{procedure}{DefaultVideoModeSelector}
\Declaration
function  DefaultVideoModeSelector(const VideoMode: TVideoMode; Params: Longint): Boolean;
\Description
\Errors
\SeeAlso
\end{procedure}

\begin{procedure}{DoneVideo}
\Declaration
procedure DoneVideo; 
\Description
{ Deinitializes the video subsystem }
\Errors
\SeeAlso
\end{procedure}

\begin{function}{GetCapabilities}
\Declaration
function  GetCapabilities: Word; 
\Description
{ Return the capabilities of the current environment }
\Errors
\SeeAlso
\end{function}

\begin{function}{GetCursorType}
\Declaration
function GetCursorType: Word; 
\Description
{ Return the cursor type: Hidden, UnderLine or Block }
\Errors
\SeeAlso
\end{function}

\begin{procedure}{GetVideoMode}
\Declaration
procedure GetVideoMode(var Mode: TVideoMode); 
\Description
{ Return dimensions of the current video mode }
\Errors
\SeeAlso
\end{procedure}

\begin{procedure}{InitVideo}
\Declaration
procedure InitVideo; 
\Description
{ Initializes the video subsystem }
\Errors
\SeeAlso
\end{procedure}

\begin{procedure}{RegisterVideoMode}
\Declaration
procedure RegisterVideoMode(Col, Row: Word; Color: Boolean; VideoModeSelector: TVideoModeSelector; Params: Longint); 
\Description
{ Registers a video mode to be selectable by SetVideoMode } 
{ moved to interface because we need a way to retrieve the modes }
\Errors
\SeeAlso
\end{procedure}

\begin{procedure}{SetCursorPos}
\Declaration
procedure SetCursorPos(NewCursorX, NewCursorY: Word); 
\Description
{ Position the cursor to the given position }
\Errors
\SeeAlso
\end{procedure}

\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{procedure}{SetVideoMode}
\Declaration
procedure SetVideoMode(Mode: TVideoMode); 
\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}.
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.
\Errors
If the specified mode cannot be set, then \var{errVioNoSuchMode} may be set
in \var{ErrorCode}
\SeeAlso
\end{procedure}

\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. 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}

