1/* 2 * Copyright 1999-2009 Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Jeremy Friesner 7 */ 8 9 10#include "KeyInfos.h" 11 12 13#include <stdio.h> 14#include <stdlib.h> 15#include <string.h> 16#include <ctype.h> 17 18 19#include <InterfaceDefs.h> 20 21 22#define NUM_KEYS 256 23#define MAX_UTF8_LENGTH 5 // up to 4 chars, plus a nul terminator 24 25struct KeyLabelMap { 26 const char* fLabel; 27 uint8 fKeyCode; 28}; 29 30// This is a table of keys-codes that have special, hard-coded labels. 31static const struct KeyLabelMap keyLabels[] = { 32 {"<unset>", 0}, 33 {"Esc", 1}, 34 {"F1", 2}, 35 {"F2", 3}, 36 {"F3", 4}, 37 {"F4", 5}, 38 {"F5", 6}, 39 {"F6", 7}, 40 {"F7", 8}, 41 {"F8", 9}, 42 {"F9", 10}, 43 {"F10", 11}, 44 {"F11", 12}, 45 {"F12", 13}, 46 {"SysRq", 14}, 47 {"ScrlLck", 15}, 48 {"Pause", 16}, 49 {"Bcksp", 30}, 50 {"Insert", 31}, 51 {"Home", 32}, 52 {"PgUp", 33}, 53 {"Num Lock", 34}, 54 {"Kpd /", 35}, 55 {"Kpd *", 36}, 56 {"Kpd -", 37}, 57 {"Tab", 38}, 58 {"Delete", 52}, 59 {"End", 53}, 60 {"PgDn", 54}, 61 {"Kpd 7", 55}, 62 {"Kpd 8", 56}, 63 {"Kpd 9", 57}, 64 {"Kpd +", 58}, 65 {"Caps Lock", 59}, 66 {"Enter", 71}, 67 {"Kpd 4", 72}, 68 {"Kpd 5", 73}, 69 {"Kpd 6", 74}, 70 {"L.Shift", 75}, 71 {"R.Shift", 86}, 72 {"Up", 87}, 73 {"Kpd 1", 88}, 74 {"Kpd 2", 89}, 75 {"Kpd 3", 90}, 76 {"Kpd Entr", 91}, 77 {"L.Control", 92}, 78 {"L.Alt", 93}, 79 {"Space", 94}, 80 {"R.Alt", 95}, 81 {"R.Control", 96}, 82 {"Left", 97}, 83 {"Down", 98}, 84 {"Right", 99}, 85 {"Kpd 0", 100}, 86 {"Kpd .", 101}, 87 {"L.Command", 102}, 88 {"R.Command", 103}, 89 {"Menu", 104}, 90 {"PowerOn", 107}, 91}; 92 93// Key description strings (e.g. "A" or "Escape"). Null if no description is 94// available. 95static const char* keyDescriptions[NUM_KEYS]; 96 97// series of optional up-to-(4+1)-byte terminated UTF-8 character strings... 98static char utfDescriptions[NUM_KEYS * MAX_UTF8_LENGTH]; 99 100static const char* FindSpecialKeyLabelFor(uint8 keyCode, int& last); 101 102static const char* 103FindSpecialKeyLabelFor(uint8 keyCode, int& last) 104{ 105 while ((keyLabels[last].fKeyCode < keyCode) 106 && (last < (sizeof(keyLabels) / sizeof(struct KeyLabelMap)) - 1)) 107 last++; 108 109 if (keyLabels[last].fKeyCode == keyCode) 110 return keyLabels[last].fLabel; 111 else 112 return NULL; 113} 114 115 116void 117InitKeyIndices() 118{ 119 int nextSpecial = 0; 120 key_map* map; 121 char* keys; 122 get_key_map(&map, &keys); 123 124 for (int j = 0; j < NUM_KEYS; j++) { 125 keyDescriptions[j] = NULL; // default 126 127 const char* slabel = FindSpecialKeyLabelFor(j, nextSpecial); 128 int keyCode = map->normal_map[j]; 129 130 if (keyCode >= 0) { 131 const char* mapDesc = &keys[keyCode]; 132 uint8 len = *mapDesc; 133 134 for (int m = 0; m < MAX_UTF8_LENGTH; m++) 135 if (m < len) 136 utfDescriptions[j * MAX_UTF8_LENGTH + m] = mapDesc[m + 1]; 137 else 138 utfDescriptions[j * MAX_UTF8_LENGTH + m] = '\0'; 139 140 if (slabel) 141 keyDescriptions[j] = slabel; 142 else { 143 // If it's an ASCII letter, capitalize it. 144 char& c = utfDescriptions[j * MAX_UTF8_LENGTH]; 145 146 if ((len == 1) && (isalpha(c))) 147 c = toupper(c); 148 149 if ((len > 1)||((len == 1) && (c > ' '))) 150 keyDescriptions[j] = &c; 151 } 152 } else 153 utfDescriptions[j * MAX_UTF8_LENGTH] = 0x00; 154 } 155 free(keys); 156 free(map); 157} 158 159 160const char* 161GetKeyUTF8(uint8 keyIndex) 162{ 163 return &utfDescriptions[keyIndex * MAX_UTF8_LENGTH]; 164} 165 166 167const char* 168GetKeyName(uint8 keyIndex) 169{ 170 return keyDescriptions[keyIndex]; 171} 172 173 174int 175GetNumKeyIndices() 176{ 177 return NUM_KEYS; 178} 179 180 181uint8 182FindKeyCode(const char* keyName) 183{ 184 for (int i = 0; i < NUM_KEYS; i++) 185 if ((keyDescriptions[i]) 186 && (strcasecmp(keyName, keyDescriptions[i]) == 0)) 187 return i; 188 return 0; // default to sentinel value 189} 190