mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-10 08:08:36 +02:00
630 lines
21 KiB
TeX
630 lines
21 KiB
TeX
%
|
|
% $Id$
|
|
% This file is part of the FPC documentation.
|
|
% Copyright (C) 2001, 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 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 certain
|
|
events. Waiting for a keyboard event can be done with the \seef{GetKeyEvent}
|
|
function, which will return a driver-dependent key event. This key event can
|
|
be translated to a interpretable event by the \seef{TranslateKeyEvent}
|
|
function. The result of this function can be used in the other event
|
|
examining functions.
|
|
|
|
A custom keyboard driver can be installed using the \seef{SetKeyboardDriver}
|
|
function. The current keyboard driver can be retrieved using the
|
|
\seep{GetKeyboardDriver} function. The last section of this chapter
|
|
demonstrates how to make a keyboard driver.
|
|
|
|
\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 cursor 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 keys.
|
|
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 what kind of data a key event contains.
|
|
The following shift-state flags can be used to determine the shift state of
|
|
a key (i.e. which of the SHIFT, ALT and CTRL keys were pressed
|
|
simultaneously with a key):
|
|
\begin{verbatim}
|
|
kbLeftShift = 1;
|
|
kbRightShift = 2;
|
|
kbShift = kbLeftShift or kbRightShift;
|
|
kbCtrl = 4;
|
|
kbAlt = 8;
|
|
\end{verbatim}
|
|
The following constant strings are used in the key name functions
|
|
\seef{FunctionKeyName} and \seef{KeyEventToString}:
|
|
\begin{verbatim}
|
|
SShift : Array [1..3] of string[5] = ('SHIFT','CTRL','ALT');
|
|
LeftRight : Array [1..2] of string[5] = ('LEFT','RIGHT');
|
|
UnicodeChar : String = 'Unicode character ';
|
|
SScanCode : String = 'Key with scancode ';
|
|
SUnknownFunctionKey : String = 'Unknown function key : ';
|
|
SAnd : String = 'AND';
|
|
SKeyPad : Array [0..($FF2F-kbdHome)] of string[6] =
|
|
('Home','Up','PgUp','Left',
|
|
'Middle','Right','End','Down',
|
|
'PgDn','Insert','Delete','',
|
|
'','','','');
|
|
\end{verbatim}
|
|
They can be changed to localize the key names when needed.
|
|
|
|
\subsection{Types}
|
|
The \var{TKeyEvent} type is the base type for all keyboard events:
|
|
\begin{verbatim}
|
|
TKeyEvent = Longint;
|
|
\end{verbatim}
|
|
The key stroke is encoded in the 4 bytes of the \var{TKeyEvent} type.
|
|
The various fields of the key stroke encoding can be obtained by typecasting
|
|
the \var{TKeyEvent} type to the \var{TKeyRecord} type:
|
|
\begin{verbatim}
|
|
TKeyRecord = packed record
|
|
KeyCode : Word;
|
|
ShiftState, Flags : Byte;
|
|
end;
|
|
\end{verbatim}
|
|
The structure of a \var{TKeyRecord} structure is explained in \seet{keyevent}.
|
|
\begin{FPCltable}{lp{10cm}}{Structure of TKeyRecord}{keyevent}
|
|
Field & Meaning \\ \hline
|
|
KeyCode & Depending on \var{flags} either the physical representation of a key
|
|
(under DOS scancode, ascii code pair), or the translated
|
|
ASCII/unicode character.\\
|
|
ShiftState & Shift-state when this key was pressed (or shortly after) \\
|
|
Flags & Determine how to interpret \var{KeyCode} \\ \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).
|
|
|
|
The \var{TKeyboardDriver} record can be used to install a custom keyboard
|
|
driver with the \seef{SetKeyboardDriver} function:
|
|
\begin{verbatim}
|
|
Type
|
|
TKeyboardDriver = Record
|
|
InitDriver : Procedure;
|
|
DoneDriver : Procedure;
|
|
GetKeyEvent : Function : TKeyEvent;
|
|
PollKeyEvent : Function : TKeyEvent;
|
|
GetShiftState : Function : Byte;
|
|
TranslateKeyEvent : Function (KeyEvent: TKeyEvent): TKeyEvent;
|
|
TranslateKeyEventUniCode: Function (KeyEvent: TKeyEvent): TKeyEvent;
|
|
end;
|
|
\end{verbatim}
|
|
The various fields correspond to the different functions of the keyboard unit
|
|
interface. For more information about this record see \sees{kbddriver}
|
|
|
|
\section{Functions and Procedures}
|
|
|
|
\begin{procedure}{DoneKeyboard}
|
|
\Declaration
|
|
Procedure DoneKeyboard;
|
|
\Description
|
|
\var{DoneKeyboard} de-initializes the keyboard interface if the keyboard
|
|
driver is active. If the keyboard driver is not active, the function does
|
|
nothing.
|
|
|
|
This will cause the keyboard driver to clear up any allocated memory,
|
|
or restores the console or terminal the program was running in to its
|
|
initial state before the call to \seep{InitKeyBoard}. 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}{FunctionKeyName}
|
|
\Declaration
|
|
Function FunctionKeyName (KeyCode : Word) : String;
|
|
\Description
|
|
\var{FunctionKeyName} returns a string representation of the function key
|
|
with code \var{KeyCode}. This can be an actual function key, or one of the
|
|
cursor movement keys.
|
|
\Errors
|
|
In case \var{KeyCode} does not contain a function code, the
|
|
\var{SUnknownFunctionKey} string is returned, appended with the
|
|
\var{KeyCode}.
|
|
\SeeAlso
|
|
\seef{ShiftStateToString}
|
|
\seef{KeyEventToString}
|
|
\end{function}
|
|
|
|
\FPCexample{ex8}
|
|
|
|
\begin{procedure}{GetKeyboardDriver}
|
|
\Declaration
|
|
Procedure GetKeyboardDriver (Var Driver : TKeyboardDriver);
|
|
\Description
|
|
\var{GetKeyBoardDriver} returns in \var{Driver} the currently active
|
|
keyboard driver. This function can be used to enhance an existing
|
|
keyboarddriver.
|
|
|
|
For more information on getting and setting the keyboard driver
|
|
\sees{kbddriver}.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{SetKeyboardDriver}
|
|
\end{procedure}
|
|
|
|
\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 scan code, (the scan code is driver
|
|
dependent) 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 driver.
|
|
If the driver is already active, it does nothing. When the driver is
|
|
initialized, it will do everything necessary to ensure the functioning of
|
|
the keyboard, including allocating memory, initializing the terminal etc.
|
|
|
|
This function should be called once, before using any of the
|
|
keyboard functions. When it is called, the \seep{DoneKeyboard} function
|
|
should also be called before exiting the program or changing the keyboard
|
|
driver with \seef{SetKeyboardDriver}.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{DoneKeyboard}, \seef{SetKeyboardDriver}
|
|
\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}{KeyEventToString}
|
|
\Declaration
|
|
Function KeyEventToString(KeyEvent : TKeyEvent) : String;
|
|
\Description
|
|
\var{KeyEventToString} translates the key event in \var{KeyEvent} to a
|
|
human-readable description of the pressed key. It will use the constants
|
|
described in the constants section to do so.
|
|
\Errors
|
|
If an unknown key is passed, the scancode is returned, prefixed with the
|
|
\var{SScanCode} string.
|
|
\SeeAlso
|
|
\seef{FunctionKeyName}, \seef{ShiftStateToString}
|
|
\end{function}
|
|
|
|
For an example, see most other functions.
|
|
|
|
\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}{SetKeyboardDriver}
|
|
\Declaration
|
|
Function SetKeyboardDriver (Const Driver : TKeyboardDriver) : Boolean;
|
|
\Description
|
|
\var{SetKeyBoardDriver} sets the keyboard driver to \var{Driver}, if the
|
|
current keyboard driver is not yet initialized. If the current
|
|
keyboard driver is initialized, then \var{SetKeyboardDriver} does
|
|
nothing. Before setting the driver, the currently active driver should
|
|
be disabled with a call to \seep{DoneKeyboard}.
|
|
|
|
The function returns \var{True} if the driver was set, \var{False} if not.
|
|
|
|
For more information on setting the keyboard driver, see \sees{kbddriver}.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{GetKeyboardDriver}, \seep{DoneKeyboard}.
|
|
\end{function}
|
|
|
|
\begin{function}{ShiftStateToString}
|
|
\Declaration
|
|
Function ShiftStateToString(KeyEvent : TKeyEvent; UseLeftRight : Boolean) : String;
|
|
\Description
|
|
\var{ShiftStateToString} returns a string description of the shift state
|
|
of the key event \var{KeyEvent}. This can be an empty string.
|
|
|
|
The shift state is described using the strings in the \var{SShift} constant.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{FunctionKeyName}, \seef{KeyEventToString}
|
|
\end{function}
|
|
|
|
For an example, see \seef{PollShiftStateEvent}.
|
|
|
|
\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.
|
|
A complete list of scan codes can be found in \seet{keyscans}. This is the
|
|
list of keys that is used by the default key event translation mechanism.
|
|
When writing a keyboard driver, either these constants should be returned
|
|
by the various key event functions, or the \var{TranslateKeyEvent} hook
|
|
should be implemented by the driver.
|
|
\begin{FPCltable}{llllll}{Physical keys scan codes}{keyscans}
|
|
Code & Key & Code & Key & Code & Key\\ \hline
|
|
\input{keys.tex}
|
|
\end{FPCltable}
|
|
A list of scan codes for special keys and combinations with the SHIFT, ALT
|
|
and CTRL keys can be found in \seet{speckeys}; They are for quick reference
|
|
only.
|
|
\begin{FPCltable}{llccc}{Special keys scan codes}{speckeys}
|
|
Key & Code & SHIFT-Key & CTRL-Key & Alt-Key \\ \hline
|
|
NoKey & 00 & & & \\
|
|
F1 & 3B & 54 & 5E & 68 \\
|
|
F2 & 3C & 55 & 5F & 69 \\
|
|
F3 & 3D & 56 & 60 & 6A \\
|
|
F4 & 3E & 57 & 61 & 6B \\
|
|
F5 & 3F & 58 & 62 & 6C \\
|
|
F6 & 40 & 59 & 63 & 6D \\
|
|
F7 & 41 & 5A & 64 & 6E \\
|
|
F8 & 42 & 5A & 65 & 6F \\
|
|
F9 & 43 & 5B & 66 & 70 \\
|
|
F10 & 44 & 5C & 67 & 71 \\
|
|
F11 & 85 & 87 & 89 & 8B \\
|
|
F12 & 86 & 88 & 8A & 8C \\
|
|
Home & 47 & & 77 & 97 \\
|
|
Up & 48 & & 8D & 98 \\
|
|
PgUp & 49 & & 84 & 99 \\
|
|
Left & 4B & & 73 & 9B \\
|
|
Center & 4C & & 8F & \\
|
|
Right & 4D & & 74 & 9D \\
|
|
end & 4F & & 75 & 9F \\
|
|
Down & 50 & & 91 & A0 \\
|
|
PgDn & 51 & & 76 & A1 \\
|
|
Ins & 52 & 05 & 04 & A2 \\
|
|
Del & 53 & 07 & 06 & A3 \\
|
|
Tab & 8 & 0F & 94 & A5 \\
|
|
GreyPlus & & & 90 & 4E \\
|
|
\hline
|
|
\end{FPCltable}
|
|
\section{Writing a keyboard driver}
|
|
\label{se:kbddriver}
|
|
Writing a keyboard driver means that hooks must be created for most of the
|
|
keyboard unit functions. The \var{TKeyBoardDriver} record contains a field
|
|
for each of the possible hooks:
|
|
\begin{verbatim}
|
|
TKeyboardDriver = Record
|
|
InitDriver : Procedure;
|
|
DoneDriver : Procedure;
|
|
GetKeyEvent : Function : TKeyEvent;
|
|
PollKeyEvent : Function : TKeyEvent;
|
|
GetShiftState : Function : Byte;
|
|
TranslateKeyEvent : Function (KeyEvent: TKeyEvent): TKeyEvent;
|
|
TranslateKeyEventUniCode: Function (KeyEvent: TKeyEvent): TKeyEvent;
|
|
end;
|
|
\end{verbatim}
|
|
The meaning of these hooks is explained below:
|
|
\begin{description}
|
|
\item[InitDriver] Called to initialize and enable the driver.
|
|
Guaranteed to be called only once. This should initialize all needed things
|
|
for the driver.
|
|
\item[DoneDriver] Called to disable and clean up the driver. Guaranteed to be
|
|
called after a call to \var{initDriver}. This should clean up all
|
|
things initialized by \var{InitDriver}.
|
|
\item[GetKeyEvent] Called by \seef{GetKeyEvent}. Must wait for and return the
|
|
next key event. It should NOT store keys.
|
|
\item[PollKeyEvent] Called by \seef{PollKeyEvent}. It must return the next key
|
|
event if there is one. Should not store keys.
|
|
\item[GetShiftState] Called by \seef{PollShiftStateEvent}. Must return the current
|
|
shift state.
|
|
\item[TranslateKeyEvent] Should translate a raw key event to a cOrrect
|
|
key event, i.e. should fill in the shiftstate and convert function key
|
|
scancodes to function key keycodes. If the
|
|
\var{TranslateKeyEvent} is not filled in, a default translation function
|
|
will be called which converts the known scancodes from the tables in the
|
|
previous section to a correct keyevent.
|
|
\item[TranslateKeyEventUniCode] Should translate a key event to a unicode key
|
|
representation.
|
|
\end{description}
|
|
Strictly speaking, only the \var{GetKeyEvent} and \var{PollKeyEvent}
|
|
hooks must be implemented for the driver to function correctly.
|
|
|
|
The following unit demonstrates how a keyboard driver can be installed.
|
|
It takes the installed driver, and hooks into the \var{GetKeyEvent}
|
|
function to register and log the key events in a file. This driver
|
|
can work on top of any other driver, as long as it is inserted in the
|
|
\var{uses} clause {\em after} the real driver unit, and the real driver unit
|
|
should set the driver record in its initialization section.
|
|
\FPCexample{logkeys}
|
|
The following program demonstrates the use of the unit:
|
|
\FPCexample{ex9}
|
|
Note that with a simple extension of this unit could be used to make a
|
|
driver that is capable of recording and storing a set of keyboard strokes,
|
|
and replaying them at a later time, so a 'keyboard macro' capable driver.
|
|
This driver could sit on top of any other driver.
|