keyboard.tex 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  1. %
  2. % $Id$
  3. % This file is part of the FPC documentation.
  4. % Copyright (C) 2001, 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 Keyboard unit
  25. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  26. \chapter{The KEYBOARD unit}
  27. \FPCexampledir{kbdex}
  28. The \file{KeyBoard} unit implements a keyboard access layer which is system
  29. independent. It can be used to poll the keyboard state and wait for certain
  30. events. Waiting for a keyboard event can be done with the \seef{GetKeyEvent}
  31. function, which will return a driver-dependent key event. This key event can
  32. be translated to a interpretable event by the \seef{TranslateKeyEvent}
  33. function. The result of this function can be used in the other event
  34. examining functions.
  35. A custom keyboard driver can be installed using the \seef{SetKeyboardDriver}
  36. function. The current keyboard driver can be retrieved using the
  37. \seep{GetKeyboardDriver} function. The last section of this chapter
  38. demonstrates how to make a keyboard driver.
  39. \section{Constants, Type and variables }
  40. \subsection{Constants}
  41. The following constants define some error constants, which may be returned
  42. by the keyboard functions.
  43. \begin{verbatim}
  44. errKbdBase = 1010;
  45. errKbdInitError = errKbdBase + 0;
  46. errKbdNotImplemented = errKbdBase + 1;
  47. \end{verbatim}
  48. The following constants denote special keyboard keys. The first constants
  49. denote the function keys:
  50. \begin{verbatim}
  51. const
  52. kbdF1 = $FF01;
  53. kbdF2 = $FF02;
  54. kbdF3 = $FF03;
  55. kbdF4 = $FF04;
  56. kbdF5 = $FF05;
  57. kbdF6 = $FF06;
  58. kbdF7 = $FF07;
  59. kbdF8 = $FF08;
  60. kbdF9 = $FF09;
  61. kbdF10 = $FF0A;
  62. kbdF11 = $FF0B;
  63. kbdF12 = $FF0C;
  64. kbdF13 = $FF0D;
  65. kbdF14 = $FF0E;
  66. kbdF15 = $FF0F;
  67. kbdF16 = $FF10;
  68. kbdF17 = $FF11;
  69. kbdF18 = $FF12;
  70. kbdF19 = $FF13;
  71. kbdF20 = $FF14;
  72. \end{verbatim}
  73. Constants \$15 till \$1F are reserved for future function keys. The
  74. following constants denote the cursor movement keys:
  75. \begin{verbatim}
  76. kbdHome = $FF20;
  77. kbdUp = $FF21;
  78. kbdPgUp = $FF22;
  79. kbdLeft = $FF23;
  80. kbdMiddle = $FF24;
  81. kbdRight = $FF25;
  82. kbdEnd = $FF26;
  83. kbdDown = $FF27;
  84. kbdPgDn = $FF28;
  85. kbdInsert = $FF29;
  86. kbdDelete = $FF2A;
  87. \end{verbatim}
  88. Constants \$2B till \$2F are reserved for future keypad keys.
  89. The following flags are also defined:
  90. \begin{verbatim}
  91. kbASCII = $00;
  92. kbUniCode = $01;
  93. kbFnKey = $02;
  94. kbPhys = $03;
  95. kbReleased = $04;
  96. \end{verbatim}
  97. They can be used to check what kind of data a key event contains.
  98. The following shift-state flags can be used to determine the shift state of
  99. a key (i.e. which of the SHIFT, ALT and CTRL keys were pressed
  100. simultaneously with a key):
  101. \begin{verbatim}
  102. kbLeftShift = 1;
  103. kbRightShift = 2;
  104. kbShift = kbLeftShift or kbRightShift;
  105. kbCtrl = 4;
  106. kbAlt = 8;
  107. \end{verbatim}
  108. The following constant strings are used in the key name functions
  109. \seef{FunctionKeyName} and \seef{KeyEventToString}:
  110. \begin{verbatim}
  111. SShift : Array [1..3] of string[5] = ('SHIFT','CTRL','ALT');
  112. LeftRight : Array [1..2] of string[5] = ('LEFT','RIGHT');
  113. UnicodeChar : String = 'Unicode character ';
  114. SScanCode : String = 'Key with scancode ';
  115. SUnknownFunctionKey : String = 'Unknown function key : ';
  116. SAnd : String = 'AND';
  117. SKeyPad : Array [0..($FF2F-kbdHome)] of string[6] =
  118. ('Home','Up','PgUp','Left',
  119. 'Middle','Right','End','Down',
  120. 'PgDn','Insert','Delete','',
  121. '','','','');
  122. \end{verbatim}
  123. They can be changed to localize the key names when needed.
  124. \subsection{Types}
  125. The \var{TKeyEvent} type is the base type for all keyboard events:
  126. \begin{verbatim}
  127. TKeyEvent = Longint;
  128. \end{verbatim}
  129. The key stroke is encoded in the 4 bytes of the \var{TKeyEvent} type.
  130. The various fields of the key stroke encoding can be obtained by typecasting
  131. the \var{TKeyEvent} type to the \var{TKeyRecord} type:
  132. \begin{verbatim}
  133. TKeyRecord = packed record
  134. KeyCode : Word;
  135. ShiftState, Flags : Byte;
  136. end;
  137. \end{verbatim}
  138. The structure of a \var{TKeyRecord} structure is explained in \seet{keyevent}.
  139. \begin{FPCltable}{lp{10cm}}{Structure of TKeyRecord}{keyevent}
  140. Field & Meaning \\ \hline
  141. KeyCode & Depending on \var{flags} either the physical representation of a key
  142. (under DOS scancode, ascii code pair), or the translated
  143. ASCII/unicode character.\\
  144. ShiftState & Shift-state when this key was pressed (or shortly after) \\
  145. Flags & Determine how to interpret \var{KeyCode} \\ \hline
  146. \end{FPCltable}
  147. The shift-state can be checked using the various shift-state constants,
  148. and the flags in the last byte can be checked using one of the
  149. kbASCII, kbUniCode, kbFnKey, kbPhys, kbReleased constants.
  150. If there are two keys returning the same char-code, there's no way to find
  151. out which one was pressed (Gray+ and Simple+). If it needs to be known which
  152. was pressed, the untranslated keycodes must be used, but these are system
  153. dependent. System dependent constants may be defined to cover those, with
  154. possibily having the same name (but different value).
  155. The \var{TKeyboardDriver} record can be used to install a custom keyboard
  156. driver with the \seef{SetKeyboardDriver} function:
  157. \begin{verbatim}
  158. Type
  159. TKeyboardDriver = Record
  160. InitDriver : Procedure;
  161. DoneDriver : Procedure;
  162. GetKeyEvent : Function : TKeyEvent;
  163. PollKeyEvent : Function : TKeyEvent;
  164. GetShiftState : Function : Byte;
  165. TranslateKeyEvent : Function (KeyEvent: TKeyEvent): TKeyEvent;
  166. TranslateKeyEventUniCode: Function (KeyEvent: TKeyEvent): TKeyEvent;
  167. end;
  168. \end{verbatim}
  169. The various fields correspond to the different functions of the keyboard unit
  170. interface. For more information about this record see \sees{kbddriver}
  171. \section{Functions and Procedures}
  172. \begin{procedure}{DoneKeyboard}
  173. \Declaration
  174. Procedure DoneKeyboard;
  175. \Description
  176. \var{DoneKeyboard} de-initializes the keyboard interface if the keyboard
  177. driver is active. If the keyboard driver is not active, the function does
  178. nothing.
  179. This will cause the keyboard driver to clear up any allocated memory,
  180. or restores the console or terminal the program was running in to its
  181. initial state before the call to \seep{InitKeyBoard}. This function should
  182. be called on program exit. Failing to do so may leave the terminal or
  183. console window in an unusable state. Its exact action depends on the
  184. platform on which the program is running.
  185. \Errors
  186. None.
  187. \SeeAlso
  188. \seep{InitKeyBoard}
  189. \end{procedure}
  190. For an example, see most other functions.
  191. \begin{function}{FunctionKeyName}
  192. \Declaration
  193. Function FunctionKeyName (KeyCode : Word) : String;
  194. \Description
  195. \var{FunctionKeyName} returns a string representation of the function key
  196. with code \var{KeyCode}. This can be an actual function key, or one of the
  197. cursor movement keys.
  198. \Errors
  199. In case \var{KeyCode} does not contain a function code, the
  200. \var{SUnknownFunctionKey} string is returned, appended with the
  201. \var{KeyCode}.
  202. \SeeAlso
  203. \seef{ShiftStateToString}
  204. \seef{KeyEventToString}
  205. \end{function}
  206. \FPCexample{ex8}
  207. \begin{procedure}{GetKeyboardDriver}
  208. \Declaration
  209. Procedure GetKeyboardDriver (Var Driver : TKeyboardDriver);
  210. \Description
  211. \var{GetKeyBoardDriver} returns in \var{Driver} the currently active
  212. keyboard driver. This function can be used to enhance an existing
  213. keyboarddriver.
  214. For more information on getting and setting the keyboard driver
  215. \sees{kbddriver}.
  216. \Errors
  217. None.
  218. \SeeAlso
  219. \seef{SetKeyboardDriver}
  220. \end{procedure}
  221. \begin{function}{GetKeyEvent}
  222. \Declaration
  223. function GetKeyEvent: TKeyEvent;
  224. \Description
  225. \var{GetKeyEvent} returns the last keyevent if one was stored in
  226. \var{PendingKeyEvent}, or waits for one if none is available.
  227. A non-blocking version is available in \seef{PollKeyEvent}.
  228. The returned key is encoded as a \var{TKeyEvent} type variable, and
  229. is normally the physical key scan code, (the scan code is driver
  230. dependent) which can be translated with one of the translation
  231. functions \seef{TranslateKeyEvent} or \seef{TranslateKeyEventUniCode}.
  232. See the types section for a description of how the key is described.
  233. \Errors
  234. If no key became available, 0 is returned.
  235. \SeeAlso
  236. \seep{PutKeyEvent}, \seef{PollKeyEvent}, \seef{TranslateKeyEvent},
  237. \seef{TranslateKeyEventUniCode}
  238. \end{function}
  239. \FPCexample{ex1}
  240. \begin{function}{GetKeyEventChar}
  241. \Declaration
  242. function GetKeyEventChar(KeyEvent: TKeyEvent): Char;
  243. \Description
  244. \var{GetKeyEventChar} returns the charcode part of the given
  245. \var{KeyEvent}, if it contains a translated character key
  246. keycode. The charcode is simply the ascii code of the
  247. character key that was pressed.
  248. It returns the null character if the key was not a character key, but e.g. a
  249. function key.
  250. \Errors
  251. None.
  252. \SeeAlso
  253. \seef{GetKeyEventUniCode},
  254. \seef{GetKeyEventShiftState},
  255. \seef{GetKeyEventFlags},
  256. \seef{GetKeyEventCode},
  257. \seef{GetKeyEvent}
  258. \end{function}
  259. For an example, see \seef{GetKeyEvent}
  260. \begin{function}{GetKeyEventCode}
  261. \Declaration
  262. function GetKeyEventCode(KeyEvent: TKeyEvent): Word;
  263. \Description
  264. \var{GetKeyEventCode} returns the translated function keycode part of
  265. the given KeyEvent, if it contains a translated function key.
  266. If the key pressed was not a function key, the null character is returned.
  267. \Errors
  268. None.
  269. \SeeAlso
  270. \seef{GetKeyEventUniCode},
  271. \seef{GetKeyEventShiftState},
  272. \seef{GetKeyEventFlags},
  273. \seef{GetKeyEventChar},
  274. \seef{GetKeyEvent}
  275. \end{function}
  276. \FPCexample{ex2}
  277. \begin{function}{GetKeyEventFlags}
  278. \Declaration
  279. function GetKeyEventFlags(KeyEvent: TKeyEvent): Byte;
  280. \Description
  281. \var{GetKeyEventFlags} returns the flags part of the given
  282. \var{KeyEvent}.
  283. \Errors
  284. None.
  285. \SeeAlso
  286. \seef{GetKeyEventUniCode},
  287. \seef{GetKeyEventShiftState},
  288. \seef{GetKeyEventCode},
  289. \seef{GetKeyEventChar},
  290. \seef{GetKeyEvent}
  291. \end{function}
  292. For an example, see \seef{GetKeyEvent}
  293. \begin{function}{GetKeyEventShiftState}
  294. \Declaration
  295. function GetKeyEventShiftState(KeyEvent: TKeyEvent): Byte;
  296. \Description
  297. \var{GetKeyEventShiftState} returns the shift-state values of
  298. the given \var{KeyEvent}. This can be used to detect which of the modifier
  299. keys \var{Shift}, \var{Alt} or \var{Ctrl} were pressed. If none were
  300. pressed, zero is returned.
  301. Note that this function does not always return expected results;
  302. In a unix X-Term, the modifier keys do not always work.
  303. \Errors
  304. None.
  305. \SeeAlso
  306. \seef{GetKeyEventUniCode},
  307. \seef{GetKeyEventFlags},
  308. \seef{GetKeyEventCode},
  309. \seef{GetKeyEventChar},
  310. \seef{GetKeyEvent}
  311. \end{function}
  312. \FPCexample{ex3}
  313. \begin{function}{GetKeyEventUniCode}
  314. \Declaration
  315. function GetKeyEventUniCode(KeyEvent: TKeyEvent): Word;
  316. \Description
  317. \var{GetKeyEventUniCode} returns the unicode part of the
  318. given \var{KeyEvent} if it contains a translated unicode
  319. character.
  320. \Errors
  321. None.
  322. \SeeAlso
  323. \seef{GetKeyEventShiftState},
  324. \seef{GetKeyEventFlags},
  325. \seef{GetKeyEventCode},
  326. \seef{GetKeyEventChar},
  327. \seef{GetKeyEvent}
  328. \end{function}
  329. No example available yet.
  330. \begin{procedure}{InitKeyBoard}
  331. \Declaration
  332. procedure InitKeyboard;
  333. \Description
  334. \var{InitKeyboard} initializes the keyboard driver.
  335. If the driver is already active, it does nothing. When the driver is
  336. initialized, it will do everything necessary to ensure the functioning of
  337. the keyboard, including allocating memory, initializing the terminal etc.
  338. This function should be called once, before using any of the
  339. keyboard functions. When it is called, the \seep{DoneKeyboard} function
  340. should also be called before exiting the program or changing the keyboard
  341. driver with \seef{SetKeyboardDriver}.
  342. \Errors
  343. None.
  344. \SeeAlso
  345. \seep{DoneKeyboard}, \seef{SetKeyboardDriver}
  346. \end{procedure}
  347. For an example, see most other functions.
  348. \begin{function}{IsFunctionKey}
  349. \Declaration
  350. function IsFunctionKey(KeyEvent: TKeyEvent): Boolean;
  351. \Description
  352. \var{IsFunctionKey} returns \var{True} if the given key event
  353. in \var{KeyEvent} was a function key or not.
  354. \Errors
  355. None.
  356. \SeeAlso
  357. \seef{GetKeyEvent}
  358. \end{function}
  359. \FPCexample{ex7}
  360. \begin{function}{KeyEventToString}
  361. \Declaration
  362. Function KeyEventToString(KeyEvent : TKeyEvent) : String;
  363. \Description
  364. \var{KeyEventToString} translates the key event in \var{KeyEvent} to a
  365. human-readable description of the pressed key. It will use the constants
  366. described in the constants section to do so.
  367. \Errors
  368. If an unknown key is passed, the scancode is returned, prefixed with the
  369. \var{SScanCode} string.
  370. \SeeAlso
  371. \seef{FunctionKeyName}, \seef{ShiftStateToString}
  372. \end{function}
  373. For an example, see most other functions.
  374. \begin{function}{PollKeyEvent}
  375. \Declaration
  376. function PollKeyEvent: TKeyEvent;
  377. \Description
  378. \var{PollKeyEvent} checks whether a key event is available,
  379. and returns it if one is found. If no event is pending,
  380. it returns 0.
  381. Note that this does not remove the key from the pending keys.
  382. The key should still be retrieved from the pending key events
  383. list with the \seef{GetKeyEvent} function.
  384. \Errors
  385. None.
  386. \SeeAlso
  387. \seep{PutKeyEvent}, \seef{GetKeyEvent}
  388. \end{function}
  389. \FPCexample{ex4}
  390. \begin{function}{PollShiftStateEvent}
  391. \Declaration
  392. function PollShiftStateEvent: TKeyEvent;
  393. \Description
  394. \var{PollShiftStateEvent} returns the current shiftstate in a
  395. keyevent. This will return 0 if there is no key event pending.
  396. \Errors
  397. None.
  398. \SeeAlso
  399. \seef{PollKeyEvent}, \seef{GetKeyEvent}
  400. \end{function}
  401. \FPCexample{ex6}
  402. \begin{procedure}{PutKeyEvent}
  403. \Declaration
  404. procedure PutKeyEvent(KeyEvent: TKeyEvent);
  405. \Description
  406. \var{PutKeyEvent} adds the given \var{KeyEvent} to the input
  407. queue. Please note that depending on the implementation this
  408. can hold only one value, i.e. when calling \var{PutKeyEvent}
  409. multiple times, only the last pushed key will be remembered.
  410. \Errors
  411. None
  412. \SeeAlso
  413. \seef{PollKeyEvent}, \seef{GetKeyEvent}
  414. \end{procedure}
  415. \FPCexample{ex5}
  416. \begin{function}{SetKeyboardDriver}
  417. \Declaration
  418. Function SetKeyboardDriver (Const Driver : TKeyboardDriver) : Boolean;
  419. \Description
  420. \var{SetKeyBoardDriver} sets the keyboard driver to \var{Driver}, if the
  421. current keyboard driver is not yet initialized. If the current
  422. keyboard driver is initialized, then \var{SetKeyboardDriver} does
  423. nothing. Before setting the driver, the currently active driver should
  424. be disabled with a call to \seep{DoneKeyboard}.
  425. The function returns \var{True} if the driver was set, \var{False} if not.
  426. For more information on setting the keyboard driver, see \sees{kbddriver}.
  427. \Errors
  428. None.
  429. \SeeAlso
  430. \seep{GetKeyboardDriver}, \seep{DoneKeyboard}.
  431. \end{function}
  432. \begin{function}{ShiftStateToString}
  433. \Declaration
  434. Function ShiftStateToString(KeyEvent : TKeyEvent; UseLeftRight : Boolean) : String;
  435. \Description
  436. \var{ShiftStateToString} returns a string description of the shift state
  437. of the key event \var{KeyEvent}. This can be an empty string.
  438. The shift state is described using the strings in the \var{SShift} constant.
  439. \Errors
  440. None.
  441. \SeeAlso
  442. \seef{FunctionKeyName}, \seef{KeyEventToString}
  443. \end{function}
  444. For an example, see \seef{PollShiftStateEvent}.
  445. \begin{function}{TranslateKeyEvent}
  446. \Declaration
  447. function TranslateKeyEvent(KeyEvent: TKeyEvent): TKeyEvent;
  448. \Description
  449. \var{TranslateKeyEvent} performs ASCII translation of the \var{KeyEvent}.
  450. It translates a physical key to a function key if the key is a function key,
  451. and translates the physical key to the ordinal of the ascii character if
  452. there is an equivalent character key.
  453. \Errors
  454. None.
  455. \SeeAlso
  456. \seef{TranslateKeyEventUniCode}
  457. \end{function}
  458. For an example, see \seef{GetKeyEvent}
  459. \begin{function}{TranslateKeyEventUniCode}
  460. \Declaration
  461. function TranslateKeyEventUniCode(KeyEvent: TKeyEvent): TKeyEvent;
  462. \Description
  463. \var{TranslateKeyEventUniCode} performs Unicode translation of the
  464. \var{KeyEvent}. It is not yet implemented for all platforms.
  465. \Errors
  466. If the function is not yet implemented, then the \var{ErrorCode} of the
  467. \file{system} unit will be set to \var{errKbdNotImplemented}
  468. \SeeAlso
  469. \end{function}
  470. No example available yet.
  471. \section{Keyboard scan codes}
  472. Special physical keys are encoded with the DOS scan codes for these keys
  473. in the second byte of the \var{TKeyEvent} type.
  474. A complete list of scan codes can be found in \seet{keyscans}. This is the
  475. list of keys that is used by the default key event translation mechanism.
  476. When writing a keyboard driver, either these constants should be returned
  477. by the various key event functions, or the \var{TranslateKeyEvent} hook
  478. should be implemented by the driver.
  479. \begin{FPCltable}{llllll}{Physical keys scan codes}{keyscans}
  480. Code & Key & Code & Key & Code & Key\\ \hline
  481. \input{keys.tex}
  482. \hline
  483. \end{FPCltable}
  484. A list of scan codes for special keys and combinations with the SHIFT, ALT
  485. and CTRL keys can be found in \seet{speckeys}; They are for quick reference
  486. only.
  487. \begin{FPCltable}{llccc}{Special keys scan codes}{speckeys}
  488. Key & Code & SHIFT-Key & CTRL-Key & Alt-Key \\ \hline
  489. NoKey & 00 & & & \\
  490. F1 & 3B & 54 & 5E & 68 \\
  491. F2 & 3C & 55 & 5F & 69 \\
  492. F3 & 3D & 56 & 60 & 6A \\
  493. F4 & 3E & 57 & 61 & 6B \\
  494. F5 & 3F & 58 & 62 & 6C \\
  495. F6 & 40 & 59 & 63 & 6D \\
  496. F7 & 41 & 5A & 64 & 6E \\
  497. F8 & 42 & 5A & 65 & 6F \\
  498. F9 & 43 & 5B & 66 & 70 \\
  499. F10 & 44 & 5C & 67 & 71 \\
  500. F11 & 85 & 87 & 89 & 8B \\
  501. F12 & 86 & 88 & 8A & 8C \\
  502. Home & 47 & & 77 & 97 \\
  503. Up & 48 & & 8D & 98 \\
  504. PgUp & 49 & & 84 & 99 \\
  505. Left & 4B & & 73 & 9B \\
  506. Center & 4C & & 8F & \\
  507. Right & 4D & & 74 & 9D \\
  508. end & 4F & & 75 & 9F \\
  509. Down & 50 & & 91 & A0 \\
  510. PgDn & 51 & & 76 & A1 \\
  511. Ins & 52 & 05 & 04 & A2 \\
  512. Del & 53 & 07 & 06 & A3 \\
  513. Tab & 8 & 0F & 94 & A5 \\
  514. GreyPlus & & & 90 & 4E \\
  515. \hline
  516. \end{FPCltable}
  517. \section{Writing a keyboard driver}
  518. \label{se:kbddriver}
  519. Writing a keyboard driver means that hooks must be created for most of the
  520. keyboard unit functions. The \var{TKeyBoardDriver} record contains a field
  521. for each of the possible hooks:
  522. \begin{verbatim}
  523. TKeyboardDriver = Record
  524. InitDriver : Procedure;
  525. DoneDriver : Procedure;
  526. GetKeyEvent : Function : TKeyEvent;
  527. PollKeyEvent : Function : TKeyEvent;
  528. GetShiftState : Function : Byte;
  529. TranslateKeyEvent : Function (KeyEvent: TKeyEvent): TKeyEvent;
  530. TranslateKeyEventUniCode: Function (KeyEvent: TKeyEvent): TKeyEvent;
  531. end;
  532. \end{verbatim}
  533. The meaning of these hooks is explained below:
  534. \begin{description}
  535. \item[InitDriver] Called to initialize and enable the driver.
  536. Guaranteed to be called only once. This should initialize all needed things
  537. for the driver.
  538. \item[DoneDriver] Called to disable and clean up the driver. Guaranteed to be
  539. called after a call to \var{initDriver}. This should clean up all
  540. things initialized by \var{InitDriver}.
  541. \item[GetKeyEvent] Called by \seef{GetKeyEvent}. Must wait for and return the
  542. next key event. It should NOT store keys.
  543. \item[PollKeyEvent] Called by \seef{PollKeyEvent}. It must return the next key
  544. event if there is one. Should not store keys.
  545. \item[GetShiftState] Called by \seef{PollShiftStateEvent}. Must return the current
  546. shift state.
  547. \item[TranslateKeyEvent] Should translate a raw key event to a cOrrect
  548. key event, i.e. should fill in the shiftstate and convert function key
  549. scancodes to function key keycodes. If the
  550. \var{TranslateKeyEvent} is not filled in, a default translation function
  551. will be called which converts the known scancodes from the tables in the
  552. previous section to a correct keyevent.
  553. \item[TranslateKeyEventUniCode] Should translate a key event to a unicode key
  554. representation.
  555. \end{description}
  556. Strictly speaking, only the \var{GetKeyEvent} and \var{PollKeyEvent}
  557. hooks must be implemented for the driver to function correctly.
  558. The following unit demonstrates how a keyboard driver can be installed.
  559. It takes the installed driver, and hooks into the \var{GetKeyEvent}
  560. function to register and log the key events in a file. This driver
  561. can work on top of any other driver, as long as it is inserted in the
  562. \var{uses} clause {\em after} the real driver unit, and the real driver unit
  563. should set the driver record in its initialization section.
  564. \FPCexample{logkeys}
  565. The following program demonstrates the use of the unit:
  566. \FPCexample{ex9}
  567. Note that with a simple extension of this unit could be used to make a
  568. driver that is capable of recording and storing a set of keyboard strokes,
  569. and replaying them at a later time, so a 'keyboard macro' capable driver.
  570. This driver could sit on top of any other driver.