00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00058 #include "../StdAfx.h"
00059 #include "gui.h"
00060 #include "keymap.h"
00061 #include "../System.h"
00062
00063 const char* bx_key_symbol[BX_KEY_NBKEYS] = {
00064 "BX_KEY_CTRL_L", "BX_KEY_SHIFT_L", "BX_KEY_F1",
00065 "BX_KEY_F2", "BX_KEY_F3", "BX_KEY_F4",
00066 "BX_KEY_F5", "BX_KEY_F6", "BX_KEY_F7",
00067 "BX_KEY_F8", "BX_KEY_F9", "BX_KEY_F10",
00068 "BX_KEY_F11", "BX_KEY_F12", "BX_KEY_CTRL_R",
00069 "BX_KEY_SHIFT_R", "BX_KEY_CAPS_LOCK", "BX_KEY_NUM_LOCK",
00070 "BX_KEY_ALT_L", "BX_KEY_ALT_R", "BX_KEY_A",
00071 "BX_KEY_B", "BX_KEY_C", "BX_KEY_D",
00072 "BX_KEY_E", "BX_KEY_F", "BX_KEY_G",
00073 "BX_KEY_H", "BX_KEY_I", "BX_KEY_J",
00074 "BX_KEY_K", "BX_KEY_L", "BX_KEY_M",
00075 "BX_KEY_N", "BX_KEY_O", "BX_KEY_P",
00076 "BX_KEY_Q", "BX_KEY_R", "BX_KEY_S",
00077 "BX_KEY_T", "BX_KEY_U", "BX_KEY_V",
00078 "BX_KEY_W", "BX_KEY_X", "BX_KEY_Y",
00079 "BX_KEY_Z", "BX_KEY_0", "BX_KEY_1",
00080 "BX_KEY_2", "BX_KEY_3", "BX_KEY_4",
00081 "BX_KEY_5", "BX_KEY_6", "BX_KEY_7",
00082 "BX_KEY_8", "BX_KEY_9", "BX_KEY_ESC",
00083 "BX_KEY_SPACE", "BX_KEY_SINGLE_QUOTE", "BX_KEY_COMMA",
00084 "BX_KEY_PERIOD", "BX_KEY_SLASH", "BX_KEY_SEMICOLON",
00085 "BX_KEY_EQUALS", "BX_KEY_LEFT_BRACKET", "BX_KEY_BACKSLASH",
00086 "BX_KEY_RIGHT_BRACKET", "BX_KEY_MINUS", "BX_KEY_GRAVE",
00087 "BX_KEY_BACKSPACE", "BX_KEY_ENTER", "BX_KEY_TAB",
00088 "BX_KEY_LEFT_BACKSLASH", "BX_KEY_PRINT", "BX_KEY_SCRL_LOCK",
00089 "BX_KEY_PAUSE", "BX_KEY_INSERT", "BX_KEY_DELETE",
00090 "BX_KEY_HOME", "BX_KEY_END", "BX_KEY_PAGE_UP",
00091 "BX_KEY_PAGE_DOWN", "BX_KEY_KP_ADD", "BX_KEY_KP_SUBTRACT",
00092 "BX_KEY_KP_END", "BX_KEY_KP_DOWN", "BX_KEY_KP_PAGE_DOWN",
00093 "BX_KEY_KP_LEFT", "BX_KEY_KP_RIGHT", "BX_KEY_KP_HOME",
00094 "BX_KEY_KP_UP", "BX_KEY_KP_PAGE_UP", "BX_KEY_KP_INSERT",
00095 "BX_KEY_KP_DELETE", "BX_KEY_KP_5", "BX_KEY_UP",
00096 "BX_KEY_DOWN", "BX_KEY_LEFT", "BX_KEY_RIGHT",
00097 "BX_KEY_KP_ENTER", "BX_KEY_KP_MULTIPLY", "BX_KEY_KP_DIVIDE",
00098 "BX_KEY_WIN_L", "BX_KEY_WIN_R", "BX_KEY_MENU",
00099 "BX_KEY_ALT_SYSREQ", "BX_KEY_CTRL_BREAK", "BX_KEY_INT_BACK",
00100 "BX_KEY_INT_FORWARD", "BX_KEY_INT_STOP", "BX_KEY_INT_MAIL",
00101 "BX_KEY_INT_SEARCH", "BX_KEY_INT_FAV", "BX_KEY_INT_HOME",
00102 "BX_KEY_POWER_MYCOMP", "BX_KEY_POWER_CALC", "BX_KEY_POWER_SLEEP",
00103 "BX_KEY_POWER_POWER", "BX_KEY_POWER_WAKE",
00104 };
00105
00106 bx_keymap_c* bx_keymap;
00107
00108 bx_keymap_c::bx_keymap_c(CConfigurator* cfg)
00109 {
00110 keymapCount = 0;
00111 keymapTable = (BXKeyEntry*) NULL;
00112 myCfg = cfg;
00113 }
00114
00115 bx_keymap_c::~bx_keymap_c(void)
00116 {
00117 if(keymapTable != NULL)
00118 {
00119 free(keymapTable);
00120 keymapTable = (BXKeyEntry*) NULL;
00121 }
00122
00123 keymapCount = 0;
00124 }
00125
00130 void bx_keymap_c::loadKeymap(u32 stringToSymbol (const char*))
00131 {
00132 if(myCfg->get_bool_value("keyboard.use_mapping", false))
00133 loadKeymap(stringToSymbol, myCfg->get_text_value("keyboard.map", "keys.map"));
00134 }
00135
00139 bool bx_keymap_c::isKeymapLoaded()
00140 {
00141 return(keymapCount > 0);
00142 }
00143
00145
00146 static unsigned char* lineptr = NULL;
00147 static int lineCount;
00148
00149 static void init_parse()
00150 {
00151 lineCount = 0;
00152 }
00153
00154 static void init_parse_line(char* line_to_parse)
00155 {
00156
00157
00158 lineptr = (unsigned char*) line_to_parse;
00159
00160 char* nl;
00161 if((nl = strchr(line_to_parse, '\n')) != NULL)
00162 {
00163 *nl = 0;
00164 }
00165 }
00166
00167 static s32 get_next_word(char* output)
00168 {
00169 char* copyp = output;
00170
00171
00172 while(*lineptr && isspace(*lineptr))
00173 lineptr++;
00174 if(!*lineptr)
00175 return -1;
00176 if(*lineptr == '#')
00177 return -1;
00178
00179
00180 while(*lineptr && !isspace(*lineptr))
00181 *copyp++ = *lineptr++;
00182 *copyp = 0;
00183
00184
00185
00186
00187 return 0;
00188 }
00189
00190 static s32 get_next_keymap_line(FILE* fp, char* bxsym, char* modsym,
00191 s32* ascii, char* hostsym)
00192 {
00193 char line[256];
00194 char buf[256];
00195 line[0] = 0;
00196 while(1)
00197 {
00198 lineCount++;
00199 if(!fgets(line, sizeof(line) - 1, fp))
00200 return -1;
00201 init_parse_line(line);
00202 if(get_next_word(bxsym) >= 0)
00203 {
00204 modsym[0] = 0;
00205
00206 char* p;
00207 if((p = strchr(bxsym, '+')) != NULL)
00208 {
00209 *p = 0;
00210 p++;
00211 strcpy(modsym, p);
00212 }
00213
00214 if(get_next_word(buf) < 0)
00215 {
00216 BX_PANIC(("keymap line %d: expected 3 columns", lineCount));
00217 return -1;
00218 }
00219
00220 if(buf[0] == '\'' && buf[2] == '\'' && buf[3] == 0)
00221 {
00222 *ascii = (u8) buf[1];
00223 }
00224 else if(!strcmp(buf, "space"))
00225 {
00226 *ascii = ' ';
00227 }
00228 else if(!strcmp(buf, "return"))
00229 {
00230 *ascii = '\n';
00231 }
00232 else if(!strcmp(buf, "tab"))
00233 {
00234 *ascii = '\t';
00235 }
00236 else if(!strcmp(buf, "backslash"))
00237 {
00238 *ascii = '\\';
00239 }
00240 else if(!strcmp(buf, "apostrophe"))
00241 {
00242 *ascii = '\'';
00243 }
00244 else if(!strcmp(buf, "none"))
00245 {
00246 *ascii = -1;
00247 }
00248 else
00249 {
00250 BX_PANIC((
00251 "keymap line %d: ascii equivalent is \"%s\" but it must be char constant like 'x', or one of space,tab,return,none",
00252 lineCount, buf));
00253 }
00254
00255 if(get_next_word(hostsym) < 0)
00256 {
00257 BX_PANIC(("keymap line %d: expected 3 columns", lineCount));
00258 return -1;
00259 }
00260
00261 return 0;
00262 }
00263
00264
00265 }
00266 }
00267
00271 void bx_keymap_c::loadKeymap(u32 stringToSymbol (const char*),
00272 const char *filename)
00273 {
00274 FILE* keymapFile;
00275 char baseSym[256];
00276 char modSym[256];
00277 char hostSym[256];
00278 s32 ascii = 0;
00279 u32 baseKey;
00280 u32 modKey;
00281 u32 hostKey;
00282
00283 if((keymapFile = fopen(filename, "r")) == NULL)
00284 {
00285 BX_PANIC(("Can not open keymap file '%s'.", filename));
00286 return;
00287 }
00288
00289 BX_INFO(("Loading keymap from '%s'", filename));
00290 init_parse();
00291
00292
00293 while(1)
00294 {
00295 if(get_next_keymap_line(keymapFile, baseSym, modSym, &ascii, hostSym) < 0)
00296 {
00297 break;
00298 }
00299
00300
00301 baseKey = convertStringToBXKey(baseSym);
00302 modKey = convertStringToBXKey(modSym);
00303 hostKey = 0;
00304 if(stringToSymbol != NULL)
00305 hostKey = stringToSymbol(hostSym);
00306
00307 BX_DEBUG((
00308 "baseKey='%s' (%d), modSym='%s' (%d), ascii=%d, guisym='%s' (%d)",
00309 baseSym, baseKey, modSym, modKey, ascii, hostSym, hostKey));
00310
00311
00312 if(baseKey == BX_KEYMAP_UNKNOWN)
00313 {
00314 BX_PANIC(("line %d: unknown BX_KEY constant '%s'", lineCount, baseSym));
00315 continue;
00316 }
00317
00318 if(hostKey == BX_KEYMAP_UNKNOWN)
00319 {
00320 BX_PANIC((
00321 "line %d: unknown host key name '%s' (wrong keymap ?)", lineCount,
00322 hostSym));
00323 continue;
00324 }
00325
00326 CHECK_REALLOCATION(keymapTable,
00327 realloc(keymapTable, (keymapCount + 1) * sizeof(BXKeyEntry)),
00328 BXKeyEntry);
00329
00330 if(keymapTable == NULL)
00331 BX_PANIC(("Can not allocate memory for keymap table."));
00332
00333 keymapTable[keymapCount].baseKey = baseKey;
00334 keymapTable[keymapCount].modKey = modKey;
00335 keymapTable[keymapCount].ascii = ascii;
00336 keymapTable[keymapCount].hostKey = hostKey;
00337
00338 keymapCount++;
00339 }
00340
00341 BX_INFO(("Loaded %d symbols", keymapCount));
00342
00343 fclose(keymapFile);
00344 }
00345
00349 u32 bx_keymap_c::convertStringToBXKey(const char* string)
00350 {
00351
00352
00353 for(u16 i = 0; i < BX_KEY_NBKEYS; i++)
00354 {
00355 if(strcmp(string, bx_key_symbol[i]) == 0)
00356 {
00357 return i;
00358 }
00359 }
00360
00361
00362 return BX_KEYMAP_UNKNOWN;
00363 }
00364
00369 BXKeyEntry* bx_keymap_c::findHostKey(u32 key)
00370 {
00371
00372
00373 for(u16 i = 0; i < keymapCount; i++)
00374 {
00375 if(keymapTable[i].hostKey == key)
00376 {
00377 BX_DEBUG(("key 0x%02x matches hostKey for entry #%d", key, i));
00378 return &keymapTable[i];
00379 }
00380 }
00381
00382 BX_DEBUG(("key %02x matches no entries", key));
00383
00384
00385 return NULL;
00386 }
00387
00392 BXKeyEntry* bx_keymap_c::findAsciiChar(u8 ch)
00393 {
00394 BX_DEBUG(("findAsciiChar (0x%02x)", ch));
00395
00396
00397 for(u16 i = 0; i < keymapCount; i++)
00398 {
00399 if(keymapTable[i].ascii == ch)
00400 {
00401 BX_DEBUG(("key %02x matches ascii for entry #%d", ch, i));
00402 return &keymapTable[i];
00403 }
00404 }
00405
00406 BX_DEBUG(("key 0x%02x matches no entries", ch));
00407
00408
00409 return NULL;
00410 }
00411
00412 const char* bx_keymap_c::getBXKeyName(u32 key)
00413 {
00414 return bx_key_symbol[key & 0x7fffffff];
00415 }