#include "KeyInfos.h"
#include <ctype.h>
#include <sstream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <strings.h>
#include <InterfaceDefs.h>
#define NUM_KEYS 128
#define MAX_UTF8_LENGTH 5
struct KeyLabelMap {
const char* fLabel;
uint8 fKeyCode;
};
static const struct KeyLabelMap keyLabels[] = {
{"<unset>", 0},
{"Esc", 1},
{"F1", 2},
{"F2", 3},
{"F3", 4},
{"F4", 5},
{"F5", 6},
{"F6", 7},
{"F7", 8},
{"F8", 9},
{"F9", 10},
{"F10", 11},
{"F11", 12},
{"F12", 13},
{"SysRq", 14},
{"ScrlLck", 15},
{"Pause", 16},
{"Bcksp", 30},
{"Insert", 31},
{"Home", 32},
{"PgUp", 33},
{"Num Lock", 34},
{"Kpd /", 35},
{"Kpd *", 36},
{"Kpd -", 37},
{"Tab", 38},
{"Delete", 52},
{"End", 53},
{"PgDn", 54},
{"Kpd 7", 55},
{"Kpd 8", 56},
{"Kpd 9", 57},
{"Kpd +", 58},
{"Caps Lock", 59},
{"Enter", 71},
{"Kpd 4", 72},
{"Kpd 5", 73},
{"Kpd 6", 74},
{"L.Shift", 75},
{"R.Shift", 86},
{"Up", 87},
{"Kpd 1", 88},
{"Kpd 2", 89},
{"Kpd 3", 90},
{"Kpd Entr", 91},
{"L.Control", 92},
{"L.Alt", 93},
{"Space", 94},
{"R.Alt", 95},
{"R.Control", 96},
{"Left", 97},
{"Down", 98},
{"Right", 99},
{"Kpd 0", 100},
{"Kpd .", 101},
{"L.Command", 102},
{"R.Command", 103},
{"Menu", 104},
{"PowerOn", 107},
};
static const char* keyDescriptions[NUM_KEYS];
static char utfDescriptions[NUM_KEYS * MAX_UTF8_LENGTH];
static const char*
FindSpecialKeyLabelFor(uint8 keyCode, uint32& last)
{
while ((keyLabels[last].fKeyCode < keyCode)
&& (last < (sizeof(keyLabels) / sizeof(struct KeyLabelMap)) - 1)) {
last++;
}
if (keyLabels[last].fKeyCode == keyCode)
return keyLabels[last].fLabel;
else
return NULL;
}
void
InitKeyIndices()
{
uint32 nextSpecial = 0;
key_map* map;
char* keys;
get_key_map(&map, &keys);
if (map == NULL || keys == NULL)
return;
for (uint8 j = 0; j < NUM_KEYS; j++) {
keyDescriptions[j] = NULL;
const char* specialLabel = FindSpecialKeyLabelFor(j, nextSpecial);
int32 keyCode = map->normal_map[j];
if (keyCode >= 0) {
const char* mapDesc = &keys[keyCode];
uint8 length = *mapDesc;
for (int m = 0; m < MAX_UTF8_LENGTH; m++)
if (m < length)
utfDescriptions[j * MAX_UTF8_LENGTH + m] = mapDesc[m + 1];
else
utfDescriptions[j * MAX_UTF8_LENGTH + m] = '\0';
if (specialLabel != NULL)
keyDescriptions[j] = specialLabel;
else {
char& c = utfDescriptions[j * MAX_UTF8_LENGTH];
if ((length == 1) && (isalpha(c)))
c = toupper(c);
if (length > 1 || (length == 1 && c > ' '))
keyDescriptions[j] = &c;
}
} else
utfDescriptions[j * MAX_UTF8_LENGTH] = 0x00;
}
free(keys);
free(map);
}
const char*
GetKeyUTF8(uint8 keyIndex)
{
return &utfDescriptions[keyIndex * MAX_UTF8_LENGTH];
}
const char*
GetKeyName(uint32 keyIndex)
{
if (keyIndex >= NUM_KEYS)
return NULL;
return keyDescriptions[keyIndex];
}
BString
GetFallbackKeyName(uint32 keyCode)
{
BString keyCodeName = "KeyCode ";
std::stringstream sstream;
sstream << std::hex << keyCode;
keyCodeName.Append(sstream.str().c_str());
return keyCodeName;
}
int
GetNumKeyIndices()
{
return NUM_KEYS;
}
uint32
FindKeyCode(const char* keyName)
{
if (strncmp(keyName, "KeyCode ", 7) == 0)
return strtoul(keyName + 7, NULL, 16);
for (uint8 i = 0; i < NUM_KEYS; i++) {
if ((keyDescriptions[i])
&& (strcasecmp(keyName, keyDescriptions[i]) == 0)) {
return i;
}
}
return 0;
}