lua api: add register_on_item_activate
[waspsaliva.git] / src / client / keycode.cpp
blob6a0e9f569f74c52617a399fb2ac55d461d8ba4df
1 /*
2 Minetest
3 Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "keycode.h"
21 #include "exceptions.h"
22 #include "settings.h"
23 #include "log.h"
24 #include "debug.h"
25 #include "util/hex.h"
26 #include "util/string.h"
27 #include "util/basic_macros.h"
29 class UnknownKeycode : public BaseException
31 public:
32 UnknownKeycode(const char *s) :
33 BaseException(s) {};
36 struct table_key {
37 const char *Name;
38 irr::EKEY_CODE Key;
39 wchar_t Char; // L'\0' means no character assigned
40 const char *LangName; // NULL means it doesn't have a human description
43 #define DEFINEKEY1(x, lang) /* Irrlicht key without character */ \
44 { #x, irr::x, L'\0', lang },
45 #define DEFINEKEY2(x, ch, lang) /* Irrlicht key with character */ \
46 { #x, irr::x, ch, lang },
47 #define DEFINEKEY3(ch) /* single Irrlicht key (e.g. KEY_KEY_X) */ \
48 { "KEY_KEY_" TOSTRING(ch), irr::KEY_KEY_ ## ch, (wchar_t) *TOSTRING(ch), TOSTRING(ch) },
49 #define DEFINEKEY4(ch) /* single Irrlicht function key (e.g. KEY_F3) */ \
50 { "KEY_F" TOSTRING(ch), irr::KEY_F ## ch, L'\0', "F" TOSTRING(ch) },
51 #define DEFINEKEY5(ch) /* key without Irrlicht keycode */ \
52 { ch, irr::KEY_KEY_CODES_COUNT, (wchar_t) *ch, ch },
54 #define N_(text) text
56 static const struct table_key table[] = {
57 // Keys that can be reliably mapped between Char and Key
58 DEFINEKEY3(0)
59 DEFINEKEY3(1)
60 DEFINEKEY3(2)
61 DEFINEKEY3(3)
62 DEFINEKEY3(4)
63 DEFINEKEY3(5)
64 DEFINEKEY3(6)
65 DEFINEKEY3(7)
66 DEFINEKEY3(8)
67 DEFINEKEY3(9)
68 DEFINEKEY3(A)
69 DEFINEKEY3(B)
70 DEFINEKEY3(C)
71 DEFINEKEY3(D)
72 DEFINEKEY3(E)
73 DEFINEKEY3(F)
74 DEFINEKEY3(G)
75 DEFINEKEY3(H)
76 DEFINEKEY3(I)
77 DEFINEKEY3(J)
78 DEFINEKEY3(K)
79 DEFINEKEY3(L)
80 DEFINEKEY3(M)
81 DEFINEKEY3(N)
82 DEFINEKEY3(O)
83 DEFINEKEY3(P)
84 DEFINEKEY3(Q)
85 DEFINEKEY3(R)
86 DEFINEKEY3(S)
87 DEFINEKEY3(T)
88 DEFINEKEY3(U)
89 DEFINEKEY3(V)
90 DEFINEKEY3(W)
91 DEFINEKEY3(X)
92 DEFINEKEY3(Y)
93 DEFINEKEY3(Z)
94 DEFINEKEY2(KEY_PLUS, L'+', "+")
95 DEFINEKEY2(KEY_COMMA, L',', ",")
96 DEFINEKEY2(KEY_MINUS, L'-', "-")
97 DEFINEKEY2(KEY_PERIOD, L'.', ".")
99 // Keys without a Char
100 DEFINEKEY1(KEY_LBUTTON, N_("Left Button"))
101 DEFINEKEY1(KEY_RBUTTON, N_("Right Button"))
102 DEFINEKEY1(KEY_CANCEL, N_("Cancel"))
103 DEFINEKEY1(KEY_MBUTTON, N_("Middle Button"))
104 DEFINEKEY1(KEY_XBUTTON1, N_("X Button 1"))
105 DEFINEKEY1(KEY_XBUTTON2, N_("X Button 2"))
106 DEFINEKEY1(KEY_BACK, N_("Backspace"))
107 DEFINEKEY1(KEY_TAB, N_("Tab"))
108 DEFINEKEY1(KEY_CLEAR, N_("Clear"))
109 DEFINEKEY1(KEY_RETURN, N_("Return"))
110 DEFINEKEY1(KEY_SHIFT, N_("Shift"))
111 DEFINEKEY1(KEY_CONTROL, N_("Control"))
112 //~ Key name, common on Windows keyboards
113 DEFINEKEY1(KEY_MENU, N_("Menu"))
114 DEFINEKEY1(KEY_PAUSE, N_("Pause"))
115 DEFINEKEY1(KEY_CAPITAL, N_("Caps Lock"))
116 DEFINEKEY1(KEY_SPACE, N_("Space"))
117 DEFINEKEY1(KEY_PRIOR, N_("Page up"))
118 DEFINEKEY1(KEY_NEXT, N_("Page down"))
119 DEFINEKEY1(KEY_END, N_("End"))
120 DEFINEKEY1(KEY_HOME, N_("Home"))
121 DEFINEKEY1(KEY_LEFT, N_("Left"))
122 DEFINEKEY1(KEY_UP, N_("Up"))
123 DEFINEKEY1(KEY_RIGHT, N_("Right"))
124 DEFINEKEY1(KEY_DOWN, N_("Down"))
125 //~ Key name
126 DEFINEKEY1(KEY_SELECT, N_("Select"))
127 //~ "Print screen" key
128 DEFINEKEY1(KEY_PRINT, N_("Print"))
129 DEFINEKEY1(KEY_EXECUT, N_("Execute"))
130 DEFINEKEY1(KEY_SNAPSHOT, N_("Snapshot"))
131 DEFINEKEY1(KEY_INSERT, N_("Insert"))
132 DEFINEKEY1(KEY_DELETE, N_("Delete"))
133 DEFINEKEY1(KEY_HELP, N_("Help"))
134 DEFINEKEY1(KEY_LWIN, N_("Left Windows"))
135 DEFINEKEY1(KEY_RWIN, N_("Right Windows"))
136 DEFINEKEY1(KEY_NUMPAD0, N_("Numpad 0")) // These are not assigned to a char
137 DEFINEKEY1(KEY_NUMPAD1, N_("Numpad 1")) // to prevent interference with KEY_KEY_[0-9].
138 DEFINEKEY1(KEY_NUMPAD2, N_("Numpad 2"))
139 DEFINEKEY1(KEY_NUMPAD3, N_("Numpad 3"))
140 DEFINEKEY1(KEY_NUMPAD4, N_("Numpad 4"))
141 DEFINEKEY1(KEY_NUMPAD5, N_("Numpad 5"))
142 DEFINEKEY1(KEY_NUMPAD6, N_("Numpad 6"))
143 DEFINEKEY1(KEY_NUMPAD7, N_("Numpad 7"))
144 DEFINEKEY1(KEY_NUMPAD8, N_("Numpad 8"))
145 DEFINEKEY1(KEY_NUMPAD9, N_("Numpad 9"))
146 DEFINEKEY1(KEY_MULTIPLY, N_("Numpad *"))
147 DEFINEKEY1(KEY_ADD, N_("Numpad +"))
148 DEFINEKEY1(KEY_SEPARATOR, N_("Numpad ."))
149 DEFINEKEY1(KEY_SUBTRACT, N_("Numpad -"))
150 DEFINEKEY1(KEY_DECIMAL, NULL)
151 DEFINEKEY1(KEY_DIVIDE, N_("Numpad /"))
152 DEFINEKEY4(1)
153 DEFINEKEY4(2)
154 DEFINEKEY4(3)
155 DEFINEKEY4(4)
156 DEFINEKEY4(5)
157 DEFINEKEY4(6)
158 DEFINEKEY4(7)
159 DEFINEKEY4(8)
160 DEFINEKEY4(9)
161 DEFINEKEY4(10)
162 DEFINEKEY4(11)
163 DEFINEKEY4(12)
164 DEFINEKEY4(13)
165 DEFINEKEY4(14)
166 DEFINEKEY4(15)
167 DEFINEKEY4(16)
168 DEFINEKEY4(17)
169 DEFINEKEY4(18)
170 DEFINEKEY4(19)
171 DEFINEKEY4(20)
172 DEFINEKEY4(21)
173 DEFINEKEY4(22)
174 DEFINEKEY4(23)
175 DEFINEKEY4(24)
176 DEFINEKEY1(KEY_NUMLOCK, N_("Num Lock"))
177 DEFINEKEY1(KEY_SCROLL, N_("Scroll Lock"))
178 DEFINEKEY1(KEY_LSHIFT, N_("Left Shift"))
179 DEFINEKEY1(KEY_RSHIFT, N_("Right Shift"))
180 DEFINEKEY1(KEY_LCONTROL, N_("Left Control"))
181 DEFINEKEY1(KEY_RCONTROL, N_("Right Control"))
182 DEFINEKEY1(KEY_LMENU, N_("Left Menu"))
183 DEFINEKEY1(KEY_RMENU, N_("Right Menu"))
185 // Rare/weird keys
186 DEFINEKEY1(KEY_KANA, "Kana")
187 DEFINEKEY1(KEY_HANGUEL, "Hangul")
188 DEFINEKEY1(KEY_HANGUL, "Hangul")
189 DEFINEKEY1(KEY_JUNJA, "Junja")
190 DEFINEKEY1(KEY_FINAL, "Final")
191 DEFINEKEY1(KEY_KANJI, "Kanji")
192 DEFINEKEY1(KEY_HANJA, "Hanja")
193 DEFINEKEY1(KEY_ESCAPE, N_("IME Escape"))
194 DEFINEKEY1(KEY_CONVERT, N_("IME Convert"))
195 DEFINEKEY1(KEY_NONCONVERT, N_("IME Nonconvert"))
196 DEFINEKEY1(KEY_ACCEPT, N_("IME Accept"))
197 DEFINEKEY1(KEY_MODECHANGE, N_("IME Mode Change"))
198 DEFINEKEY1(KEY_APPS, N_("Apps"))
199 DEFINEKEY1(KEY_SLEEP, N_("Sleep"))
200 #if !(IRRLICHT_VERSION_MAJOR <= 1 && IRRLICHT_VERSION_MINOR <= 7 && IRRLICHT_VERSION_REVISION < 3)
201 DEFINEKEY1(KEY_OEM_1, "OEM 1") // KEY_OEM_[0-9] and KEY_OEM_102 are assigned to multiple
202 DEFINEKEY1(KEY_OEM_2, "OEM 2") // different chars (on different platforms too) and thus w/o char
203 DEFINEKEY1(KEY_OEM_3, "OEM 3")
204 DEFINEKEY1(KEY_OEM_4, "OEM 4")
205 DEFINEKEY1(KEY_OEM_5, "OEM 5")
206 DEFINEKEY1(KEY_OEM_6, "OEM 6")
207 DEFINEKEY1(KEY_OEM_7, "OEM 7")
208 DEFINEKEY1(KEY_OEM_8, "OEM 8")
209 DEFINEKEY1(KEY_OEM_AX, "OEM AX")
210 DEFINEKEY1(KEY_OEM_102, "OEM 102")
211 #endif
212 DEFINEKEY1(KEY_ATTN, "Attn")
213 DEFINEKEY1(KEY_CRSEL, "CrSel")
214 DEFINEKEY1(KEY_EXSEL, "ExSel")
215 DEFINEKEY1(KEY_EREOF, N_("Erase EOF"))
216 DEFINEKEY1(KEY_PLAY, N_("Play"))
217 DEFINEKEY1(KEY_ZOOM, N_("Zoom"))
218 DEFINEKEY1(KEY_PA1, "PA1")
219 DEFINEKEY1(KEY_OEM_CLEAR, N_("OEM Clear"))
221 // Keys without Irrlicht keycode
222 DEFINEKEY5("!")
223 DEFINEKEY5("\"")
224 DEFINEKEY5("#")
225 DEFINEKEY5("$")
226 DEFINEKEY5("%")
227 DEFINEKEY5("&")
228 DEFINEKEY5("'")
229 DEFINEKEY5("(")
230 DEFINEKEY5(")")
231 DEFINEKEY5("*")
232 DEFINEKEY5("/")
233 DEFINEKEY5(":")
234 DEFINEKEY5(";")
235 DEFINEKEY5("<")
236 DEFINEKEY5("=")
237 DEFINEKEY5(">")
238 DEFINEKEY5("?")
239 DEFINEKEY5("@")
240 DEFINEKEY5("[")
241 DEFINEKEY5("\\")
242 DEFINEKEY5("]")
243 DEFINEKEY5("^")
244 DEFINEKEY5("_")
247 #undef N_
250 struct table_key lookup_keyname(const char *name)
252 for (const auto &table_key : table) {
253 if (strcmp(table_key.Name, name) == 0)
254 return table_key;
257 throw UnknownKeycode(name);
260 struct table_key lookup_keykey(irr::EKEY_CODE key)
262 for (const auto &table_key : table) {
263 if (table_key.Key == key)
264 return table_key;
267 std::ostringstream os;
268 os << "<Keycode " << (int) key << ">";
269 throw UnknownKeycode(os.str().c_str());
272 struct table_key lookup_keychar(wchar_t Char)
274 for (const auto &table_key : table) {
275 if (table_key.Char == Char)
276 return table_key;
279 std::ostringstream os;
280 os << "<Char " << hex_encode((char*) &Char, sizeof(wchar_t)) << ">";
281 throw UnknownKeycode(os.str().c_str());
284 KeyPress::KeyPress(const char *name)
286 if (strlen(name) == 0) {
287 Key = irr::KEY_KEY_CODES_COUNT;
288 Char = L'\0';
289 m_name = "";
290 return;
293 if (strlen(name) <= 4) {
294 // Lookup by resulting character
295 int chars_read = mbtowc(&Char, name, 1);
296 FATAL_ERROR_IF(chars_read != 1, "Unexpected multibyte character");
297 try {
298 struct table_key k = lookup_keychar(Char);
299 m_name = k.Name;
300 Key = k.Key;
301 return;
302 } catch (UnknownKeycode &e) {};
303 } else {
304 // Lookup by name
305 m_name = name;
306 try {
307 struct table_key k = lookup_keyname(name);
308 Key = k.Key;
309 Char = k.Char;
310 return;
311 } catch (UnknownKeycode &e) {};
314 // It's not a known key, complain and try to do something
315 Key = irr::KEY_KEY_CODES_COUNT;
316 int chars_read = mbtowc(&Char, name, 1);
317 FATAL_ERROR_IF(chars_read != 1, "Unexpected multibyte character");
318 m_name = "";
319 warningstream << "KeyPress: Unknown key '" << name << "', falling back to first char.";
322 KeyPress::KeyPress(const irr::SEvent::SKeyInput &in, bool prefer_character)
324 if (prefer_character)
325 Key = irr::KEY_KEY_CODES_COUNT;
326 else
327 Key = in.Key;
328 Char = in.Char;
330 try {
331 if (valid_kcode(Key))
332 m_name = lookup_keykey(Key).Name;
333 else
334 m_name = lookup_keychar(Char).Name;
335 } catch (UnknownKeycode &e) {
336 m_name = "";
340 const char *KeyPress::sym() const
342 return m_name.c_str();
345 const char *KeyPress::name() const
347 if (m_name.empty())
348 return "";
349 const char *ret;
350 if (valid_kcode(Key))
351 ret = lookup_keykey(Key).LangName;
352 else
353 ret = lookup_keychar(Char).LangName;
354 return ret ? ret : "<Unnamed key>";
357 const KeyPress EscapeKey("KEY_ESCAPE");
358 const KeyPress CancelKey("KEY_CANCEL");
361 Key config
364 // A simple cache for quicker lookup
365 std::unordered_map<std::string, KeyPress> g_key_setting_cache;
367 KeyPress getKeySetting(const char *settingname)
369 std::unordered_map<std::string, KeyPress>::iterator n;
370 n = g_key_setting_cache.find(settingname);
371 if (n != g_key_setting_cache.end())
372 return n->second;
374 KeyPress k(g_settings->get(settingname).c_str());
375 g_key_setting_cache[settingname] = k;
376 return k;
379 void clearKeyCache()
381 g_key_setting_cache.clear();
384 irr::EKEY_CODE keyname_to_keycode(const char *name)
386 return lookup_keyname(name).Key;