video.tex 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  1. %
  2. % $Id$
  3. % This file is part of the FPC documentation.
  4. % Copyright (C) 1997, by Michael Van Canneyt
  5. %
  6. % The FPC documentation is free text; you can redistribute it and/or
  7. % modify it under the terms of the GNU Library General Public License as
  8. % published by the Free Software Foundation; either version 2 of the
  9. % License, or (at your option) any later version.
  10. %
  11. % The FPC Documentation is distributed in the hope that it will be useful,
  12. % but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. % Library General Public License for more details.
  15. %
  16. % You should have received a copy of the GNU Library General Public
  17. % License along with the FPC documentation; see the file COPYING.LIB. If not,
  18. % write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  19. % Boston, MA 02111-1307, USA.
  20. %
  21. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  22. %
  23. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  24. % The Video unit
  25. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  26. \chapter{The VIDEO unit}
  27. \FPCexampledir{videoex}
  28. The \file{Video} unit implements a screen access layer which is system
  29. independent. It can be used to write on the screen in a system-independent
  30. way, which should be optimal on all platforms for which the unit is
  31. implemented.
  32. The working of the \file{Video} is simple: After calling \seep{InitVideo},
  33. the array \var{VideoBuf} contains a representation of the video screen of
  34. size \var{ScreenWidth*ScreenHeight}, going from left to right and top to
  35. bottom when walking the array elements: \var{VideoBuf[0]} contains the
  36. character and color code of the top-left character on the screen.
  37. \var{VideoBuf[ScreenWidth]} contains the data for the character in the
  38. first column of the second row on the screen, and so on.
  39. To write to the 'screen', the text to be written should be written to the
  40. \var{VideoBuf} array. Calling \seep{UpdateScreen} will then cp the text to
  41. the screen in the most optimal way. (an example can be found further on).
  42. The color attribute is a combination of the foreground and background color,
  43. plus the blink bit. The bits describe the various color combinations:
  44. \begin{description}
  45. \item[bits 0-3] The foreground color. Can be set using all color constants.
  46. \item[bits 4-6] The background color. Can be set using a subset of the
  47. color constants.
  48. \item[bit 7] The blinking bit. If this bit is set, the character will appear
  49. blinking.
  50. \end{description}
  51. Each possible color has a constant associated with it, see page
  52. \pageref{vidcolorconst} for a list of constants.
  53. The contents of the \var{VideoBuf} array may be modified: This is 'writing'
  54. to the screen. As soon as everything that needs to be written in the array
  55. is in the \var{VideoBuf} array, calling \var{UpdateScreen} will copy the
  56. contents of the array screen to the screen, in a manner that is as efficient
  57. as possible.
  58. The updating of the screen can be prohibited to optimize performance; To
  59. this end, the \seep{LockScreenUpdate} function can be used: This will
  60. increment an internal counter. As long as the counter differs from zero,
  61. calling \seep{UpdateScreen} will not do anything. The counter can be
  62. lowered with \seep{UnlockScreenUpdate}. When it reaches zero, the next call
  63. to \seep{UpdateScreen} will actually update the screen. This is useful when
  64. having nested procedures that do a lot of screen writing.
  65. The video unit also presents an interface for custom screen drivers, thus
  66. it is possible to override the default screen driver with a custom screen
  67. driver, see the \seef{SetVideoDriver} call. The current video driver can
  68. be retrieved using the \seep{GetVideoDriver} call.
  69. \begin{remark}
  70. The video unit should {\em not} be used together with the \file{crt} unit.
  71. Doing so will result in very strange behaviour, possibly program crashes.
  72. \end{remark}
  73. \section{Constants, Type and variables }
  74. \subsection{Constants}
  75. \label{vidcolorconst}
  76. The following constants describe colors that can be used as
  77. foreground and background colors.
  78. \begin{verbatim}
  79. Black = 0;
  80. Blue = 1;
  81. Green = 2;
  82. Cyan = 3;
  83. Red = 4;
  84. Magenta = 5;
  85. Brown = 6;
  86. LightGray = 7;
  87. \end{verbatim}
  88. The following color constants can be used as foreground colors only:
  89. \begin{verbatim}
  90. DarkGray = 8;
  91. LightBlue = 9;
  92. LightGreen = 10;
  93. LightCyan = 11;
  94. LightRed = 12;
  95. LightMagenta = 13;
  96. Yellow = 14;
  97. White = 15;
  98. \end{verbatim}
  99. The foreground and background color can be combined to a color attribute
  100. with the following code:
  101. \begin{verbatim}
  102. Attr:=ForeGroundColor + (BackGroundColor shl 4);
  103. \end{verbatim}
  104. The color attribute can be logically or-ed with the blink attribute to
  105. produce a blinking character:
  106. \begin{verbatim}
  107. Blink = 128;
  108. \end{verbatim}
  109. But not all drivers may support this.
  110. The following constants describe the capabilities of a certain video mode:
  111. \begin{verbatim}
  112. cpUnderLine = $0001;
  113. cpBlink = $0002;
  114. cpColor = $0004;
  115. cpChangeFont = $0008;
  116. cpChangeMode = $0010;
  117. cpChangeCursor = $0020;
  118. \end{verbatim}
  119. The following constants describe the various supported cursor modes:
  120. \begin{verbatim}
  121. crHidden = 0;
  122. crUnderLine = 1;
  123. crBlock = 2;
  124. crHalfBlock = 3;
  125. \end{verbatim}
  126. When a video function needs to report an error condition, the following
  127. constants are used:
  128. \begin{verbatim}
  129. vioOK = 0;
  130. errVioBase = 1000;
  131. errVioInit = errVioBase + 1; { Initialization error}
  132. errVioNotSupported = errVioBase + 2; { Unsupported function }
  133. errVioNoSuchMode = errVioBase + 3; { No such video mode }
  134. \end{verbatim}
  135. The following constants can be read to get some information about the
  136. current screen:
  137. \begin{verbatim}
  138. ScreenWidth : Word = 0; { Width of the screen, in characters }
  139. ScreenHeight : Word = 0; { Height of the screen, in characters }
  140. LowAscii : Boolean = true;
  141. NoExtendedFrame : Boolean = false;
  142. FVMaxWidth = 132;
  143. \end{verbatim}
  144. The error-handling code uses the following constants:
  145. \begin{verbatim}
  146. errOk = 0;
  147. ErrorCode: Longint = ErrOK;
  148. ErrorInfo: Pointer = nil;
  149. ErrorHandler: TErrorHandler = DefaultErrorHandler;
  150. \end{verbatim}
  151. The \var{ErrorHandler} variable can be set to a custom-error handling
  152. function. It is set by default to the \seep{DefaultErrorHandler} function.
  153. \subsection{Types}
  154. The \var{TVideoMode} record describes a videomode. Its fields are
  155. self-explaining: \var{Col,Row} describe the number of columns and
  156. rows on the screen for this mode. \var{Color} is \var{True} if this mode
  157. supports colors, or \var{False} if not.
  158. \begin{verbatim}
  159. PVideoMode = ^TVideoMode;
  160. TVideoMode = record
  161. Col,Row : Word;
  162. Color : Boolean;
  163. end;
  164. \end{verbatim}
  165. \var{TVideoCell} describes one character on the screen. One of the bytes
  166. contains the color attribute with which the character is drawn on the screen,
  167. and the other byte contains the ASCII code of the character to be drawn. The
  168. exact position of the different bytes in the record is operating system specific.
  169. On most little-endian systems, the high byte represents the color attribute,
  170. while the low-byte represents the ASCII code of the character to be drawn.
  171. \begin{verbatim}
  172. TVideoCell = Word;
  173. PVideoCell = ^TVideoCell;
  174. \end{verbatim}
  175. The \var{TVideoBuf} and \var{PVideoBuf} are two types used to represent the
  176. screen.
  177. \begin{verbatim}
  178. TVideoBuf = array[0..32759] of TVideoCell;
  179. PVideoBuf = ^TVideoBuf;
  180. \end{verbatim}
  181. The following type is used when reporting error conditions:
  182. \begin{verbatim}
  183. TErrorHandlerReturnValue = (errRetry, errAbort, errContinue);
  184. \end{verbatim}
  185. Here, \var{errRetry} means retry the operation, \var{errAbort}
  186. abort and return error code and \var{errContinue} means abort
  187. without returning an errorcode.
  188. The \var{TErrorHandler} function is used to register an own error
  189. handling function. It should be used when installing a custom error
  190. handling function, and must return one of the above values.
  191. \begin{verbatim}
  192. TErrorHandler =
  193. function (Code: Longint; Info: Pointer): TErrorHandlerReturnValue;
  194. \end{verbatim}
  195. \var{Code} should contain the error code for the error condition,
  196. and the \var{Info} parameter may contain any data type specific to
  197. the error code passed to the function.
  198. The \var{TVideoDriver} record can be used to install a custom video
  199. driver, with the \seef{SetVideoDriver} call:
  200. \begin{verbatim}
  201. TVideoDriver = Record
  202. InitDriver : Procedure;
  203. DoneDriver : Procedure;
  204. UpdateScreen : Procedure(Force : Boolean);
  205. ClearScreen : Procedure;
  206. SetVideoMode : Function (Const Mode : TVideoMode) : Boolean;
  207. GetVideoModeCount : Function : Word;
  208. GetVideoModeData : Function(Index : Word; Var Data : TVideoMode) : Boolean;
  209. SetCursorPos : procedure (NewCursorX, NewCursorY: Word);
  210. GetCursorType : function : Word;
  211. SetCursorType : procedure (NewType: Word);
  212. GetCapabilities : Function : Word;
  213. end;
  214. \end{verbatim}
  215. \subsection{Variables}
  216. The following variables contain information about the current screen
  217. status:
  218. \begin{verbatim}
  219. ScreenColor : Boolean;
  220. CursorX, CursorY : Word;
  221. \end{verbatim}
  222. \var{ScreenColor} indicates whether the current screen supports colors.
  223. \var{CursorX,CursorY} contain the current cursor position.
  224. The following variable forms the heart of the \file{Video} unit: The
  225. \var{VideoBuf} array represents the physical screen. Writing to this
  226. array and calling \seep{UpdateScreen} will write the actual characters
  227. to the screen.
  228. \begin{verbatim}
  229. VideoBuf : PVideoBuf;
  230. OldVideoBuf : PVideoBuf;
  231. VideoBufSize : Longint;
  232. \end{verbatim}
  233. The \var{OldVideoBuf} contains the state of the video screen after the last
  234. screen update. The \seep{UpdateScreen} function uses this array to decide
  235. which characters on screen should be updated, and which not.
  236. Note that the \var{OldVideoBuf} array may be ignored by some drivers, so
  237. it should not be used. The Array is in the interface section of the video
  238. unit mainly so drivers that need it can make use of it.
  239. \section{Functions and Procedures}
  240. The examples in this section make use of the unit \file{vidutil}, which
  241. contains the \var{TextOut} function. This function writes a text to the
  242. screen at a given location. It looks as follows:
  243. \FPCexample{vidutil}
  244. \begin{procedure}{ClearScreen}
  245. \Declaration
  246. procedure ClearScreen;
  247. \Description
  248. \var{ClearScreen} clears the entire screen, and calls \seep{UpdateScreen}
  249. after that. This is done by writing spaces to all character cells of the
  250. video buffer in the default color (lightgray on black, color attribute \$07).
  251. \Errors
  252. None.
  253. \SeeAlso
  254. \seep{InitVideo}, \seep{UpdateScreen}
  255. \end{procedure}
  256. \FPCexample{ex3}
  257. \begin{procedure}{DefaultErrorHandler}
  258. \Declaration
  259. function DefaultErrorHandler(AErrorCode: Longint; AErrorInfo: Pointer): TErrorHandlerReturnValue;
  260. \Description
  261. \var{DefaultErrorHandler} is the default error handler used by the video
  262. driver. It simply sets the error code \var{AErrorCode} and \var{AErrorInfo}
  263. in the global variables \var{ErrorCode} and \var{ErrorInfo} and returns
  264. \var{errContinue}.
  265. \Errors
  266. None.
  267. \SeeAlso
  268. \end{procedure}
  269. \begin{procedure}{DoneVideo}
  270. \Declaration
  271. procedure DoneVideo;
  272. \Description
  273. \var{DoneVideo} disables the Video driver if the video driver is active. If
  274. the videodriver was already disabled or not yet initialized, it does
  275. nothing. Disabling the driver means it will clean up any allocated
  276. resources, possibly restore the screen in the state it was before
  277. \var{InitVideo} was called. Particularly, the \var{VideoBuf} and
  278. \var{OldVideoBuf} arrays are no longer valid after a call to
  279. \var{DoneVideo}.
  280. The \var{DoneVideo} should always be called if \var{InitVideo} was called.
  281. Failing to do so may leave the screen in an unusable state after the program
  282. exits.
  283. \Errors
  284. Normally none. If the driver reports an error, this is done through the
  285. \var{ErrorCode} variable.
  286. \SeeAlso
  287. \seep{InitVideo}
  288. \end{procedure}
  289. For an example, see most other functions.
  290. \begin{function}{GetCapabilities}
  291. \Declaration
  292. function GetCapabilities: Word;
  293. \Description
  294. \var{GetCapabilities} returns the capabilities of the current driver.
  295. It is an or-ed combination of the following constants:
  296. \begin{description}
  297. \item[cpUnderLine] The driver supports underlined characters.
  298. \item[cpBlink] The driver supports blinking characters.
  299. \item[cpColor] The driver supports colors.
  300. \item[cpChangeFont] The driver supports the setting of a screen font.
  301. Note, however, that a font setting API is not supported by the video unit.
  302. \item[cpChangeMode] The driver supports the setting of screen modes.
  303. \item[cpChangeCursor] The driver supports changing the cursor shape.
  304. \end{description}
  305. Note that the video driver should not yet be initialized to use this
  306. function. It is a property of the driver.
  307. \Errors
  308. None.
  309. \SeeAlso
  310. \seef{GetCursorType}, \seep{GetVideoDriver}
  311. \end{function}
  312. \FPCexample{ex4}
  313. \begin{function}{GetCursorType}
  314. \Declaration
  315. function GetCursorType: Word;
  316. \Description
  317. \var{GetCursorType} returns the current cursor type. It is one of the
  318. following values:
  319. \begin{description}
  320. \item[crHidden] The cursor is currently hidden.
  321. \item[crUnderLine] The cursor is currently the underline character.
  322. \item[crBlock] The cursor is currently the block character.
  323. \item[crHalfBlock] The cursur is currently a block with height of half the
  324. character cell height.
  325. \end{description}
  326. Note that not all drivers support all types of cursors.
  327. \Errors
  328. None.
  329. \SeeAlso
  330. \seep{SetCursorType}, \seef{GetCapabilities}
  331. \end{function}
  332. \FPCexample{ex5}
  333. \begin{function}{GetLockScreenCount}
  334. \Declaration
  335. Function GetLockScreenCount : integer;
  336. \Description
  337. \var{GetLockScreenCount} returns the current lock level. When the lock
  338. level is zero, a call to \seep{UpdateScreen} will actually update the
  339. screen.
  340. \Errors
  341. None.
  342. \SeeAlso
  343. \seep{LockScreenUpdate}, \seep{UnlockScreenUpdate}, \seep{UpdateScreen}
  344. \end{function}
  345. \FPCexample{ex6}
  346. \begin{procedure}{GetVideoDriver}
  347. \Declaration
  348. Procedure GetVideoDriver (Var Driver : TVideoDriver);
  349. \Declaration
  350. \var{GetVideoDriver} retrieves the current videodriver and returns it in
  351. \var{Driver}. This can be used to chain video drivers.
  352. \Errors
  353. None.
  354. \SeeAlso
  355. \seef{SetVideoDriver}
  356. \end{procedure}
  357. For an example, see the section on writing a custom video driver.
  358. \begin{procedure}{GetVideoMode}
  359. \Declaration
  360. procedure GetVideoMode(var Mode: TVideoMode);
  361. \Description
  362. \var{GetVideoMode} returns the settings of the currently active video mode.
  363. The \var{row,col} fields indicate the dimensions of the current video mode,
  364. and \var{Color} is true if the current video supports colors.
  365. \Errors
  366. None.
  367. \SeeAlso
  368. \seef{SetVideoMode}, \seef{GetVideoModeData}
  369. \end{procedure}
  370. \FPCexample{ex7}
  371. \begin{function}{GetVideoModeCount}
  372. \Declaration
  373. Function GetVideoModeCount : Word;
  374. \Description
  375. \var{GetVideoModeCount} returns the number of video modes that the current
  376. driver supports. If the driver does not support switching of modes, then 1
  377. is returned.
  378. This function can be used in conjunction with the \seef{GetVideoModeData}
  379. function to retrieve data for the supported video modes.
  380. \Errors
  381. None.
  382. \SeeAlso
  383. \seef{GetVideoModeData}, \seep{GetVideoMode}
  384. \end{function}
  385. \FPCexample{ex8}
  386. \begin{function}{GetVideoModeData}
  387. \Declaration
  388. Function GetVideoModeData(Index : Word; Var Data: TVideoMode) : Boolean;
  389. \Description
  390. \var{GetVideoModeData} returns the characteristics of the \var{Index}-th
  391. video mode in \var{Data}. \var{Index} is zero based, and has a maximum value of
  392. \var{GetVideoModeCount-1}. If the current driver does not support setting of
  393. modes (\var{GetVideoModeCount=1}) and \var{Index} is zero, the current mode
  394. is returned.
  395. The function returns \var{True} if the mode data was retrieved succesfully,
  396. \var{False} otherwise.
  397. \Errors
  398. In case \var{Index} has a wrong value, \var{False} is returned.
  399. \SeeAlso
  400. \seef{GetVideoModeCount}, \seef{SetVideoMode}, \seep{GetVideoMode}
  401. \end{function}
  402. For an example, see \seef{GetVideoModeCount}.
  403. \begin{procedure}{InitVideo}
  404. \Declaration
  405. procedure InitVideo;
  406. \Description
  407. \var{InitVideo} Initializes the video subsystem. If the video system was
  408. already initialized, it does nothing.
  409. After the driver has been initialized, the \var{VideoBuf} and \var{OldVideoBuf}
  410. pointers are initialized, based on the \var{ScreenWidth} and
  411. \var{ScreenHeight} variables. When this is done, the screen is cleared.
  412. \Errors
  413. if the driver fails to initialize, the \var{ErrorCode} variable is set.
  414. \SeeAlso
  415. \seep{DoneVideo}
  416. \end{procedure}
  417. For an example, see most other functions.
  418. \begin{procedure}{LockScreenUpdate}
  419. \Declaration
  420. Procedure LockScreenUpdate;
  421. \Description
  422. \var{LockScreenUpdate} increments the screen update lock count with one.
  423. As long as the screen update lock count is not zero, \seep{UpdateScreen}
  424. will not actually update the screen.
  425. This function can be used to optimize screen updating: If a lot of writing
  426. on the screen needs to be done (by possibly unknown functions), calling
  427. \var{LockScreenUpdate} before the drawing, and \seep{UnlockScreenUpdate}
  428. after the drawing, followed by a \seep{UpdateScreen} call, all writing will
  429. be shown on screen at once.
  430. \Errors
  431. None.
  432. \SeeAlso
  433. \seep{UpdateScreen}, \seep{UnlockScreenUpdate}, \seef{GetLockScreenCount}
  434. \end{procedure}
  435. For an example, see \seef{GetLockScreenCount}.
  436. \begin{procedure}{SetCursorPos}
  437. \Declaration
  438. procedure SetCursorPos(NewCursorX, NewCursorY: Word);
  439. \Description
  440. \var{SetCursorPos} positions the cursor on the given position: Column
  441. \var{NewCursorX} and row \var{NewCursorY}. The origin of the screen is the
  442. upper left corner, and has coordinates \var{(0,0)}.
  443. The current position is stored in the \var{CursorX} and \var{CursorY}
  444. variables.
  445. \Errors
  446. None.
  447. \SeeAlso
  448. \seep{SetCursorType}
  449. \end{procedure}
  450. \FPCexample{ex2}
  451. \begin{procedure}{SetCursorType}
  452. \Declaration
  453. procedure SetCursorType(NewType: Word);
  454. \Description
  455. \var{SetCursorType} sets the cursor to the type specified in \var{NewType}.
  456. \begin{description}
  457. \item[crHidden] the cursor is not visible.
  458. \item[crUnderLine] the cursor is a small underline character (usually
  459. denoting insert mode).
  460. \item[crBlock] the cursor is a block the size of a screen cell (usually
  461. denoting overwrite mode).
  462. \item[crHalfBlock] the cursor is a block half the size of a screen cell.
  463. \end{description}
  464. \Errors
  465. None.
  466. \SeeAlso
  467. \seep{SetCursorPos}
  468. \end{procedure}
  469. \begin{function}{SetVideoDriver}
  470. \Declaration
  471. Function SetVideoDriver (Const Driver : TVideoDriver) : Boolean;
  472. \Description
  473. \var{SetVideoDriver} sets the videodriver to be used to \var{Driver}. If
  474. the current videodriver is initialized (after a call to \var{InitVideo})
  475. then it does nothing and returns \var{False}.
  476. A new driver can only be installed if the previous driver was not yet
  477. activated (i.e. before a call to \seep{InitVideo}) or after it was
  478. deactivated (i.e after a call to \var{DoneVideo}).
  479. For more information about installing a videodriver, see \sees{viddriver}.
  480. \Errors
  481. If the current driver is initialized, then \var{False} is returned.
  482. \SeeAlso
  483. The example video driver in \sees{viddriver}
  484. \end{function}
  485. For an example, see the section on writing a custom video driver.
  486. \begin{function}{SetVideoMode}
  487. \Declaration
  488. Function SetVideoMode(Mode: TVideoMode) : Boolean;
  489. \Description
  490. \var{SetVideoMode} sets the video mode to the mode specified in \var{Mode}:
  491. \begin{verbatim}
  492. TVideoMode = record
  493. Col,Row : Word;
  494. Color : Boolean;
  495. end;
  496. \end{verbatim}
  497. If the call was succesful, then the screen will have \var{Col} columns and
  498. \var{Row} rows, and will be displaying in color if \var{Color} is
  499. \var{True}.
  500. The function returns \var{True} if the mode was set succesfully, \var{False}
  501. otherwise.
  502. Note that the video mode may not always be set. E.g. a console on Linux
  503. or a telnet session cannot always set the mode. It is important to check
  504. the error value returned by this function if it was not succesful.
  505. The mode can be set when the video driver has not yet been initialized
  506. (i.e. before \seep{InitVideo} was called) In that case, the video mode will
  507. be stored, and after the driver was initialized, an attempt will be made to
  508. set the requested mode. Changing the video driver before the call to
  509. \var{InitVideo} will clear the stored video mode.
  510. To know which modes are valid, use the \seef{GetVideoModeCount} and
  511. \seef{GetVideoModeData} functions. To retrieve the current video mode,
  512. use the \seep{GetVideoMode} procedure.
  513. \Errors
  514. If the specified mode cannot be set, then \var{errVioNoSuchMode} may be set
  515. in \var{ErrorCode}
  516. \SeeAlso
  517. \seef{GetVideoModeCount}
  518. \seef{GetVideoModeData}
  519. \seep{GetVideoMode}
  520. \end{function}
  521. \begin{procedure}{UnlockScreenUpdate}
  522. \Declaration
  523. Procedure UnlockScreenUpdate;
  524. \Description
  525. \var{UnlockScreenUpdate} decrements the screen update lock count with one if
  526. it is larger than zero. When the lock count reaches zero, the
  527. \seep{UpdateScreen} will actually update the screen. No screen update will
  528. be performed as long as the screen update lock count is nonzero. This
  529. mechanism can be used to increase screen performance in case a lot of
  530. writing is done.
  531. It is important to make sure that each call to \seep{LockScreenUpdate} is
  532. matched by exactly one call to \var{UnlockScreenUpdate}
  533. \Errors
  534. None.
  535. \SeeAlso
  536. \seep{LockScreenUpdate}, \seef{GetLockScreenCount}, \seep{UpdateScreen}
  537. \end{procedure}
  538. For an example, see \seef{GetLockScreenCount}.
  539. \begin{procedure}{UpdateScreen}
  540. \Declaration
  541. procedure UpdateScreen(Force: Boolean);
  542. \Description
  543. \var{UpdateScreen} synchronizes the actual screen with the contents
  544. of the \var{VideoBuf} internal buffer. The parameter \var{Force}
  545. specifies whether the whole screen has to be redrawn (\var{Force=True})
  546. or only parts that have changed since the last update of the screen.
  547. The \var{Video} unit keeps an internal copy of the screen as it last
  548. wrote it to the screen (in the \var{OldVideoBuf} array). The current
  549. contents of \var{VideoBuf} are examined to see what locations on the
  550. screen need to be updated. On slow terminals (e.g. a \linux telnet
  551. session) this mechanism can speed up the screen redraw considerably.
  552. \Errors
  553. None.
  554. \SeeAlso
  555. \seep{ClearScreen}
  556. \end{procedure}
  557. For an example, see most other functions.
  558. \section{Writing a custom video driver}
  559. \label{se:viddriver}
  560. Writing a custom video driver is not difficult, and generally means
  561. implementing a couple of functions, which whould be registered with
  562. the \seef{SetVideoDriver} function. The various functions that can be
  563. implemented are located in the \var{TVideoDriver} record:
  564. \begin{verbatim}
  565. TVideoDriver = Record
  566. InitDriver : Procedure;
  567. DoneDriver : Procedure;
  568. UpdateScreen : Procedure(Force : Boolean);
  569. ClearScreen : Procedure;
  570. SetVideoMode : Function (Const Mode : TVideoMode) : Boolean;
  571. GetVideoModeCount : Function : Word;
  572. GetVideoModeData : Function(Index : Word; Var Data : TVideoMode) : Boolean;
  573. SetCursorPos : procedure (NewCursorX, NewCursorY: Word);
  574. GetCursorType : function : Word;
  575. SetCursorType : procedure (NewType: Word);
  576. GetCapabilities : Function : Word;
  577. end;
  578. \end{verbatim}
  579. Not all of these functions must be implemented. In fact, the only absolutely
  580. necessary function to write a functioning driver is the \var{UpdateScreen}
  581. function. The general calls in the \file{Video} unit will check which
  582. functionality is implemented by the driver.
  583. The functionality of these calls is the same as the functionality of the
  584. calls in the video unit, so the expected behaviour can be found in the
  585. previous section. Some of the calls, however, need some additional remarks.
  586. \begin{description}
  587. \item[InitDriver] Called by \var{InitVideo}, this function should initialize
  588. any data structures needed for the functionality of the driver, maybe do some
  589. screen initializations. The function is guaranteed to be called only once; It
  590. can only be called again after a call to \var{DoneVideo}. The variables
  591. \var{ScreenWidth} and \var{ScreenHeight} should be initialized correctly
  592. after a call to this function, as the \var{InitVideo} call will initialize
  593. the \var{VideoBuf} and \var{OldVideoBuf} arrays based on their values.
  594. \item[DoneDriver] This should clean up any structures that have been
  595. initialized in the \var{InitDriver} function. It should possibly also
  596. restore the screen as it was before the driver was initialized. The VideoBuf
  597. and \var{OldVideoBuf} arrays will be disposed of by the general \var{DoneVideo}
  598. call.
  599. \item[UpdateScreen] This is the only required function of the driver. It
  600. should update the screen based on the \var{VideoBuf} array's contents. It
  601. can optimize this process by comparing the values with values in the
  602. \var{OldVideoBuf} array. After updating the screen, the \var{UpdateScreen}
  603. procedure should update the \var{OldVideoBuf} by itself. If the \var{Force}
  604. parameter is \var{True}, the whole screen should be updated, not just the
  605. changed values.
  606. \item[ClearScreen] If there is a faster way to clear the screen than to
  607. write spaces in all character cells, then it can be implemented here. If the
  608. driver does not implement this function, then the general routines will
  609. write spaces in all video cells, and will call \var{UpdateScreen(True)}.
  610. \item[SetVideoMode] Should set the desired video mode, if available. It
  611. should return \var{True} if the mode was set, \var{False} if not.
  612. \item[GetVideoModeCount] Should return the number of supported video modes.
  613. If no modes are supported, this function should not be implemented; the
  614. general routines will return 1. (for the current mode)
  615. \item[GetVideoModeData] Should return the data for the \var{Index}-th mode;
  616. \var{Index} is zero based. The function should return true if the data was
  617. returned correctly, false if \var{Index} contains an invalid index.
  618. If this is not implemented, then the general routine will return the current
  619. video mode when \var{Index} equals 0.
  620. \item[GetCapabilities] If this function is not implemented, zero (i.e.
  621. no capabilities) will be returned by the general function.
  622. \end{description}
  623. The following unit shows how to override a video driver, with a driver
  624. that writes debug information to a file.
  625. \FPCexample{viddbg}
  626. The unit can be used in any of the demonstration programs, by simply
  627. including it in the \var{uses} clause. Setting \var{DetailedVideoLogging} to
  628. \var{True} will create a more detailed log (but will also slow down
  629. functioning)