%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The Keyboard unit
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{The KEYBOARD unit}
\FPCexampledir{kbdex}

The \file{KeyBoard} unit implements a keyboard access layer which is system
independent. It can be used to poll the keyboard state and wait for certaine
events. 

\section{Constants, Type and variables }

\subsection{Constants}

The following constants define some error constants, which may be returned
by the keyboard functions.
\begin{verbatim}
errKbdBase           = 1010;
errKbdInitError      = errKbdBase + 0;
errKbdNotImplemented = errKbdBase + 1;
\end{verbatim}
The following constants denote special keyboard keys. The first constants
denote the function keys:
\begin{verbatim}
const
  kbdF1        = $FF01;
  kbdF2        = $FF02;
  kbdF3        = $FF03;
  kbdF4        = $FF04;
  kbdF5        = $FF05;
  kbdF6        = $FF06;
  kbdF7        = $FF07;
  kbdF8        = $FF08;
  kbdF9        = $FF09;
  kbdF10       = $FF0A;
  kbdF11       = $FF0B;
  kbdF12       = $FF0C;
  kbdF13       = $FF0D;
  kbdF14       = $FF0E;
  kbdF15       = $FF0F;
  kbdF16       = $FF10;
  kbdF17       = $FF11;
  kbdF18       = $FF12;
  kbdF19       = $FF13;
  kbdF20       = $FF14;
\end{verbatim}
Constants  \$15 till \$1F are reserved for future function keys. The
following constants denote the curso movement keys:
\begin{verbatim}
  kbdHome      = $FF20;
  kbdUp        = $FF21;
  kbdPgUp      = $FF22;
  kbdLeft      = $FF23;
  kbdMiddle    = $FF24;
  kbdRight     = $FF25;
  kbdEnd       = $FF26;
  kbdDown      = $FF27;
  kbdPgDn      = $FF28;

  kbdInsert    = $FF29;
  kbdDelete    = $FF2A;
\end{verbatim}
Constants \$2B till \$2F are reserved for future keypad key.
The following flags are also defined:
\begin{verbatim}
  kbASCII       = $00;
  kbUniCode     = $01;
  kbFnKey       = $02;
  kbPhys        = $03;
  kbReleased    = $04;
\end{verbatim}
They can be used to check And the following shift-state flags:
\begin{verbatim}
  kbLeftShift   = 1;
  kbRightShift  = 2;
  kbShift       = kbLeftShift or kbRightShift;
  kbCtrl        = 4;
  kbAlt         = 8;
\end{verbatim}
\subsection{Types}
The \var{TKeyEvent} type is the base type for all keyboard events:
\begin{verbatim}
  TKeyEvent = Longint;
\end{verbatim}
The structure of a \var{TKeyEvent} is explained in \seet{keyevent}.
\begin{FPCltable}{ll}{Structure of TKeyEvent}{keyevent}
Bytes & Meaning \\ \hline
2 bytes & Depending on \var{flags} either the physical representation of a key
         (under DOS scancode, ascii code pair), or the translated
           ASCII/unicode character.\\
1 byte & shift-state when this key was pressed (or shortly after) \\
1 byte & \var{flags}, determining how to read the first two bytes \\ \hline.
\end{FPCltable}
The shift-state can be checked using the various shift-state constants, 
and the flags in the last byte can be checked using one of the
kbASCII,kbUniCode,kbFnKey,kbPhys, kbReleased constants.

If there are two keys returning the same char-code, there's no way to find
out which one was pressed (Gray+ and Simple+). If it needs to be known which
was pressed, the untranslated keycodes must be used, but these are system
dependent. System dependent constants may be defined to cover those, with
possibily having the same name (but different value).
\subsection{Variables}
The following variable contains any pending (i.e. not yet consumed) keyboard
event:
\begin{verbatim}
var
  PendingKeyEvent : TKeyEvent;
\end{verbatim}

\section{Functions and Procedures}

\begin{procedure}{DoneKeyboard}
\Declaration
Procedure DoneKeyboard;
\Description
\var{DoneKeyboard} de-initializes the keyboard interface. 
It clears up any allocated memory, or restores the console or terminal 
the program was running in to its initial state. This function should 
be called on program exit. Failing to do so may leave the terminal or
console window in an unusable state. Its exact action depends on the 
platform on which the program is running.
\Errors
None.
\SeeAlso
\seep{InitKeyBoard}
\end{procedure}

For an example, see most other functions.

\begin{function}{GetKeyEvent}
\Declaration
function GetKeyEvent: TKeyEvent;
\Description
\var{GetKeyEvent} returns the last keyevent if one was stored in
\var{PendingKeyEvent}, or waits for one if none is available.
A non-blocking version is available in \seef{PollKeyEvent}.

The returned key is encoded as a \var{TKeyEvent} type variable, and
is normally the physical key code, which can be translated with one
of the translation functions \seef{TranslateKeyEvent} or
\seef{TranslateKeyEventUniCode}. See the types section for a 
description of how the key is described.
\Errors
If no key became available, 0 is returned.
\SeeAlso
\seep{PutKeyEvent}, \seef{PollKeyEvent}, \seef{TranslateKeyEvent},
\seef{TranslateKeyEventUniCode}
\end{function}

\FPCexample{ex1}

\begin{function}{GetKeyEventChar}
\Declaration
function GetKeyEventChar(KeyEvent: TKeyEvent): Char;
\Description
\var{GetKeyEventChar} returns the charcode part of the given 
\var{KeyEvent}, if it contains a translated character key 
keycode. The charcode is simply the ascii code of the 
character key that was pressed.

It returns the null character if the key was not a character key, but e.g. a
function key.
\Errors
None.
\SeeAlso
\seef{GetKeyEventUniCode},
\seef{GetKeyEventShiftState}, 
\seef{GetKeyEventFlags},
\seef{GetKeyEventCode},
\seef{GetKeyEvent}
\end{function}

For an example, see \seef{GetKeyEvent}

\begin{function}{GetKeyEventCode}
\Declaration
function GetKeyEventCode(KeyEvent: TKeyEvent): Word;
\Description
\var{GetKeyEventCode} returns the translated function keycode part of 
the given KeyEvent, if it contains a translated function key.

If the key pressed was not a function key, the null character is returned.
\Errors
None.
\SeeAlso
\seef{GetKeyEventUniCode},
\seef{GetKeyEventShiftState}, 
\seef{GetKeyEventFlags},
\seef{GetKeyEventChar},
\seef{GetKeyEvent}
\end{function}

\FPCexample{ex2}

\begin{function}{GetKeyEventFlags}
\Declaration
function GetKeyEventFlags(KeyEvent: TKeyEvent): Byte;
\Description
\var{GetKeyEventFlags} returns the flags part of the given 
\var{KeyEvent}. 
\Errors
None.
\SeeAlso
\seef{GetKeyEventUniCode},
\seef{GetKeyEventShiftState}, 
\seef{GetKeyEventCode},
\seef{GetKeyEventChar},
\seef{GetKeyEvent}
\end{function}

For an example, see \seef{GetKeyEvent}

\begin{function}{GetKeyEventShiftState}
\Declaration
function GetKeyEventShiftState(KeyEvent: TKeyEvent): Byte;
\Description
\var{GetKeyEventShiftState} returns the shift-state values of 
the given \var{KeyEvent}. This can be used to detect which of the modifier
keys \var{Shift}, \var{Alt} or \var{Ctrl} were pressed. If none were
pressed, zero is returned.

Note that this function does not always return expected results;
In a unix X-Term, the modifier keys do not always work.
\Errors
None.
\SeeAlso
\seef{GetKeyEventUniCode},
\seef{GetKeyEventFlags}, 
\seef{GetKeyEventCode},
\seef{GetKeyEventChar},
\seef{GetKeyEvent}
\end{function}

\FPCexample{ex3}

\begin{function}{GetKeyEventUniCode}
\Declaration
function GetKeyEventUniCode(KeyEvent: TKeyEvent): Word;
\Description
\var{GetKeyEventUniCode} returns the unicode part of the 
given \var{KeyEvent} if it contains a translated unicode 
character.
\Errors
None.
\SeeAlso
\seef{GetKeyEventShiftState},
\seef{GetKeyEventFlags}, 
\seef{GetKeyEventCode},
\seef{GetKeyEventChar},
\seef{GetKeyEvent}
\end{function}

No example available yet.

\begin{procedure}{InitKeyBoard}
\Declaration
procedure InitKeyboard;
\Description
\var{InitKeyboard} initializes the keyboard interface, any 
additional platform specific parameters should be passed by 
setting platform-specific global variables.

This function should be called once, before using any of the
keyboard functions.
\Errors
None.
\SeeAlso
\seep{DoneKeyboard}
\end{procedure}

For an example, see most other functions.

\begin{function}{IsFunctionKey}
\Declaration
function IsFunctionKey(KeyEvent: TKeyEvent): Boolean;
\Description
\var{IsFunctionKey} returns \var{True} if the given key event
in \var{KeyEvent} was a function key or not.
\Errors
None.
\SeeAlso
\seef{GetKeyEvent}
\end{function}

\FPCexample{ex7}

\begin{function}{PollKeyEvent}
\Declaration
function PollKeyEvent: TKeyEvent;
\Description
\var{PollKeyEvent} checks whether a key event is available, 
and returns it if one is found. If no event is pending, 
it returns 0. 

Note that this does not remove the key from the pending keys. 
The key should still be retrieved from the pending key events 
list with the \seef{GetKeyEvent} function.
\Errors
None.
\SeeAlso
\seep{PutKeyEvent}, \seef{GetKeyEvent}
\end{function}

\FPCexample{ex4}

\begin{function}{PollShiftStateEvent}
\Declaration
function PollShiftStateEvent: TKeyEvent;
\Description
\var{PollShiftStateEvent} returns the current shiftstate in a 
keyevent. This will return 0 if there is no key event pending.
\Errors
None.
\SeeAlso
\seef{PollKeyEvent}, \seef{GetKeyEvent}
\end{function}

\FPCexample{ex6}

\begin{procedure}{PutKeyEvent}
\Declaration
procedure PutKeyEvent(KeyEvent: TKeyEvent);
\Description
\var{PutKeyEvent} adds the given \var{KeyEvent} to the input 
queue. Please note that depending on the implementation this 
can hold only one value, i.e. when calling \var{PutKeyEvent}
multiple times, only the last pushed key will be remembered.
\Errors
None
\SeeAlso
\seef{PollKeyEvent}, \seef{GetKeyEvent}
\end{procedure}

\FPCexample{ex5}

\begin{function}{TranslateKeyEvent}
\Declaration
function TranslateKeyEvent(KeyEvent: TKeyEvent): TKeyEvent;
\Description
\var{TranslateKeyEvent} performs ASCII translation of the \var{KeyEvent}.
It translates a physical key to a function key if the key is a function key,
and translates the physical key to the ordinal of the ascii character if 
there is an equivalent character key.
\Errors
None.
\SeeAlso
\seef{TranslateKeyEventUniCode}
\end{function}

For an example, see \seef{GetKeyEvent}

\begin{function}{TranslateKeyEventUniCode}
\Declaration
function TranslateKeyEventUniCode(KeyEvent: TKeyEvent): TKeyEvent;
\Description
\var{TranslateKeyEventUniCode} performs Unicode translation of the 
\var{KeyEvent}. It is not yet implemented for all platforms.

\Errors
If the function is not yet implemented, then the \var{ErrorCode} of the 
\file{system} unit will be set to \var{errKbdNotImplemented}
\SeeAlso
\end{function}

No example available yet.

\section{Keyboard scan codes}
Special physical keys are encoded with the DOS scan codes for these keys
in the second byte of the \var{TKeyEvent} type.
What follows is a list of the scan codes.
\begin{FPCtable}{ll}{Physical keys scan codes}
Scan code (hex) & Key \\ \hline
00 & NoKey \\
01 & ALT-Esc \\
02 & ALT-Space \\
04 & CTRL-Ins \\
05 & SHIFT-Ins \\
06 & CTRL-Del \\
07 & SHIFT-Del \\
08 & ALT-Back \\
09 & ALT-SHIFT-Back \\
0F & SHIFT-Tab \\
10 & ALT-Q \\
11 & ALT-W \\
12 & ALT-E \\
13 & ALT-R \\
14 & ALT-T \\
15 & ALT-Y \\
16 & ALT-U \\
17 & ALT-I \\
18 & ALT-O \\
19 & ALT-P \\
1A & ALT-LftBrack \\
1B & ALT-RgtBrack \\
1E & ALT-A \\
1F & ALT-S \\
20 & ALT-D \\
21 & ALT-F \\
22 & ALT-G \\
23 & ALT-H \\
24 & ALT-J \\
25 & ALT-K \\
26 & ALT-L \\
27 & ALT-SemiCol \\
28 & ALT-Quote \\
29 & ALT-OpQuote \\
2B & ALT-BkSlash \\
2C & ALT-Z \\
2D & ALT-X \\
2E & ALT-C \\
2F & ALT-V \\
30 & ALT-B \\
31 & ALT-N \\
32 & ALT-M \\
33 & ALT-Comma \\
34 & ALT-Period \\
35 & ALT-Slash \\
37 & ALT-GreyAst \\
3B & F1 \\
3C & F2 \\
3D & F3 \\
3E & F4 \\
3F & F5 \\
40 & F6 \\
41 & F7 \\
42 & F8 \\
43 & F9 \\
44 & F10 \\
47 & Home \\
48 & Up \\
49 & PgUp \\
4B & Left \\
4C & Center \\
4D & Right \\
4E & ALT-GrayPlus \\
4F & end \\
50 & Down \\
51 & PgDn \\
52 & Ins \\
53 & Del \\
54 & SHIFT-F1 \\
55 & SHIFT-F2 \\
56 & SHIFT-F3 \\
57 & SHIFT-F4 \\
58 & SHIFT-F5 \\
59 & SHIFT-F6 \\
5A & SHIFT-F7 \\
5B & SHIFT-F8 \\
5C & SHIFT-F9 \\
5D & SHIFT-F10 \\
5E & CTRL-F1 \\
5F & CTRL-F2 \\
60 & CTRL-F3 \\
61 & CTRL-F4 \\
62 & CTRL-F5 \\
63 & CTRL-F6 \\
64 & CTRL-F7 \\
65 & CTRL-F8 \\
66 & CTRL-F9 \\
67 & CTRL-F10 \\
68 & ALT-F1 \\
69 & ALT-F2 \\
6A & ALT-F3 \\
6B & ALT-F4 \\
6C & ALT-F5 \\
6D & ALT-F6 \\
6E & ALT-F7 \\
6F & ALT-F8 \\
70 & ALT-F9 \\
71 & ALT-F10 \\
72 & CTRL-PrtSc \\
73 & CTRL-Left \\
74 & CTRL-Right \\
75 & CTRL-end \\
76 & CTRL-PgDn \\
77 & CTRL-Home \\
78 & ALT-1 \\
79 & ALT-2 \\
7A & ALT-3 \\
7B & ALT-4 \\
7C & ALT-5 \\
7D & ALT-6 \\
7E & ALT-7 \\
7F & ALT-8 \\
80 & ALT-9 \\
81 & ALT-0 \\
82 & ALT-Minus \\
83 & ALT-Equal \\
84 & CTRL-PgUp \\
85 & F11 \\
86 & F12 \\
87 & SHIFT-F11 \\
88 & SHIFT-F12 \\
89 & CTRL-F11 \\
8A & CTRL-F12 \\
8B & ALT-F11 \\
8C & ALT-F12 \\
8D & CTRL-Up \\
8E & CTRL-Minus \\
8F & CTRL-Center \\
90 & CTRL-GreyPlus \\
91 & CTRL-Down \\
94 & CTRL-Tab \\
97 & ALT-Home \\
98 & ALT-Up \\
99 & ALT-PgUp \\
9B & ALT-Left \\
9D & ALT-Right \\
9F & ALT-end \\
A0 & ALT-Down \\
A1 & ALT-PgDn \\
A2 & ALT-Ins \\
A3 & ALT-Del \\
A5 & ALT-Tab \\ \hline
\end{FPCtable}