]> git.lizzy.rs Git - minetest.git/blob - src/client/keycode.cpp
Check for falling `float` nodes in liquid transform (#12862)
[minetest.git] / src / client / keycode.cpp
1 /*
2 Minetest
3 Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
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.
9
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.
14
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.
18 */
19
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"
28
29 class UnknownKeycode : public BaseException
30 {
31 public:
32         UnknownKeycode(const char *s) :
33                 BaseException(s) {};
34 };
35
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
41 };
42
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 },
53
54 #define N_(text) text
55
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'.', ".")
98
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"))
184
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         DEFINEKEY1(KEY_OEM_1, "OEM 1") // KEY_OEM_[0-9] and KEY_OEM_102 are assigned to multiple
201         DEFINEKEY1(KEY_OEM_2, "OEM 2") // different chars (on different platforms too) and thus w/o char
202         DEFINEKEY1(KEY_OEM_3, "OEM 3")
203         DEFINEKEY1(KEY_OEM_4, "OEM 4")
204         DEFINEKEY1(KEY_OEM_5, "OEM 5")
205         DEFINEKEY1(KEY_OEM_6, "OEM 6")
206         DEFINEKEY1(KEY_OEM_7, "OEM 7")
207         DEFINEKEY1(KEY_OEM_8, "OEM 8")
208         DEFINEKEY1(KEY_OEM_AX, "OEM AX")
209         DEFINEKEY1(KEY_OEM_102, "OEM 102")
210         DEFINEKEY1(KEY_ATTN, "Attn")
211         DEFINEKEY1(KEY_CRSEL, "CrSel")
212         DEFINEKEY1(KEY_EXSEL, "ExSel")
213         DEFINEKEY1(KEY_EREOF, N_("Erase EOF"))
214         DEFINEKEY1(KEY_PLAY, N_("Play"))
215         DEFINEKEY1(KEY_ZOOM, N_("Zoom"))
216         DEFINEKEY1(KEY_PA1, "PA1")
217         DEFINEKEY1(KEY_OEM_CLEAR, N_("OEM Clear"))
218
219         // Keys without Irrlicht keycode
220         DEFINEKEY5("!")
221         DEFINEKEY5("\"")
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 };
244
245 #undef N_
246
247
248 struct table_key lookup_keyname(const char *name)
249 {
250         for (const auto &table_key : table) {
251                 if (strcmp(table_key.Name, name) == 0)
252                         return table_key;
253         }
254
255         throw UnknownKeycode(name);
256 }
257
258 struct table_key lookup_keykey(irr::EKEY_CODE key)
259 {
260         for (const auto &table_key : table) {
261                 if (table_key.Key == key)
262                         return table_key;
263         }
264
265         std::ostringstream os;
266         os << "<Keycode " << (int) key << ">";
267         throw UnknownKeycode(os.str().c_str());
268 }
269
270 struct table_key lookup_keychar(wchar_t Char)
271 {
272         for (const auto &table_key : table) {
273                 if (table_key.Char == Char)
274                         return table_key;
275         }
276
277         std::ostringstream os;
278         os << "<Char " << hex_encode((char*) &Char, sizeof(wchar_t)) << ">";
279         throw UnknownKeycode(os.str().c_str());
280 }
281
282 KeyPress::KeyPress(const char *name)
283 {
284         if (strlen(name) == 0) {
285                 Key = irr::KEY_KEY_CODES_COUNT;
286                 Char = L'\0';
287                 m_name = "";
288                 return;
289         }
290
291         if (strlen(name) <= 4) {
292                 // Lookup by resulting character
293                 int chars_read = mbtowc(&Char, name, 1);
294                 FATAL_ERROR_IF(chars_read != 1, "Unexpected multibyte character");
295                 try {
296                         struct table_key k = lookup_keychar(Char);
297                         m_name = k.Name;
298                         Key = k.Key;
299                         return;
300                 } catch (UnknownKeycode &e) {};
301         } else {
302                 // Lookup by name
303                 m_name = name;
304                 try {
305                         struct table_key k = lookup_keyname(name);
306                         Key = k.Key;
307                         Char = k.Char;
308                         return;
309                 } catch (UnknownKeycode &e) {};
310         }
311
312         // It's not a known key, complain and try to do something
313         Key = irr::KEY_KEY_CODES_COUNT;
314         int chars_read = mbtowc(&Char, name, 1);
315         FATAL_ERROR_IF(chars_read != 1, "Unexpected multibyte character");
316         m_name = "";
317         warningstream << "KeyPress: Unknown key '" << name
318                 << "', falling back to first char." << std::endl;
319 }
320
321 KeyPress::KeyPress(const irr::SEvent::SKeyInput &in, bool prefer_character)
322 {
323         if (prefer_character)
324                 Key = irr::KEY_KEY_CODES_COUNT;
325         else
326                 Key = in.Key;
327         Char = in.Char;
328
329         try {
330                 if (valid_kcode(Key))
331                         m_name = lookup_keykey(Key).Name;
332                 else
333                         m_name = lookup_keychar(Char).Name;
334         } catch (UnknownKeycode &e) {
335                 m_name.clear();
336         };
337 }
338
339 const char *KeyPress::sym() const
340 {
341         return m_name.c_str();
342 }
343
344 const char *KeyPress::name() const
345 {
346         if (m_name.empty())
347                 return "";
348         const char *ret;
349         if (valid_kcode(Key))
350                 ret = lookup_keykey(Key).LangName;
351         else
352                 ret = lookup_keychar(Char).LangName;
353         return ret ? ret : "<Unnamed key>";
354 }
355
356 const KeyPress EscapeKey("KEY_ESCAPE");
357 const KeyPress CancelKey("KEY_CANCEL");
358
359 /*
360         Key config
361 */
362
363 // A simple cache for quicker lookup
364 std::unordered_map<std::string, KeyPress> g_key_setting_cache;
365
366 KeyPress getKeySetting(const char *settingname)
367 {
368         std::unordered_map<std::string, KeyPress>::iterator n;
369         n = g_key_setting_cache.find(settingname);
370         if (n != g_key_setting_cache.end())
371                 return n->second;
372
373         KeyPress k(g_settings->get(settingname).c_str());
374         g_key_setting_cache[settingname] = k;
375         return k;
376 }
377
378 void clearKeyCache()
379 {
380         g_key_setting_cache.clear();
381 }
382
383 irr::EKEY_CODE keyname_to_keycode(const char *name)
384 {
385         return lookup_keyname(name).Key;
386 }