aboutsummaryrefslogtreecommitdiff
Commit message (Expand)AuthorAge
...
* Add srollbar formspec elementsapier2014-07-16
* Fix android build after removal of indev and math mapgensapier2014-07-16
* Fix crash reported here: https://forum.minetest.net/viewtopic.php?f=6&t=9726Novatux2014-07-13
* Move MapBlock (de)serializing code out of Database classsfan52014-07-12
* Remove proller from creditsproller2014-07-12
* Remove indev mapgenproller2014-07-12
* Remove math mapgenproller2014-07-12
* Update default control documentationBlockMen2014-07-07
* Switch back repository to dev-mode after 0.4.10 release.sapier2014-07-07
* Faces shading fixesRealBadAngel2014-07-07
* Don't copy back already generated blocks on map generationkwolekr2014-07-07
* Don't unload blocks if save failedkwolekr2014-07-07
* Fix regression in leveldb backendsapier2014-07-07
* Update version numbers for 0.4.10sapier2014-07-06
* Fix client crash on deletion of an object the clients localplayer is attached tosapier2014-07-06
* Switch android to leveldb as sqlite3 is broken and fails to save any mapblock...sapier2014-07-06
* Improve error reporting in leveldb backendsfan52014-07-06
* Fix non-smooth non-shader node shading (Fixes #1436, regression by commit a0f...Perttu Ahola2014-07-06
* Fix errors/warnings reported by valgrindsfan52014-07-06
* Fix memory leak in EmergeManagerPilzAdam2014-07-06
* Fix warnings reported by clangsfan52014-07-06
* Fix typos in doc/lua-api.txtsfan52014-07-05
* Remove FPS from being next to the version stringPerttu Ahola2014-07-05
* Fix typo in doc/lua_api.txtKahrl2014-07-05
* Fix memory leaks in GenericCAO, ShaderSource and Player classessapier2014-07-02
* Fix inversion of full_punch_intervalNovatux2014-07-02
* Move master server to seperate repositoryShadowNinja2014-06-30
* Fix regression in light calculationsapier2014-06-30
* Fix serverlist code style, const-correctness, and typesShadowNinja2014-06-30
* Fix server list boolean typing and alignmentShadowNinja2014-06-30
* Add support for multipart/form-data to HTTPFetch for server announcingShadowNinja2014-06-30
* Masterserver: Fix compiling servers.jstproller2014-06-30
* Add redis options to documentationsfan52014-06-29
* Copy zlib and freetype dll to windows package toosapier2014-06-29
* Add support for Android 2.3+sapier2014-06-29
* Don't spam server console on player/playersao error but just drop the affecte...sapier2014-06-29
* Glasslike_framed drawtype rework.RealBadAngel2014-06-29
* OS X compatibility fixesMartin Doege2014-06-29
* Fix msvc2012 buildsapier2014-06-29
* Add formspec api versioningsapier2014-06-29
* Make sure none of the irrlicht member objects of GenericCAO are deleted prior...sapier2014-06-29
* Make player files saving againSmallJoker2014-06-29
* Masterserver: Fix undefined playersproller2014-06-28
* Add prefixes to enum values and fix style issueskwolekr2014-06-28
* Make GUITable mouse wheel scrolling fasterKahrl2014-06-27
* Fix GenericCAO fails to grabing member animated mesh node to prevent it do be...sapier2014-06-27
* Fix wrong status text rectangle. Fix for #1412RealBadAngel2014-06-27
* Add separate download timeout to allow download of bigger files or on low ban...sapier2014-06-26
* Fix statement not set NULL on deletionsapier2014-06-25
* Add setting for tooltips show delay.RealBadAngel2014-06-25
/span> GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "keycode.h" #include "exceptions.h" #include "settings.h" #include "log.h" #include "debug.h" #include "util/hex.h" #include "util/string.h" #include "util/basic_macros.h" class UnknownKeycode : public BaseException { public: UnknownKeycode(const char *s) : BaseException(s) {}; }; struct table_key { const char *Name; irr::EKEY_CODE Key; wchar_t Char; // L'\0' means no character assigned const char *LangName; // NULL means it doesn't have a human description }; #define DEFINEKEY1(x, lang) /* Irrlicht key without character */ \ { #x, irr::x, L'\0', lang }, #define DEFINEKEY2(x, ch, lang) /* Irrlicht key with character */ \ { #x, irr::x, ch, lang }, #define DEFINEKEY3(ch) /* single Irrlicht key (e.g. KEY_KEY_X) */ \ { "KEY_KEY_" TOSTRING(ch), irr::KEY_KEY_ ## ch, (wchar_t) *TOSTRING(ch), TOSTRING(ch) }, #define DEFINEKEY4(ch) /* single Irrlicht function key (e.g. KEY_F3) */ \ { "KEY_F" TOSTRING(ch), irr::KEY_F ## ch, L'\0', "F" TOSTRING(ch) }, #define DEFINEKEY5(ch) /* key without Irrlicht keycode */ \ { ch, irr::KEY_KEY_CODES_COUNT, (wchar_t) *ch, ch }, #define N_(text) text static const struct table_key table[] = { // Keys that can be reliably mapped between Char and Key DEFINEKEY3(0) DEFINEKEY3(1) DEFINEKEY3(2) DEFINEKEY3(3) DEFINEKEY3(4) DEFINEKEY3(5) DEFINEKEY3(6) DEFINEKEY3(7) DEFINEKEY3(8) DEFINEKEY3(9) DEFINEKEY3(A) DEFINEKEY3(B) DEFINEKEY3(C) DEFINEKEY3(D) DEFINEKEY3(E) DEFINEKEY3(F) DEFINEKEY3(G) DEFINEKEY3(H) DEFINEKEY3(I) DEFINEKEY3(J) DEFINEKEY3(K) DEFINEKEY3(L) DEFINEKEY3(M) DEFINEKEY3(N) DEFINEKEY3(O) DEFINEKEY3(P) DEFINEKEY3(Q) DEFINEKEY3(R) DEFINEKEY3(S) DEFINEKEY3(T) DEFINEKEY3(U) DEFINEKEY3(V) DEFINEKEY3(W) DEFINEKEY3(X) DEFINEKEY3(Y) DEFINEKEY3(Z) DEFINEKEY2(KEY_PLUS, L'+', "+") DEFINEKEY2(KEY_COMMA, L',', ",") DEFINEKEY2(KEY_MINUS, L'-', "-") DEFINEKEY2(KEY_PERIOD, L'.', ".") // Keys without a Char DEFINEKEY1(KEY_LBUTTON, N_("Left Button")) DEFINEKEY1(KEY_RBUTTON, N_("Right Button")) DEFINEKEY1(KEY_CANCEL, N_("Cancel")) DEFINEKEY1(KEY_MBUTTON, N_("Middle Button")) DEFINEKEY1(KEY_XBUTTON1, N_("X Button 1")) DEFINEKEY1(KEY_XBUTTON2, N_("X Button 2")) DEFINEKEY1(KEY_BACK, N_("Back")) DEFINEKEY1(KEY_TAB, N_("Tab")) DEFINEKEY1(KEY_CLEAR, N_("Clear")) DEFINEKEY1(KEY_RETURN, N_("Return")) DEFINEKEY1(KEY_SHIFT, N_("Shift")) DEFINEKEY1(KEY_CONTROL, N_("Control")) DEFINEKEY1(KEY_MENU, N_("Menu")) DEFINEKEY1(KEY_PAUSE, N_("Pause")) DEFINEKEY1(KEY_CAPITAL, N_("Caps Lock")) DEFINEKEY1(KEY_SPACE, N_("Space")) DEFINEKEY1(KEY_PRIOR, N_("Prior")) DEFINEKEY1(KEY_NEXT, N_("Next")) DEFINEKEY1(KEY_END, N_("End")) DEFINEKEY1(KEY_HOME, N_("Home")) DEFINEKEY1(KEY_LEFT, N_("Left")) DEFINEKEY1(KEY_UP, N_("Up")) DEFINEKEY1(KEY_RIGHT, N_("Right")) DEFINEKEY1(KEY_DOWN, N_("Down")) DEFINEKEY1(KEY_SELECT, N_("Select")) DEFINEKEY1(KEY_PRINT, N_("Print")) DEFINEKEY1(KEY_EXECUT, N_("Execute")) DEFINEKEY1(KEY_SNAPSHOT, N_("Snapshot")) DEFINEKEY1(KEY_INSERT, N_("Insert")) DEFINEKEY1(KEY_DELETE, N_("Delete")) DEFINEKEY1(KEY_HELP, N_("Help")) DEFINEKEY1(KEY_LWIN, N_("Left Windows")) DEFINEKEY1(KEY_RWIN, N_("Right Windows")) DEFINEKEY1(KEY_NUMPAD0, N_("Numpad 0")) // These are not assigned to a char DEFINEKEY1(KEY_NUMPAD1, N_("Numpad 1")) // to prevent interference with KEY_KEY_[0-9]. DEFINEKEY1(KEY_NUMPAD2, N_("Numpad 2")) DEFINEKEY1(KEY_NUMPAD3, N_("Numpad 3")) DEFINEKEY1(KEY_NUMPAD4, N_("Numpad 4")) DEFINEKEY1(KEY_NUMPAD5, N_("Numpad 5")) DEFINEKEY1(KEY_NUMPAD6, N_("Numpad 6")) DEFINEKEY1(KEY_NUMPAD7, N_("Numpad 7")) DEFINEKEY1(KEY_NUMPAD8, N_("Numpad 8")) DEFINEKEY1(KEY_NUMPAD9, N_("Numpad 9")) DEFINEKEY1(KEY_MULTIPLY, N_("Numpad *")) DEFINEKEY1(KEY_ADD, N_("Numpad +")) DEFINEKEY1(KEY_SEPARATOR, N_("Numpad .")) DEFINEKEY1(KEY_SUBTRACT, N_("Numpad -")) DEFINEKEY1(KEY_DECIMAL, NULL) DEFINEKEY1(KEY_DIVIDE, N_("Numpad /")) DEFINEKEY4(1) DEFINEKEY4(2) DEFINEKEY4(3) DEFINEKEY4(4) DEFINEKEY4(5) DEFINEKEY4(6) DEFINEKEY4(7) DEFINEKEY4(8) DEFINEKEY4(9) DEFINEKEY4(10) DEFINEKEY4(11) DEFINEKEY4(12) DEFINEKEY4(13) DEFINEKEY4(14) DEFINEKEY4(15) DEFINEKEY4(16) DEFINEKEY4(17) DEFINEKEY4(18) DEFINEKEY4(19) DEFINEKEY4(20) DEFINEKEY4(21) DEFINEKEY4(22) DEFINEKEY4(23) DEFINEKEY4(24) DEFINEKEY1(KEY_NUMLOCK, N_("Num Lock")) DEFINEKEY1(KEY_SCROLL, N_("Scroll Lock")) DEFINEKEY1(KEY_LSHIFT, N_("Left Shift")) DEFINEKEY1(KEY_RSHIFT, N_("Right Shift")) DEFINEKEY1(KEY_LCONTROL, N_("Left Control")) DEFINEKEY1(KEY_RCONTROL, N_("Right Control")) DEFINEKEY1(KEY_LMENU, N_("Left Menu")) DEFINEKEY1(KEY_RMENU, N_("Right Menu")) // Rare/weird keys DEFINEKEY1(KEY_KANA, "Kana") DEFINEKEY1(KEY_HANGUEL, "Hangul") DEFINEKEY1(KEY_HANGUL, "Hangul") DEFINEKEY1(KEY_JUNJA, "Junja") DEFINEKEY1(KEY_FINAL, "Final") DEFINEKEY1(KEY_KANJI, "Kanji") DEFINEKEY1(KEY_HANJA, "Hanja") DEFINEKEY1(KEY_ESCAPE, N_("IME Escape")) DEFINEKEY1(KEY_CONVERT, N_("IME Convert")) DEFINEKEY1(KEY_NONCONVERT, N_("IME Nonconvert")) DEFINEKEY1(KEY_ACCEPT, N_("IME Accept")) DEFINEKEY1(KEY_MODECHANGE, N_("IME Mode Change")) DEFINEKEY1(KEY_APPS, N_("Apps")) DEFINEKEY1(KEY_SLEEP, N_("Sleep")) #if !(IRRLICHT_VERSION_MAJOR <= 1 && IRRLICHT_VERSION_MINOR <= 7 && IRRLICHT_VERSION_REVISION < 3) DEFINEKEY1(KEY_OEM_1, "OEM 1") // KEY_OEM_[0-9] and KEY_OEM_102 are assigned to multiple DEFINEKEY1(KEY_OEM_2, "OEM 2") // different chars (on different platforms too) and thus w/o char DEFINEKEY1(KEY_OEM_3, "OEM 3") DEFINEKEY1(KEY_OEM_4, "OEM 4") DEFINEKEY1(KEY_OEM_5, "OEM 5") DEFINEKEY1(KEY_OEM_6, "OEM 6") DEFINEKEY1(KEY_OEM_7, "OEM 7") DEFINEKEY1(KEY_OEM_8, "OEM 8") DEFINEKEY1(KEY_OEM_AX, "OEM AX") DEFINEKEY1(KEY_OEM_102, "OEM 102") #endif DEFINEKEY1(KEY_ATTN, "Attn") DEFINEKEY1(KEY_CRSEL, "CrSel") DEFINEKEY1(KEY_EXSEL, "ExSel") DEFINEKEY1(KEY_EREOF, N_("Erase EOF")) DEFINEKEY1(KEY_PLAY, N_("Play")) DEFINEKEY1(KEY_ZOOM, N_("Zoom")) DEFINEKEY1(KEY_PA1, "PA1") DEFINEKEY1(KEY_OEM_CLEAR, N_("OEM Clear")) // Keys without Irrlicht keycode DEFINEKEY5("!") DEFINEKEY5("\"") DEFINEKEY5("#") DEFINEKEY5("$") DEFINEKEY5("%") DEFINEKEY5("&") DEFINEKEY5("'") DEFINEKEY5("(") DEFINEKEY5(")") DEFINEKEY5("*") DEFINEKEY5("/") DEFINEKEY5(":") DEFINEKEY5(";") DEFINEKEY5("<") DEFINEKEY5("=") DEFINEKEY5(">") DEFINEKEY5("?") DEFINEKEY5("@") DEFINEKEY5("[") DEFINEKEY5("\\") DEFINEKEY5("]") DEFINEKEY5("^") DEFINEKEY5("_") }; #undef N_ struct table_key lookup_keyname(const char *name) { for (u16 i = 0; i < ARRLEN(table); i++) { if (strcmp(table[i].Name, name) == 0) return table[i]; } throw UnknownKeycode(name); } struct table_key lookup_keykey(irr::EKEY_CODE key) { for (u16 i = 0; i < ARRLEN(table); i++) { if (table[i].Key == key) return table[i]; } std::ostringstream os; os << "<Keycode " << (int) key << ">"; throw UnknownKeycode(os.str().c_str()); } struct table_key lookup_keychar(wchar_t Char) { for (u16 i = 0; i < ARRLEN(table); i++) { if (table[i].Char == Char) return table[i]; } std::ostringstream os; os << "<Char " << hex_encode((char*) &Char, sizeof(wchar_t)) << ">"; throw UnknownKeycode(os.str().c_str()); } KeyPress::KeyPress() : Key(irr::KEY_KEY_CODES_COUNT), Char(L'\0'), m_name("") {} KeyPress::KeyPress(const char *name) { if (strlen(name) == 0) { Key = irr::KEY_KEY_CODES_COUNT; Char = L'\0'; m_name = ""; return; } else if (strlen(name) <= 4) { // Lookup by resulting character int chars_read = mbtowc(&Char, name, 1); FATAL_ERROR_IF(chars_read != 1, "Unexpected multibyte character"); try { struct table_key k = lookup_keychar(Char); m_name = k.Name; Key = k.Key; return; } catch (UnknownKeycode &e) {}; } else { // Lookup by name m_name = name; try { struct table_key k = lookup_keyname(name); Key = k.Key; Char = k.Char; return; } catch (UnknownKeycode &e) {}; } // It's not a known key, complain and try to do something Key = irr::KEY_KEY_CODES_COUNT; int chars_read = mbtowc(&Char, name, 1); FATAL_ERROR_IF(chars_read != 1, "Unexpected multibyte character"); m_name = ""; warningstream << "KeyPress: Unknown key '" << name << "', falling back to first char."; } KeyPress::KeyPress(const irr::SEvent::SKeyInput &in, bool prefer_character) { if (prefer_character) Key = irr::KEY_KEY_CODES_COUNT; else Key = in.Key; Char = in.Char; try { if (valid_kcode(Key)) m_name = lookup_keykey(Key).Name; else m_name = lookup_keychar(Char).Name; } catch (UnknownKeycode &e) { m_name = ""; }; } const char *KeyPress::sym() const { return m_name.c_str(); } const char *KeyPress::name() const { if (m_name == "") return ""; const char *ret; if (valid_kcode(Key)) ret = lookup_keykey(Key).LangName; else ret = lookup_keychar(Char).LangName; return ret ? ret : "<Unnamed key>"; } const KeyPress EscapeKey("KEY_ESCAPE"); const KeyPress CancelKey("KEY_CANCEL"); const KeyPress NumberKey[] = { KeyPress("0"), KeyPress("1"), KeyPress("2"), KeyPress("3"), KeyPress("4"), KeyPress("5"), KeyPress("6"), KeyPress("7"), KeyPress("8"), KeyPress("9") }; /* Key config */ // A simple cache for quicker lookup std::map<std::string, KeyPress> g_key_setting_cache; KeyPress getKeySetting(const char *settingname) { std::map<std::string, KeyPress>::iterator n; n = g_key_setting_cache.find(settingname); if(n != g_key_setting_cache.end()) return n->second; KeyPress k(g_settings->get(settingname).c_str()); g_key_setting_cache[settingname] = k; return k; } void clearKeyCache() { g_key_setting_cache.clear(); } irr::EKEY_CODE keyname_to_keycode(const char *name) { return lookup_keyname(name).Key; }