Unit Keymap

From Ultibo.org
Jump to: navigation, search

Return to Unit Reference


Description


Ultibo Keymap Interface unit

Keymaps

Keymaps define the translation of a keyboard scan code (the SCAN_CODE_* values) to a key code value (the KEY_CODE_* values) and provide the ability to handle different keyboard layouts in different countries and regions.

The keyboard scan codes are based on the values in Section 10 of the Universal Serial Bus HID Usage Tables v1.12 and are the actual values returned by the keyboard when a key is pressed.

The key code values are based on the Unicode standard with each key code mapped to the code point for that character.

This allows almost infinite flexibility in the way keyboard scan codes are mapped to actual characters and avoids the need to make unreliable assumptions about ASCII characters and upper or lower case handling.

Since the output of the keyboard is a stream of TKeyboardData structures containing both the scan code and the key code then higher level functions can retranslate the data in any way required.

Caps Keys

Caps keys account for the set of keys which are affected by Caps Lock in any given keyboard layout.

In some layouts only the alphabetic keys are affected, in other layouts some or all of the numeric and punctuation keys are also affected.

The caps keys data for any keyboard layout allows defining ranges of keys that are affected by the Caps Lock state.

Dead Keys

Dead keys account for the set of keys which behave as dead keys in any given keyboard layout.

On pressing a deadkey it will be recognized by the keyboard as such and stored until the next key press occurs. If the next keypress is one of the resolves for the pressed dead key then the output character will be the key code value of the resolve not for the key itself.

If the next keypress after a dead key is not one of the resolves that the dead key and the pressed key will both be output to the keyboard buffer.

Setting the default keymap for the system

Additional keymaps are provided as units which can be included in a program and will auto load themselves if included.

All keymap units are configured to check for both the environment variable KEYMAP_DEFAULT and the global configuration variable KEYMAP_DEFAULT to determine if either of them is set to the name of that keymap. If either is set to the keymap name then that keymap will also set itself as the default during system startup.

The environment variable KEYMAP_DEFAULT can be set by adding KEYMAP_DEFAULT=XX (where XX is the name of the keymap, eg DE for Keymap_DE) to the command line of the application (dependent on the system, for a Raspberry Pi use the cmdline.txt file on the SD card).

The global configuration variable KEYMAP_DEFAULT can be set in code by including the GlobalConfig unit in a program and setting the variable during startup.

At any time after startup the default keymap can be changed by call the KeymapSetDefault function.

Constants



Keymap specific constants KEYMAP_*
KEYMAP_KEY_COUNT = 256; Number of key mappings in a keymap entry
KEYMAP_ROW_COUNT = 4; Number of mapping rows per key in a keymap entry (Normal, Shift, AltGr, Shift_AltGr)
KEYMAP_ROW_SIZE = SizeOf(Word);  
 
KEYMAP_MAX_CAPSKEYS = 50; Maximum number of keys that can be listed in the TKeymapCapskeys structure
KEYMAP_MAX_DEADKEYS = 5; Maximum number of keys that can be listed in the TKeymapDeadkeys structure
KEYMAP_MAX_RESOLVES = 20; Maximum number of resolves that can be listed in the TKeymapDeadkey structure


Keymap signature KEYMAP_SIGNATURE_*
KEYMAP_SIGNATURE = $863FDBA1;  


Keymap name length KEYMAP_*_LENGTH
KEYMAP_NAME_LENGTH = SIZE_64; Length of keymap name
KEYMAP_DESC_LENGTH = SIZE_128; Length of keymap description


Keymap mode KEYMAP_MODE_*
KEYMAP_MODE_NONE = 0;  


Keymap flag KEYMAP_FLAG_*
KEYMAP_FLAG_NONE = $00000000;  
KEYMAP_FLAG_ALTGR = $00000001; The key mapping uses the AltGr key
KEYMAP_FLAG_CAPS_ALL = $00000002; Caps Lock shifts all characters not just alphabetic
KEYMAP_FLAG_CAPS_ASCII = $00000004; Caps Lock shifts only ASCII characters A to Z


Keymap index KEYMAP_INDEX_*
KEYMAP_INDEX_NORMAL = 0; Normal (unshifted) value
KEYMAP_INDEX_SHIFT = 1; Shifted value
KEYMAP_INDEX_ALTGR = 2; AltGr value
KEYMAP_INDEX_SHIFT_ALTGR = 3; Shift plus AltGr value


Type definitions



Keymap header

PKeymapHeader = ^TKeymapHeader;

TKeymapHeader = record

Mode:LongWord; Keymap mode (eg KEYMAP_MODE_NONE)
Flags:LongWord; Keymap flags (eg KEYMAP_FLAG_ALTGR)
KeyCount:LongWord; Number of keys in keymap (Default: KEYMAP_KEY_COUNT)
RowCount:LongWord; Number of index rows in keymap (Default: KEYMAP_ROW_COUNT)
Name:String[255]; Keymap name
Description:String[255]; Keymap description

Keymap data

PKeymapData = ^TKeymapData;

TKeymapData = record

Data:array[0..255,KEYMAP_INDEX_NORMAL..KEYMAP_INDEX_SHIFT_ALTGR] of Word; Key mapping data, 4 words for Normal, Shift, AltGr, Shift+AltGr for each of the 256 keys (See KEY_CODE_* constants)

Keymap chars

PKeymapChars = ^TKeymapChars;

TKeymapChars = array[0..0] of Word;

   

Keymap capskey

PKeymapCapskey = ^TKeymapCapskey;

TKeymapCapskey = record

Note: Keymap Capskey (Keys affected by the Caps Lock function)
First:Word; First key in caps key range (SCAN_CODE_* value)
Last:Word; Last key in caps key range (SCAN_CODE_* value)(Make first and last the same for a single key)

Keymap capskeys

PKeymapCapskeys = ^TKeymapCapskeys;

TKeymapCapskeys = record

Count:LongWord;  
Keys:array[0..KEYMAP_MAX_CAPSKEYS - 1] of TKeymapCapskey;  

Keymap resolve

PKeymapResolve = ^TKeymapResolve;

TKeymapResolve = record

Key:Word; The scan code of the key pressed after the deadkey (SCAN_CODE_* value)
Index:Byte; The index state of the key pressed after the deadkey (eg KEYMAP_INDEX_NORMAL)
Code:Word; The key code of the resulting character (KEY_CODE_* value)

Keymap deadkey

PKeymapDeadkey = ^TKeymapDeadkey;

TKeymapDeadkey = record

Note: Keymap Deadkey (Keys which behave as dead keys)
Key:Word; The scan code of the key which behaves as a deadkey (SCAN_CODE_* value)
Index:Byte; The index state in which the key behaves as a deadkey (eg KEYMAP_INDEX_NORMAL)
Resolves:array[0..KEYMAP_MAX_RESOLVES - 1] of TKeymapResolve;  

Keymap deadkeys

PKeymapDeadkeys = ^TKeymapDeadkeys;

TKeymapDeadkeys = record

Count:LongWord;  
Keys:array[0..KEYMAP_MAX_DEADKEYS - 1] of TKeymapDeadkey;  

Keymap properties

PKeymapProperties = ^TKeymapProperties;

TKeymapProperties = record

KeymapMode:LongWord; Keymap mode (eg KEYMAP_MODE_NONE)
KeymapFlags:LongWord; Keymap flags (eg KEYMAP_FLAG_ALTGR)
KeyCount:LongWord; Number of keys in keymap (Default: KEYMAP_KEY_COUNT)
RowCount:LongWord; Number of index rows in keymap (Default: KEYMAP_ROW_COUNT)
KeymapName:array[0..KEYMAP_NAME_LENGTH - 1] of Char; Keymap name
KeymapDescription:array[0..KEYMAP_DESC_LENGTH - 1] of Char; Keymap description

Keymap enumeration callback

TKeymapEnumerate = function(Handle:TKeymapHandle; Data:Pointer):LongWord;

Keymap entry

PKeymapEntry = ^TKeymapEntry;

TKeymapEntry = record

Keymap Properties
Signature:LongWord; Signature for entry validation
KeymapMode:LongWord; Keymap mode (eg KEYMAP_MODE_NONE)
KeymapFlags:LongWord; Keymap flags (eg KEYMAP_FLAG_ALTGR)
KeymapName:array[0..KEYMAP_NAME_LENGTH - 1] of Char; Keymap name
KeymapDescription:array[0..KEYMAP_DESC_LENGTH - 1] of Char; Keymap description
Driver Properties
KeyData:Pointer; Keymap key data
KeyCount:LongWord; Number of keys in key data (Default: KEYMAP_KEY_COUNT)
RowCount:LongWord; Number of index rows in key data (Default: KEYMAP_ROW_COUNT)
CapskeysData:PKeymapCapskeys; Keymap Capskeys data (Keys affected by Caps Lock)
DeadkeysData:PKeymapDeadkeys; Keymap Deadkeys data (Keys which behave as Dead keys)
Internal Properties
Prev:PKeymapEntry; Previous entry in Keymap table
Next:PKeymapEntry; Next entry in Keymap table


Public variables


None defined

Function declarations



Initialization functions

procedure KeymapInit;
Description: Initialize the keymap unit, keymap table and default keymap
Note Called only during system startup


Keymap functions

function KeymapLoad(Header:PKeymapHeader; Data:PKeymapData; Size:LongWord):TKeymapHandle;
Description: Load a Keymap from a keymap data block and add to the Keymap table
Header Pointer to the keymap header
Data Pointer to the keymap data
Size Size of the keymap data
Return Handle of the newly loaded keymap or INVALID_HANDLE_VALUE on failure


function KeymapLoadEx(Header:PKeymapHeader; Data:PKeymapData; Capskeys:PKeymapCapskeys; Deadkeys:PKeymapDeadkeys; Size:LongWord; Properties:PKeymapProperties):TKeymapHandle;
Description: Load a Keymap from a keymap data block and add to the Keymap table
Header Pointer to the keymap header (See TKeymapHeader)
Data Pointer to the keymap data (See TKeymapData)
Capskeys Pointer to the capskeys table (Optional)
Deadkeys Pointer to the deadkeys table (Optional)
Size Size of the keymap data
Properties Pointer to a keymap properties record to use instead of the header (Optional)
Return Handle of the newly loaded keymap or INVALID_HANDLE_VALUE on failure


function KeymapUnload(Handle:TKeymapHandle):LongWord;
Description: Unload an existing keymap and remove from the Keymap table
Handle The handle of the keymap to unload
Return ERROR_SUCCESS if completed or another error code on failure


function KeymapGetName(Handle:TKeymapHandle):String;
Description: Get the name of the specified keymap
Handle The handle of the keymap to get the name for
Return The name of the keymap (eg US)


function KeymapGetDescription(Handle:TKeymapHandle):String;
Description: Get the description of the specified keymap
Handle The handle of the keymap to get the description for
Return The description of the keymap (eg US English)


function KeymapCheckFlag(Handle:TKeymapHandle; Flag:LongWord):Boolean;
Description: Check if a specified keymap has a particular flag set or not
Handle The handle of the keymap to check the flag for
Flag The flag value to check (eg KEYMAP_FLAG_CAPS_ASCII)
Return True if the flag is set and False if not set


function KeymapGetKeyCode(Handle:TKeymapHandle; ScanCode:Word; Index:Byte):Word;
Description: Resolve a scan code and index value to a key code using the specified keymap
Handle The handle of the keymap to use for translation
ScanCode The keyboard scan code value to resolve (eg SCAN_CODE_A)
Index The keymap index to use for the translation (eg KEYMAP_INDEX_SHIFT)
Return The translated key code value (eg KEY_CODE_A) or KEY_CODE_NONE on failure


function KeymapGetCharCode(Handle:TKeymapHandle; KeyCode:Word):Char;
Description: Resolve a key code value to an ANSI character code using the specified keymap
Handle The handle of the keymap to use for translation
KeyCode The key code value to resolve (eg KEY_CODE_A)
Return The ANSI character value for the keycode or 0 on failure


function KeymapGetCharUnicode(Handle:TKeymapHandle; KeyCode:Word):WideChar;
Description: Resolve a key code value to a Unicode character code using the specified keymap
Handle The handle of the keymap to use for translation
KeyCode The key code value to resolve (eg KEY_CODE_A)
Return The Unicode character value for the keycode or 0 on failure


function KeymapCheckCapskey(Handle:TKeymapHandle; ScanCode:Word):Boolean;
Description: Check if a scan code is affected by the Caps Lock key in the specified keymap
Handle The handle of the keymap to check
ScanCode The scan code value to check (eg SCAN_CODE_A)
Return True if affected by Caps Lock, False if not


function KeymapCheckDeadkey(Handle:TKeymapHandle; ScanCode:Word; Index:Byte):Boolean;
Description: Check if a scan code represents a Dead Key in the specified keymap
Handle The handle of the keymap to check
ScanCode The scan code value to check (eg SCAN_CODE_A)
Index The keymap index to check (eg KEYMAP_INDEX_SHIFT)
Return True if the scan key is a Dead Key, False if not


function KeymapResolveDeadkey(Handle:TKeymapHandle; DeadCode,ScanCode:Word; DeadIndex,ScanIndex:Byte; var KeyCode:Word):Boolean;
Description: Resolve a Dead Key and the next scan code to a key code value
Handle The handle of the keymap to use for resolution
DeadCode The scan code value of the dead key (eg SCAN_CODE_GRAVE)
ScanCode The scan code value of the next key (eg (SCAN_CODE_A)
DeadIndex The keymap index of the dead key (eg KEYMAP_INDEX_SHIFT)
ScanIndex The keymap index of the next key (eg KEYMAP_INDEX_SHIFT)
KeyCode Return value for the key code represented by the dead key/next key combination (or KEY_CODE_NONE)
Return True if the dead key/next key combination resolves to a key code or False if not


function KeymapGetProperties(Handle:TKeymapHandle; Properties:PKeymapProperties):LongWord;
Description: Get the properties of the specified keymap
Handle The handle of the keymap to get the properties for
Properties Pointer to a keymap properties structure to return the properties
Return ERROR_SUCCESS if completed or another error code on failure


function KeymapFindByName(const Name:String):TKeymapHandle; 
Description: Find a keymap by name
Name The name of the keymap to find (eg US)
Return The handle of the matching keymap or INVALID_HANDLE_VALUE if not found


function KeymapFindByDescription(const Description:String):TKeymapHandle;
Description: Find a keymap by description
Description The description of the keymap to find (eg US English)
Return The handle of the matching keymap or INVALID_HANDLE_VALUE if not found


function KeymapEnumerate(Callback:TKeymapEnumerate; Data:Pointer):LongWord;
Description: Enumerate all loaded keymaps
Callback The function to call for each loaded keymap
Data A private data pointer to pass to callback for each loaded keymap


Keymap helper functions

function KeymapGetCount:LongWord;
Description: Get the current keymap count
Note None documented


function KeymapGetDefault:TKeymapHandle;
Description: Get the current default keymap
Note None documented


function KeymapSetDefault(Handle:TKeymapHandle):LongWord;
Description: Set the current default keymap
Note None documented


function KeymapCheck(Keymap:PKeymapEntry):PKeymapEntry;
Description: Check if the supplied Keymap is in the Keymap table
Note None documented


Return to Unit Reference