00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <common/Keyboard.h>
00022 #include <common/Defines.h>
00023 #include <XML/XMLFile.h>
00024
00025 bool Keyboard::dvorak_ = false;
00026
00027 Keyboard *Keyboard::instance_ = 0;
00028
00029 Keyboard *Keyboard::instance()
00030 {
00031 if (!instance_)
00032 {
00033 instance_ = new Keyboard;
00034 }
00035
00036 return instance_;
00037 }
00038
00039 Keyboard::Keyboard() : keybHistCnt_(0), mHighSurrogate(0)
00040 {
00041
00042 }
00043
00044 Keyboard::~Keyboard()
00045 {
00046
00047 }
00048
00049 bool Keyboard::init()
00050 {
00051 SDL_EnableUNICODE(1);
00052 SDL_EnableKeyRepeat(250, 100);
00053 return true;
00054 }
00055
00056 unsigned int Keyboard::getKeyboardState()
00057 {
00058
00059 const unsigned int keymask = KMOD_LSHIFT | KMOD_RSHIFT | KMOD_LCTRL | KMOD_RCTRL |
00060 KMOD_LALT | KMOD_RALT | KMOD_LMETA | KMOD_RMETA;
00061
00062 return SDL_GetModState() & keymask;
00063 }
00064
00065 char *Keyboard::getkeyboardbuffer(unsigned int &bufCnt)
00066 {
00067 bufCnt = SDLK_LAST;
00068 return (char *) SDL_GetKeyState(NULL);
00069 }
00070
00071 KeyboardHistory::HistoryElement *Keyboard::getkeyboardhistory(unsigned int &histCnt)
00072 {
00073 histCnt = keybHistCnt_;
00074 keybHistCnt_=0;
00075
00076 return keybHist_;
00077 }
00078
00079 #define UTF16_IS_HIGH_SURROGATE(U) ((Uint16)((U) - 0xD800) < 0x0400)
00080 #define UTF16_IS_LOW_SURROGATE(U) ((Uint16)((U) - 0xDC00) < 0x0400)
00081 #define UTF16_SURROGATE_PAIR_TO_UTF32(H,L) (((H) << 10) + (L) - (0xD800 << 10) - 0xDC00 + 0x00010000)
00082
00083 void Keyboard::raiseUnicodeUTF16(Uint16 utf16, SDLKey key)
00084 {
00085
00086 if (keybHistCnt_ >= MAX_KEYBDHIST) return;
00087
00088 KeyboardHistory::HistoryElement newElement =
00089 {
00090 key,
00091 utf16
00092 };
00093
00094
00095 keybHist_[keybHistCnt_++] = newElement;
00096 }
00097
00098 void Keyboard::handleUnicodeUTF16(Uint16 utf16, SDLKey key)
00099 {
00100
00101
00102
00103
00104
00105
00106 if (mHighSurrogate == 0)
00107 {
00108 if (UTF16_IS_HIGH_SURROGATE(utf16))
00109 {
00110 mHighSurrogate = utf16;
00111 }
00112 else
00113 {
00114 raiseUnicodeUTF16(utf16, key);
00115 }
00116 }
00117 else
00118 {
00119 if (UTF16_IS_LOW_SURROGATE(utf16))
00120 {
00121
00122 raiseUnicodeUTF16(UTF16_SURROGATE_PAIR_TO_UTF32(mHighSurrogate, utf16), key);
00123 mHighSurrogate = 0;
00124 }
00125 else if (UTF16_IS_HIGH_SURROGATE(utf16))
00126 {
00127
00128 raiseUnicodeUTF16(mHighSurrogate, key);
00129 mHighSurrogate = utf16;
00130 }
00131 else
00132 {
00133
00134 raiseUnicodeUTF16(mHighSurrogate, key);
00135 mHighSurrogate = 0;
00136 raiseUnicodeUTF16(utf16, key);
00137 }
00138 }
00139 }
00140
00141 void Keyboard::processKeyboardEvent(SDL_Event &event)
00142 {
00143
00144 if (event.type != SDL_KEYDOWN) return;
00145
00146 handleUnicodeUTF16(event.key.keysym.unicode, event.key.keysym.sym);
00147 }
00148
00149 bool &Keyboard::getDvorak()
00150 {
00151 return dvorak_;
00152 }
00153
00154 void Keyboard::clear()
00155 {
00156 std::map<std::string, KeyboardKey *>::iterator itor;
00157 for (itor = keyMap_.begin();
00158 itor != keyMap_.end();
00159 itor++)
00160 {
00161 delete (*itor).second;
00162 }
00163 keyMap_.clear();
00164 keyList_.clear();
00165 commandKeys_.clear();
00166 }
00167
00168 bool Keyboard::saveKeyFile()
00169 {
00170 XMLNode keysNode("keys");
00171 std::list<std::string>::iterator itor;
00172 for (itor = keyList_.begin();
00173 itor != keyList_.end();
00174 itor++)
00175 {
00176 KeyboardKey *key = getKey((*itor).c_str());
00177 if (!key || !key->getChanged()) continue;
00178
00179 XMLNode *keyNode = new XMLNode("keyentry");
00180 if (key->getNameIsCommand())
00181 keyNode->addChild(new XMLNode("command", key->getName()));
00182 else keyNode->addChild(new XMLNode("name", key->getName()));
00183 keyNode->addChild(new XMLNode("title", key->getTitle()));
00184 keyNode->addChild(new XMLNode("description", key->getDescription()));
00185 keyNode->addChild(new XMLNode("group", S3D::formatStringBuffer("%i", key->getGroup())));
00186
00187 std::vector<KeyboardKey::KeyEntry> &keys = key->getKeys();
00188 std::vector<KeyboardKey::KeyEntry>::iterator subitor;
00189 for (subitor = keys.begin();
00190 subitor != keys.end();
00191 subitor++)
00192 {
00193 KeyboardKey::KeyEntry &subentry = (*subitor);
00194 const char *name = "";
00195 const char *state = "";
00196 KeyboardKey::translateKeyNameValue(subentry.key, name);
00197 KeyboardKey::translateKeyStateValue(subentry.state, state);
00198 XMLNode *subnode = new XMLNode("key", name);
00199 if (strcmp(state, "NONE") != 0) subnode->addParameter(
00200 new XMLNode("state", state, XMLNode::XMLParameterType));
00201 keyNode->addChild(subnode);
00202 }
00203
00204 keysNode.addChild(keyNode);
00205 }
00206
00207 std::string fileName = S3D::getSettingsFile("keys.xml");
00208 if (!keysNode.writeToFile(fileName)) return false;
00209
00210 return true;
00211 }
00212
00213 bool Keyboard::loadKeyFile(bool loadDefaults)
00214 {
00215
00216 clear();
00217
00218
00219 if (!loadKeyFile(S3D::getDataFile("data/keys.xml"), true)) return false;
00220
00221
00222 std::string fileName = S3D::getSettingsFile("keys.xml");
00223 if (S3D::fileExists(fileName) && !loadDefaults)
00224 {
00225 if (!loadKeyFile(fileName, false)) return false;
00226 }
00227
00228
00229 std::map<std::string, KeyboardKey *>::iterator keyItor;
00230 for (keyItor = keyMap_.begin();
00231 keyItor != keyMap_.end();
00232 keyItor++)
00233 {
00234 KeyboardKey *key = keyItor->second;
00235
00236
00237 if (key->getNameIsCommand()) commandKeys_.push_back(key);
00238
00239
00240 std::map<std::string, KeyboardKey *>::iterator dupeItor;
00241 for (dupeItor = keyMap_.begin();
00242 dupeItor != keyMap_.end();
00243 dupeItor++)
00244 {
00245 KeyboardKey *dupe = dupeItor->second;
00246 if (dupe == key) continue;
00247
00248 std::vector<KeyboardKey::KeyEntry> &dupeKeys = dupe->getKeys();
00249 std::vector<KeyboardKey::KeyEntry>::iterator itor;
00250 for (itor = dupeKeys.begin();
00251 itor != dupeKeys.end();
00252 itor++)
00253 {
00254 KeyboardKey::KeyEntry &entry = *itor;
00255 int keyIndex = key->keyIndex(entry.key, entry.state);
00256 if (keyIndex != -1)
00257 {
00258 const char *keyName = "", *stateName = "";
00259 KeyboardKey::translateKeyNameValue(entry.key, keyName);
00260 KeyboardKey::translateKeyStateValue(entry.state, stateName);
00261
00262 S3D::dialogMessage("Keyboard", S3D::formatStringBuffer(
00263 "Warning: Key \"%s\" and state \"%s\" defined for \"%s\" was also defined for \"%s\"",
00264 keyName, stateName, key->getName(), dupe->getName()));
00265
00266 key->removeKey(keyIndex);
00267 }
00268 }
00269 }
00270 }
00271
00272 return true;
00273 }
00274
00275 bool Keyboard::loadKeyFile(const std::string &fileName, bool masterFile)
00276 {
00277
00278 XMLFile file;
00279 if (!file.readFile(fileName))
00280 {
00281 S3D::dialogMessage("Keyboard", S3D::formatStringBuffer(
00282 "Failed to parse \"%s\"\n%s",
00283 fileName.c_str(),
00284 file.getParserError()));
00285 return false;
00286 }
00287
00288
00289 if (!file.getRootNode())
00290 {
00291 S3D::dialogMessage("Keyboard", S3D::formatStringBuffer(
00292 "Failed to find key definition file \"%s\"",
00293 fileName.c_str()));
00294 return false;
00295 }
00296
00297
00298 std::list<XMLNode *>::iterator childrenItor;
00299 std::list<XMLNode *> &children = file.getRootNode()->getChildren();
00300 for (childrenItor = children.begin();
00301 childrenItor != children.end();
00302 childrenItor++)
00303 {
00304
00305 XMLNode *currentNode = (*childrenItor);
00306 if (strcmp(currentNode->getName(), "keyentry"))
00307 {
00308 S3D::dialogMessage("Keyboard",
00309 "Failed to find keyentry node");
00310 return false;
00311 }
00312
00313
00314 const char *keyName = 0;
00315 bool command = false;
00316 XMLNode *nameNode;
00317 XMLNode *commandNode;
00318 if (currentNode->getNamedChild("name", nameNode, false))
00319 {
00320 keyName = nameNode->getContent();
00321 command = false;
00322 }
00323 else if (currentNode->getNamedChild("command", commandNode, false))
00324 {
00325 keyName = commandNode->getContent();
00326 command = true;
00327 }
00328 else
00329 {
00330 S3D::dialogMessage("Keyboard",
00331 "Failed to find name node");
00332 return false;
00333 }
00334
00335 if (masterFile)
00336 {
00337
00338
00339 std::map<std::string, KeyboardKey *>::iterator findItor =
00340 keyMap_.find(keyName);
00341 if (findItor != keyMap_.end())
00342 {
00343
00344 delete findItor->second;
00345 keyMap_.erase(findItor);
00346 }
00347 }
00348 else
00349 {
00350
00351
00352
00353
00354 std::map<std::string, KeyboardKey *>::iterator findItor =
00355 keyMap_.find(keyName);
00356 if (findItor != keyMap_.end())
00357 {
00358
00359 delete findItor->second;
00360 keyMap_.erase(findItor);
00361 }
00362 else
00363 {
00364
00365
00366 continue;
00367 }
00368 }
00369
00370
00371 XMLNode *descNode;
00372 if (!currentNode->getNamedChild("description", descNode)) return false;
00373 const char *keyDesc = descNode->getContent();
00374
00375
00376 int group = 0;
00377 if (!currentNode->getNamedChild("group", group)) return false;
00378
00379
00380 XMLNode *titleNode;
00381 if (!currentNode->getNamedChild("title", titleNode)) return false;
00382 const char *keyTitle = titleNode->getContent();
00383
00384
00385 XMLNode *currentKey = 0;
00386 std::list<std::string> keyNames, keyStateNames;
00387 while (currentNode->getNamedChild("key", currentKey, false))
00388 {
00389 const char *state = "NONE";
00390 XMLNode *stateNode;
00391 if (currentKey->getNamedParameter("state", stateNode, false))
00392 state = stateNode->getContent();
00393
00394
00395 keyNames.push_back(currentKey->getContent());
00396 keyStateNames.push_back(state);
00397 }
00398
00399
00400 KeyboardKey *newKey = new KeyboardKey(keyName, keyTitle, keyDesc, group, command);
00401 if (!newKey->addKeys(keyNames, keyStateNames)) return false;
00402 if (masterFile) newKey->setChanged(false);
00403
00404
00405 keyMap_[keyName] = newKey;
00406 if (masterFile) keyList_.push_back(keyName);
00407 if (!currentNode->failChildren()) return false;
00408 }
00409
00410 return true;
00411 }
00412
00413 KeyboardKey *Keyboard::getKey(const char *name)
00414 {
00415 static KeyboardKey defaultKey("None", "None", "None", 0, false);
00416
00417 std::map<std::string, KeyboardKey *>::iterator itor =
00418 keyMap_.find(name);
00419 if (itor != keyMap_.end()) return (*itor).second;
00420
00421 S3D::dialogMessage("Keyboard", S3D::formatStringBuffer(
00422 "Failed to find key for key name \"%s\"",
00423 name));
00424 return &defaultKey;
00425 }
00426