Translated using Weblate (Chinese (Simplified))
[oweals/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 #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"))
220
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("_")
245 };
246
247 #undef N_
248
249
250 struct table_key lookup_keyname(const char *name)
251 {
252         for (const auto &table_key : table) {
253                 if (strcmp(table_key.Name, name) == 0)
254                         return table_key;
255         }
256
257         throw UnknownKeycode(name);
258 }
259
260 struct table_key lookup_keykey(irr::EKEY_CODE key)
261 {
262         for (const auto &table_key : table) {
263                 if (table_key.Key == key)
264                         return table_key;
265         }
266
267         std::ostringstream os;
268         os << "<Keycode " << (int) key << ">";
269         throw UnknownKeycode(os.str().c_str());
270 }
271
272 struct table_key lookup_keychar(wchar_t Char)
273 {
274         for (const auto &table_key : table) {
275                 if (table_key.Char == Char)
276                         return table_key;
277         }
278
279         std::ostringstream os;
280         os << "<Char " << hex_encode((char*) &Char, sizeof(wchar_t)) << ">";
281         throw UnknownKeycode(os.str().c_str());
282 }
283
284 KeyPress::KeyPress(const char *name)
285 {
286         if (strlen(name) == 0) {
287                 Key = irr::KEY_KEY_CODES_COUNT;
288                 Char = L'\0';
289                 m_name = "";
290                 return;
291         }
292
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) {};
312         }
313
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.";
320 }
321
322 KeyPress::KeyPress(const irr::SEvent::SKeyInput &in, bool prefer_character)
323 {
324         if (prefer_character)
325                 Key = irr::KEY_KEY_CODES_COUNT;
326         else
327                 Key = in.Key;
328         Char = in.Char;
329
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 = "";
337         };
338 }
339
340 const char *KeyPress::sym() const
341 {
342         return m_name.c_str();
343 }
344
345 const char *KeyPress::name() const
346 {
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>";
355 }
356
357 const KeyPress EscapeKey("KEY_ESCAPE");
358 const KeyPress CancelKey("KEY_CANCEL");
359
360 /*
361         Key config
362 */
363
364 // A simple cache for quicker lookup
365 std::unordered_map<std::string, KeyPress> g_key_setting_cache;
366
367 KeyPress getKeySetting(const char *settingname)
368 {
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;
373
374         KeyPress k(g_settings->get(settingname).c_str());
375         g_key_setting_cache[settingname] = k;
376         return k;
377 }
378
379 void clearKeyCache()
380 {
381         g_key_setting_cache.clear();
382 }
383
384 irr::EKEY_CODE keyname_to_keycode(const char *name)
385 {
386         return lookup_keyname(name).Key;
387 }