Access to low-level keyboard functions

The 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 function, which will return a driver-dependent key event. This key event can be translated to a interpretable event by the function. The result of this function can be used in the other event examining functions.

A custom keyboard driver can be installed using the function. The current keyboard driver can be retrieved using the function. The last section of this chapter demonstrates how to make a keyboard driver.

Base of keyboard routine error reporting constants. Failed to initialize keyboard driver Keyboard driver not implemented. F1 function key pressed. F2 function key pressed. F3 function key pressed. F4 function key pressed. F5 function key pressed. F6 function key pressed. F7 function key pressed. F8 function key pressed. F9 function key pressed. F10 function key pressed. F12 function key pressed. F12 function key pressed. F13 function key pressed. F14 function key pressed. F15 function key pressed. F16 function key pressed. F17 function key pressed. F18 function key pressed. F19 function key pressed. F20 function key pressed. function key pressed. Shift key name index. Alt key name index. Alt key name index. Shift key name index. Home key pressed Arrow up key pressed Arrow down key pressed Page Up key pressed Arrow left key pressed Middle key pad key pressed (numerical 5) Arrow right key pressed End key pressed Page down key pressed Insert key pressed Delete key pressed Ascii code key event Unicode code key event Physical key code event Key release event Left shift key modifier Right shift key modifier Shift key modifier Control key modifier Alt key modifier Names of modifier keys This constant describes the various modifier keys. This constant is used by the key event description routines. It can be changed to localize the key descriptions when needed. Names for left-right keys This constant contains strings to describe left and right keys. This constant is used by the key event description routines. It can be changed to localize the key descriptions when needed. Unicode character string. This constant contains a string to denote a unicode key event. This constant is used by the key event description routines. It can be changed to localize the key descriptions when needed. Scancode key This constant contains a string to denote a scancode key event. This constant is used by the key event description routines. It can be changed to localize the key descriptions when needed. Unknown function key This constant contains a string to denote that an unknown function key was found. This constant is used by the key event description routines. It can be changed to localize the key descriptions when needed. 'And' description string This constant is used as the 'And' word in key descriptions. This constant is used by the key event description routines. It can be changed to localize the key descriptions when needed. Names of keypad keys This constant describes all keypad keys. This constant is used by the key event description routines. It can be changed to localize the key descriptions when needed. Base type to describe all key events.

The TKeyEvent type is the base type for all keyboard events.

The key stroke is encoded in the 4 bytes of the TKeyEvent type. The various fields of the key stroke encoding can be obtained by typecasting the TKeyEvent type to the type.

Key event decoding type.

The structure of a TKeyRecord structure is explained in the following table:

Structure of TKeyRecord
FieldMeaning
KeyCode Depending on 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 KeyCode

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).

Keyboard driver structure

The TKeyboardDriver record can be used to install a custom keyboard driver with the function.

The various fields correspond to the different functions of the keyboard unit interface. For more information about this record see

Deactivate keyboard driver.

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

For an example, see most other functions.

None.
Return string representation of a function key code. FunctionKeyName returns a string representation of the function key with code KeyCode. This can be an actual function key, or one of the cursor movement keys. In case KeyCode does not contain a function code, the SUnknownFunctionKey string is returned, appended with the KeyCode. Return the current keyboard driver record.

GetKeyBoardDriver returns in 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 .

None.
Get the next raw key event, wait if needed.

GetKeyEvent returns the last keyevent if one was stored in PendingKeyEvent, or waits for one if none is available. A non-blocking version is available in .

The returned key is encoded as a 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 or . See the types section for a description of how the key is described.

If no key became available, 0 is returned. ,
Get the character key part of a key event.

GetKeyEventChar returns the charcode part of the given 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.

For an example, see

None. , , , ,
Translate function key part of a key event code.

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.

None. , , , ,
Extract the flags from a key event.

GetKeyEventFlags returns the flags part of the given KeyEvent.

For an example, see

None. , , , ,
Return the current state of the shift keys.

GetKeyEventShiftState returns the shift-state values of the given KeyEvent. This can be used to detect which of the modifier keys Shift, Alt or 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.

None. , , , ,
Return the unicode key event. GetKeyEventUniCode returns the unicode part of the given KeyEvent if it contains a translated unicode character. None. , , , , Initialize the keyboard driver.

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 function should also be called before exiting the program or changing the keyboard driver with .

For an example, see most other functions.

None.
Check whether a given event is a function key event. IsFunctionKey returns True if the given key event in KeyEvent was a function key or not. None. Return a string describing the key event.

KeyEventToString translates the key event in KeyEvent to a human-readable description of the pressed key. It will use the constants described in the constants section to do so.

For an example, see most other functions.

If an unknown key is passed, the scancode is returned, prefixed with the SScanCode string.
Check event queue for key press KeyPressed checks the keyboard event queue to see whether a key event is present, and returns True if a key event is available. This function simply calls and checks for a valid result. None. Get next key event, but does not wait.

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 function.

None.
Check current shift state. PollShiftStateEvent returns the current shiftstate in a keyevent. This will return 0 if there is no key event pending. None. Put a key event in the event queue. PutKeyEvent adds the given KeyEvent to the input queue. Please note that depending on the implementation this can hold only one value, i.e. when calling PutKeyEvent multiple times, only the last pushed key will be remembered. None Set a new keyboard driver.

SetKeyBoardDriver sets the keyboard driver to Driver, if the current keyboard driver is not yet initialized. If the current keyboard driver is initialized, then SetKeyboardDriver does nothing. Before setting the driver, the currently active driver should be disabled with a call to .

The function returns True if the driver was set, False if not.

For more information on setting the keyboard driver, see .

None. .
Return description of key event shift state

ShiftStateToString returns a string description of the shift state of the key event KeyEvent. This can be an empty string.

The shift state is described using the strings in the SShift constant.

For an example, see .

None.
Translate raw event to ascii key event

TranslateKeyEvent performs ASCII translation of the 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.

For an example, see

None.
Translate raw event to UNICode key event TranslateKeyEventUniCode performs Unicode translation of the KeyEvent. It is not yet implemented for all platforms. If the function is not yet implemented, then the ErrorCode of the system unit will be set to errKbdNotImplemented Keyboard scan codes

Special physical keys are encoded with the DOS scan codes for these keys in the second byte of the type. A complete list of scan codes can be found in the below table. 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 TranslateKeyEvent hook should be implemented by the driver.

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

A list of scan codes for special keys and combinations with the SHIFT, ALT and CTRL keys can be found in the following table: They are for quick reference only.

Special keys scan codes
Key Code SHIFT-Key CTRL-Key Alt-Key
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
Writing a keyboard driver

Writing a keyboard driver means that hooks must be created for most of the keyboard unit functions. The TKeyBoardDriver record contains a field for each of the possible hooks:

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;

The meaning of these hooks is explained below:

InitDriver
Called to initialize and enable the driver. Guaranteed to be called only once. This should initialize all needed things for the driver.
DoneDriver
Called to disable and clean up the driver. Guaranteed to be called after a call to initDriver. This should clean up all things initialized by InitDriver.
GetKeyEvent
Called by . Must wait for and return the next key event. It should NOT store keys.
PollKeyEvent
Called by . It must return the next key event if there is one. Should not store keys.
GetShiftState
Called by . Must return the current shift state.
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 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.
TranslateKeyEventUniCode
Should translate a key event to a unicode key representation.

Strictly speaking, only the GetKeyEvent and PollKeyEvent hooks must be implemented for the driver to function correctly.

The example unit demonstrates how a keyboard driver can be installed. It takes the installed driver, and hooks into the 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 uses clause after the real driver unit, and the real driver unit should set the driver record in its initialization section.

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.