keymap.cpp

Go to the documentation of this file.
00001 /* ES40 emulator.
00002  * Copyright (C) 2007-2008 by the ES40 Emulator Project
00003  *
00004  * WWW    : http://sourceforge.net/projects/es40
00005  * E-mail : camiel@camicom.com
00006  * 
00007  *  This file is based upon Bochs.
00008  *
00009  *  Copyright (C) 2002  MandrakeSoft S.A.
00010  *
00011  *    MandrakeSoft S.A.
00012  *    43, rue d'Aboukir
00013  *    75002 Paris - France
00014  *    http://www.linux-mandrake.com/
00015  *    http://www.mandrakesoft.com/
00016  *
00017  *  This library is free software; you can redistribute it and/or
00018  *  modify it under the terms of the GNU Lesser General Public
00019  *  License as published by the Free Software Foundation; either
00020  *  version 2 of the License, or (at your option) any later version.
00021  *
00022  *  This library is distributed in the hope that it will be useful,
00023  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00024  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00025  *  Lesser General Public License for more details.
00026  *
00027  *  You should have received a copy of the GNU Lesser General Public
00028  *  License along with this library; if not, write to the Free Software
00029  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
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 // I'll add these to the keymap object in a minute.
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   // chop off newline
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   // find first nonspace
00172   while(*lineptr && isspace(*lineptr))
00173     lineptr++;
00174   if(!*lineptr)
00175     return -1;              // nothing but spaces until end of line
00176   if(*lineptr == '#')
00177     return -1;              // nothing but a comment
00178 
00179   // copy nonspaces into the output
00180   while(*lineptr && !isspace(*lineptr))
00181     *copyp++ = *lineptr++;
00182   *copyp = 0;               // null terminate the copy
00183 
00184   // there must be at least one nonspace, since that's why we stopped the
00185   // first loop!
00186   //  BX_ASSERT (copyp != output);
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;            // EOF
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;             // truncate bxsym.
00210         p++;                // move one char beyond the +
00211         strcpy(modsym, p);  // copy the rest to modsym
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     // no words on this line, keep reading.
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   // Read keymap file one line at a time
00293   while(1)
00294   {
00295     if(get_next_keymap_line(keymapFile, baseSym, modSym, &ascii, hostSym) < 0)
00296     {
00297       break;
00298     }
00299 
00300     // convert X_KEY_* symbols to values
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     // Check if data is valid
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   // We look through the bx_key_symbol table to find the searched string
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   // Key is not known
00362   return BX_KEYMAP_UNKNOWN;
00363 }
00364 
00369 BXKeyEntry* bx_keymap_c::findHostKey(u32 key)
00370 {
00371 
00372   // We look through the keymap table to find the searched key
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   // Return default
00385   return NULL;
00386 }
00387 
00392 BXKeyEntry* bx_keymap_c::findAsciiChar(u8 ch)
00393 {
00394   BX_DEBUG(("findAsciiChar (0x%02x)", ch));
00395 
00396   // We look through the keymap table to find the searched key
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   // Return default
00409   return NULL;
00410 }
00411 
00412 const char* bx_keymap_c::getBXKeyName(u32 key)
00413 {
00414   return bx_key_symbol[key & 0x7fffffff];
00415 }

SourceForge.net Logo
Project space on SourceForge.net