Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

KeyMap.cpp

Go to the documentation of this file.
00001 /*
00002  * KeyMap.cpp
00003  *
00004  * Part of Fly! Legacy project
00005  *
00006  * Copyright 2003 Chris Wallace
00007  *
00008  * Fly! Legacy is free software; you can redistribute it and/or modify
00009  *   it under the terms of the GNU General Public License as published by
00010  *   the Free Software Foundation; either version 2 of the License, or
00011  *   (at your option) any later version.
00012  *
00013  * Fly! Legacy is distributed in the hope that it will be useful,
00014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  *   GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  *   along with Fly! Legacy; if not, write to the Free Software
00020  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  */
00023 
00035 #include "../Include/KeyMap.h"
00036 #include "../Include/Utility.h"
00037 #include "../Include/Globals.h"
00038 #include "../Include/Ui.h"
00039 
00040 using namespace std;
00041 
00042 
00043 //
00044 // CKeyDefinition
00045 //
00046 CKeyDefinition::CKeyDefinition (void)
00047 : kyid (0), code (0), user (true), enab (true), cb (NULL)
00048 {
00049   strcpy (name, "");
00050 }
00051 
00052 int CKeyDefinition::Read (SStream *stream, Tag tag)
00053 {
00054   int rc = TAG_IGNORED;
00055 
00056   switch (tag) {
00057   case 'kyid':
00058     // Key unique ID
00059     ReadTag (&kyid, stream);
00060     rc = TAG_READ;
00061     break;
00062 
00063   case 'name':
00064     // Key name
00065     ReadString (name, 64, stream);
00066     rc = TAG_READ;
00067     break;
00068 
00069   case 'code':
00070     // Key code and modifier
00071     ReadInt (&code, stream);
00072     rc = TAG_READ;
00073     break;
00074 
00075   case 'user':
00076     // User-mappable?
00077     {
00078       int i;
00079       ReadInt (&i, stream);
00080       user = (i != 0);
00081     }
00082     rc = TAG_READ;
00083     break;
00084 
00085   case 'enab':
00086     // Enabled?
00087     {
00088       int i;
00089       ReadInt (&i, stream);
00090       enab = (i != 0);
00091     }
00092     rc = TAG_READ;
00093     break;
00094   }
00095 
00096   if (rc == TAG_IGNORED) {
00097     char s[16];
00098     TagToString (s, tag);
00099     globals->logWarning->Write ("CKeyDefinition::Read : Unknown tag %s", s);
00100   }
00101   
00102   return rc;
00103 }
00104 
00105 char* CKeyDefinition::GetName (void)
00106 {
00107   return name;
00108 }
00109 
00110 int CKeyDefinition::GetCode (void)
00111 {
00112   return code;
00113 }
00114 
00115 
00116 //
00117 // CKeySet
00118 //
00119 CKeySet::CKeySet (Tag tag)
00120 : kset (tag), user (true), enab (true)
00121 {
00122   strcpy (name, "");
00123 }
00124 
00125 CKeySet::~CKeySet (void)
00126 {
00127   // Delete key definitions
00128   map<Tag,CKeyDefinition*>::iterator i;
00129   for (i=kkey.begin(); i!=kkey.end(); i++) {
00130     delete i->second;
00131   }
00132 }
00133 
00134 int CKeySet::Read (SStream *stream, Tag tag)
00135 {
00136   int rc = TAG_IGNORED;
00137 
00138   switch (tag) {
00139   case 'name':
00140     // Key set name
00141     ReadString (name, 64, stream);
00142     rc = TAG_READ;
00143     break;
00144 
00145   case 'user':
00146     // Are keys in this key set user-mappable?
00147     {
00148       int i;
00149       ReadInt (&i, stream);
00150       user = (i != 0);
00151     }
00152     rc = TAG_READ;
00153     break;
00154 
00155   case 'enab':
00156     // Is this key set enabled?
00157     {
00158       int i;
00159       ReadInt (&i, stream);
00160       enab = (i != 0);
00161     }
00162     rc = TAG_READ;
00163     break;
00164 
00165   case 'kkey':
00166     // Key definition sub-object
00167     {
00168       CKeyDefinition *kkeyObj = new CKeyDefinition;
00169       ReadFrom (kkeyObj, stream);
00170       kkey[kkeyObj->kyid] = kkeyObj;
00171     }
00172     rc = TAG_READ;
00173     break;
00174   }
00175 
00176   if (rc == TAG_IGNORED) {
00177     char s[16];
00178     TagToString (s, tag);
00179     globals->logWarning->Write ("CKeySet::Read : Unknown tag %s", s);
00180   }
00181 
00182   return rc;
00183 }
00184 
00185 char* CKeySet::GetName (void)
00186 {
00187   return name;
00188 }
00189 
00190 bool CKeySet::GetUserModifiableState (void)
00191 {
00192   return user;
00193 }
00194 
00195 bool CKeySet::GetEnabledState (void)
00196 {
00197   return enab;
00198 }
00199 
00200 int CKeySet::GetNumKeyDefinitions (void)
00201 {
00202   return kkey.size();
00203 }
00204 
00205 
00206 CKeyDefinition* CKeySet::GetKeyDefinition (int i)
00207 {
00208   CKeyDefinition *rc = NULL;
00209 
00210   if (i <= GetNumKeyDefinitions()) {
00211     map<Tag,CKeyDefinition*>::iterator iter = kkey.begin();
00212     for (int count=i; count>0; count--, iter++);
00213     rc = iter->second;
00214   }
00215 
00216   return rc;
00217 }
00218 
00219 
00220 //
00221 // CKeyMap
00222 //
00223 CKeyMap::CKeyMap (const char* keyFilename)
00224 : vers (0)
00225 {
00226   SStream *s = new SStream;
00227   strcpy (s->filename, keyFilename);
00228   strcpy (s->mode, "r");
00229   OpenStream (s);
00230   if (s->stream) {
00231     ReadFrom (this, s);
00232   } else {
00233     gtfo ("ERROR : Could not read key mappings from System\\Default.key");
00234   }
00235   CloseStream (s);
00236   delete s;
00237 }
00238 
00239 CKeyMap::~CKeyMap (void)
00240 {
00241   // Delete key sets
00242   map<Tag,CKeySet*>::iterator i;
00243   for (i=kset.begin(); i!=kset.end(); i++) {
00244     delete i->second;
00245   }
00246 }
00247 
00248 int CKeyMap::Read (SStream *stream, Tag tag)
00249 {
00250   int rc = TAG_IGNORED;
00251 
00252   switch (tag) {
00253   case 'vers':
00254     // Version
00255     ReadInt (&vers, stream);
00256     rc = TAG_READ;
00257     break;
00258 
00259   case 'kset':
00260     // KeySet sub-object
00261     {
00262       Tag ksetTag;
00263       ReadTag (&ksetTag, stream);
00264       CKeySet *ksetObj = new CKeySet (ksetTag);
00265       ReadFrom (ksetObj, stream);
00266       kset[ksetObj->kset] = ksetObj;
00267     }
00268     rc = TAG_READ;
00269     break;
00270   }
00271 
00272   if (rc == TAG_IGNORED) {
00273     char s[16];
00274     TagToString (s, tag);
00275     globals->logWarning->Write ("CKeyMap::Read : Unknown tag %s", s);
00276   }
00277 
00278   return rc;
00279 }
00280 
00281 typedef struct {
00282   EKeyboardKeys kbkey;
00283   char      *name;
00284 } SKeyCodeFormatEntry;
00285 
00286 static SKeyCodeFormatEntry keyCodeFormatTable[] =
00287 {
00288   { KB_KEY_ESC,                   "Esc" },
00289   { KB_KEY_1,                     "1" },
00290   { KB_KEY_2,                     "2" },
00291   { KB_KEY_3,                     "3" },
00292   { KB_KEY_4,                     "4" },
00293   { KB_KEY_5,                     "5" },
00294   { KB_KEY_6,                     "6" },
00295   { KB_KEY_7,                     "7" },
00296   { KB_KEY_8,                     "8" },
00297   { KB_KEY_9,                     "9" },
00298   { KB_KEY_0,                     "0" },
00299   { KB_KEY_MINUS,                 "-" },
00300   { KB_KEY_EQUALS,                "=" },
00301   { KB_KEY_BACKSPACE,             "Backspace" },
00302   { KB_KEY_TAB,                   "Tab" },
00303   { KB_KEY_Q,                     "Q" },
00304   { KB_KEY_W,                     "W" },
00305   { KB_KEY_E,                     "E" },
00306   { KB_KEY_R,                     "R" },
00307   { KB_KEY_T,                     "T" },
00308   { KB_KEY_Y,                     "Y" },
00309   { KB_KEY_U,                     "U" },
00310   { KB_KEY_I,                     "I" },
00311   { KB_KEY_O,                     "O" },
00312   { KB_KEY_P,                     "P" },
00313   { KB_KEY_FORWARD_BRACKET,       "]" },
00314   { KB_KEY_REVERSE_BRACKET,       "[" },
00315   { KB_KEY_ENTER,                 "Enter" },
00316   { KB_KEY_LCTRL,                 "LeftCtrl" },
00317   { KB_KEY_A,                     "A" },
00318   { KB_KEY_S,                     "S" },
00319   { KB_KEY_D,                     "D" },
00320   { KB_KEY_F,                     "F" },
00321   { KB_KEY_G,                     "G" },
00322   { KB_KEY_H,                     "H" },
00323   { KB_KEY_J,                     "J" },
00324   { KB_KEY_K,                     "K" },
00325   { KB_KEY_L,                     "L" },
00326   { KB_KEY_SEMI_COLON,            ";" },
00327   { KB_KEY_SINGLE_QUOTE,          "'" },
00328   { KB_KEY_REVERSE_SINGLE_QUOTE,  "`" },
00329   { KB_KEY_LSHIFT,                "LeftShift" },
00330   { KB_KEY_BACKSLASH,             "\\" },
00331   { KB_KEY_Z,                     "Z" },
00332   { KB_KEY_X,                     "X" },
00333   { KB_KEY_C,                     "C" },
00334   { KB_KEY_V,                     "V" },
00335   { KB_KEY_B,                     "B" },
00336   { KB_KEY_N,                     "N" },
00337   { KB_KEY_M,                     "M" },
00338   { KB_KEY_COMMA,                 "," },
00339   { KB_KEY_PERIOD,                "." },
00340   { KB_KEY_SLASH,                 "/" },
00341   { KB_KEY_RSHIFT,                "RightShift" },
00342   { KB_KEY_STAR,                  "Star" },
00343   { KB_KEY_LALT,                  "LeftAlt" },
00344   { KB_KEY_SPACE,                 "Space" },
00345   { KB_KEY_CAPSLOCK,              "CapsLock" },
00346   { KB_KEY_F1,                    "F1" },
00347   { KB_KEY_F2,                    "F2" },
00348   { KB_KEY_F3,                    "F3" },
00349   { KB_KEY_F4,                    "F4" },
00350   { KB_KEY_F5,                    "F5" },
00351   { KB_KEY_F6,                    "F6" },
00352   { KB_KEY_F7,                    "F7" },
00353   { KB_KEY_F8,                    "F8" },
00354   { KB_KEY_F9,                    "F9" },
00355   { KB_KEY_F10,                   "F10" },
00356   { KB_KEY_NUMLOCK,               "NumLock" },
00357   { KB_KEY_SCROLLLOCK,            "ScrollLock" },
00358   { KB_KEY_HOME,                  "KeypadHome" },
00359   { KB_KEY_UP,                    "KeypadUpArrow" },
00360   { KB_KEY_PGUP,                  "KeypadPageUp" },
00361   { KB_KEY_KEYPAD_MINUS,          "KeypadMinus" },
00362   { KB_KEY_LEFT,                  "KeypadLeftArrow" },
00363   { KB_KEY_CENTER,                "KeypadCenter" },
00364   { KB_KEY_RIGHT,                 "KeypadRightArrow" },
00365   { KB_KEY_KEYPAD_PLUS,           "KeypadPlus" },
00366   { KB_KEY_END,                   "KeypadEnd" },
00367   { KB_KEY_DOWN,                  "KeypadDownArrow" },
00368   { KB_KEY_PGDN,                  "KeypadPageDown" },
00369   { KB_KEY_INSERT,                "KeypadIns" },
00370   { KB_KEY_DEL,                   "KeypadDel" },
00371   { KB_KEY_F11,                   "F11" },
00372   { KB_KEY_F12,                   "F12" },
00373   { KB_KEY_KEYPAD_ENTER,          "KeypadEnter" },
00374   { KB_KEY_RCTRL,                 "RightCtrl" },
00375   { KB_KEY_KEYPAD_SLASH,          "KeypadSlash" },
00376   { KB_KEY_RALT,                  "RightAlt" },
00377   { KB_KEY_EXT_NUMLOCK,           "ExtNumLock" },
00378   { KB_KEY_GRAY_HOME,             "GrayHome" },
00379   { KB_KEY_GRAY_UP,               "GrayUpArrow" },
00380   { KB_KEY_GRAY_PGUP,             "GrayPageUp" },
00381   { KB_KEY_GRAY_LEFT,             "GrayLeftArrow" },
00382   { KB_KEY_GRAY_RIGHT,            "GrayRightArrow" },
00383   { KB_KEY_GRAY_END,              "GrayEnd" },
00384   { KB_KEY_GRAY_DOWN,             "GrayDownArrow" },
00385   { KB_KEY_GRAY_PGDN,             "GrayPageDown" },
00386   { KB_KEY_GRAY_INS,              "GrayIns" },
00387   { KB_KEY_GRAY_DEL,              "GrayDel" },
00388   { KB_KEY_META,                  "Meta" }
00389 };
00390 
00391 
00392 void formatKeyCode (char *s, int code)
00393 {
00394   strcpy (s, "");
00395 
00396   // Format modifiers
00397   int iMod = (code & 0xFFFF0000) >> 16;
00398   if (iMod & KB_MODIFIER_CTRL) strcat (s, "Ctrl ");
00399   if (iMod & KB_MODIFIER_ALT)  strcat (s, "Alt ");
00400   if (iMod & KB_MODIFIER_SHIFT) strcat (s, "Shift ");
00401   if (iMod & KB_MODIFIER_META)  strcat (s, "Meta ");
00402 
00403   int nKeys = sizeof(keyCodeFormatTable) / sizeof(SKeyCodeFormatEntry);
00404   int kbkey = (code & 0x0000FFFF);
00405   for (int i=0; i<nKeys; i++) {
00406     SKeyCodeFormatEntry *p = &keyCodeFormatTable[i];
00407     if (p->kbkey == kbkey) {
00408       strcat (s, p->name);
00409       break;
00410     }
00411   }
00412   return;
00413 }
00414 
00415 
00416 void CKeyMap::Print (FILE* f)
00417 {
00418   // Iterate over keysets
00419   map<Tag,CKeySet*>::iterator i;
00420   for (i=kset.begin(); i!=kset.end(); i++) {
00421     CKeySet *pKeySet = i->second;
00422 
00423     // Format key set unique ID
00424     char s[16];
00425     TagToString (s, pKeySet->kset);
00426     fprintf (f, "KeySet '%s' %s\n", s, pKeySet->name);
00427 
00428     // Iterate over key definitions within the keyset
00429     map<Tag,CKeyDefinition*>::iterator j;
00430     for (j=pKeySet->kkey.begin(); j!=pKeySet->kkey.end(); j++) {
00431       CKeyDefinition *pKeyDef = j->second;
00432 
00433       // Format key definition unique ID
00434       char sId[16];
00435       TagToString (sId, pKeyDef->kyid);
00436 
00437       // Format key code
00438       char sCode[32];
00439       formatKeyCode (sCode, pKeyDef->code);
00440 
00441       fprintf (f, "  '%s' %-40s  %s\n", sId, pKeyDef->name, sCode);
00442     }
00443   }
00444 }
00445 
00446 
00447 CKeyDefinition* CKeyMap::FindKeyDefinitionById (Tag id)
00448 {
00449   CKeyDefinition *rc = NULL;
00450 
00452   map<Tag,CKeySet*>::iterator i;
00453   for (i=kset.begin(); i!=kset.end(); i++) {
00454     CKeySet *pKeySet = i->second;
00455 
00456     // Search for key definition in this keyset
00457     map<Tag,CKeyDefinition*>::iterator j = pKeySet->kkey.find(id);
00458     if (j != pKeySet->kkey.end()) {
00459       // Found a match
00460       rc = j->second;
00461     }
00462   }
00463 
00464   return rc;
00465 }
00466 
00467 
00468 void CKeyMap::Bind (Tag id, KeyCallbackPtr f)
00469 {
00470   CKeyDefinition *def = FindKeyDefinitionById (id);
00471   if (def) def->cb = f;
00472 }
00473 
00474 
00475 void CKeyMap::KeyPress (EKeyboardKeys key, EKeyboardModifiers mod)
00476 {
00477   // Translate key and modifier into keycode
00478   int code = (mod << 16) + key;
00479 
00481 
00482   bool handled = false;
00483   map<Tag,CKeySet*>::iterator i;
00484   for (i=kset.begin(); i!=kset.end() && !handled; i++) {
00485     CKeySet *pKeySet = i->second;
00486 
00487     map<Tag,CKeyDefinition*>::iterator j;
00488     for (j=pKeySet->kkey.begin(); j!=pKeySet->kkey.end() && !handled; j++) {
00489       CKeyDefinition *pKeyDef = j->second;
00490 
00491       if (pKeyDef->code == code) {
00492         // Found a match; call its callback which will return true if
00493         //   the key is consumed
00494         if (pKeyDef->cb) {
00495           handled = pKeyDef->cb (pKeyDef->kyid, key, mod);
00496         }
00497       }
00498     }
00499   }
00500 }
00501 
00502 
00503 int CKeyMap::GetNumKeySets (void)
00504 {
00505   return kset.size();
00506 }
00507 
00508 
00509 CKeySet* CKeyMap::GetKeySet (int i)
00510 {
00511   CKeySet *rc = NULL;
00512 
00513   if (i <= GetNumKeySets()) {
00514     map<Tag,CKeySet*>::iterator iter = kset.begin();
00515     for (int count=i; count > 0; count--, iter++);
00516     rc = iter->second;
00517   }
00518 
00519   return rc;
00520 }
00521 
SourceForge.net Logo Documentation generated by doxygen