mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-10 10:36:21 +00:00

Broken keybindings are fixed byreplacing " " with "space". Scancodes are tied to physical buttons on the keyboard and are language independant.
642 lines
11 KiB
C++
642 lines
11 KiB
C++
/*
|
|
Simple DirectMedia Layer
|
|
Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
|
|
|
|
This software is provided 'as-is', without any express or implied
|
|
warranty. In no event will the authors be held liable for any damages
|
|
arising from the use of this software.
|
|
|
|
Permission is granted to anyone to use this software for any purpose,
|
|
including commercial applications, and to alter it and redistribute it
|
|
freely, subject to the following restrictions:
|
|
|
|
1. The origin of this software must not be misrepresented; you must not
|
|
claim that you wrote the original software. If you use this software
|
|
in a product, an acknowledgment in the product documentation would be
|
|
appreciated but is not required.
|
|
2. Altered source versions must be plainly marked as such, and must not be
|
|
misrepresented as being the original software.
|
|
3. This notice may not be removed or altered from any source distribution.
|
|
*/
|
|
|
|
#include "SDL.h"
|
|
|
|
#if !SDL_VERSION_ATLEAST(2, 0, 0)
|
|
#include "sdl/keyboard.hpp"
|
|
|
|
#define SDLK_SCANCODE_MASK (1<<30)
|
|
#define SDL_SCANCODE_TO_KEYCODE(X) (X | SDLK_SCANCODE_MASK)
|
|
|
|
|
|
static const int SDL_default_keymap[SDL_NUM_SCANCODES] = {
|
|
0, 0, 0, 0,
|
|
'a',
|
|
'b',
|
|
'c',
|
|
'd',
|
|
'e',
|
|
'f',
|
|
'g',
|
|
'h',
|
|
'i',
|
|
'j',
|
|
'k',
|
|
'l',
|
|
'm',
|
|
'n',
|
|
'o',
|
|
'p',
|
|
'q',
|
|
'r',
|
|
's',
|
|
't',
|
|
'u',
|
|
'v',
|
|
'w',
|
|
'x',
|
|
'y',
|
|
'z',
|
|
'1',
|
|
'2',
|
|
'3',
|
|
'4',
|
|
'5',
|
|
'6',
|
|
'7',
|
|
'8',
|
|
'9',
|
|
'0',
|
|
SDLK_RETURN,
|
|
SDLK_ESCAPE,
|
|
SDLK_BACKSPACE,
|
|
SDLK_TAB,
|
|
SDLK_SPACE,
|
|
'-',
|
|
'=',
|
|
'[',
|
|
']',
|
|
'\\',
|
|
'#',
|
|
';',
|
|
'\'',
|
|
'`',
|
|
',',
|
|
'.',
|
|
'/',
|
|
SDLK_CAPSLOCK,
|
|
SDLK_F1,
|
|
SDLK_F2,
|
|
SDLK_F3,
|
|
SDLK_F4,
|
|
SDLK_F5,
|
|
SDLK_F6,
|
|
SDLK_F7,
|
|
SDLK_F8,
|
|
SDLK_F9,
|
|
SDLK_F10,
|
|
SDLK_F11,
|
|
SDLK_F12,
|
|
SDLK_PRINT,
|
|
SDLK_SCROLLOCK,
|
|
SDLK_PAUSE,
|
|
SDLK_INSERT,
|
|
SDLK_HOME,
|
|
SDLK_PAGEUP,
|
|
SDLK_DELETE,
|
|
SDLK_END,
|
|
SDLK_PAGEDOWN,
|
|
SDLK_RIGHT,
|
|
SDLK_LEFT,
|
|
SDLK_DOWN,
|
|
SDLK_UP,
|
|
0,
|
|
SDLK_KP_DIVIDE,
|
|
SDLK_KP_MULTIPLY,
|
|
SDLK_KP_MINUS,
|
|
SDLK_KP_PLUS,
|
|
SDLK_KP_ENTER,
|
|
SDLK_KP1,
|
|
SDLK_KP2,
|
|
SDLK_KP3,
|
|
SDLK_KP4,
|
|
SDLK_KP5,
|
|
SDLK_KP6,
|
|
SDLK_KP7,
|
|
SDLK_KP8,
|
|
SDLK_KP9,
|
|
SDLK_KP0,
|
|
SDLK_KP_PERIOD,
|
|
0,
|
|
0,
|
|
SDLK_POWER,
|
|
SDLK_KP_EQUALS,
|
|
SDLK_F13,
|
|
SDLK_F14,
|
|
SDLK_F15,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
SDLK_HELP,
|
|
SDLK_MENU,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0, 0, 0,
|
|
0,
|
|
0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0,
|
|
SDLK_SYSREQ,
|
|
0,
|
|
SDLK_CLEAR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0, 0,
|
|
SDLK_LCTRL,
|
|
SDLK_LSHIFT,
|
|
SDLK_LALT,
|
|
SDLK_LMETA,
|
|
SDLK_RCTRL,
|
|
SDLK_RSHIFT,
|
|
SDLK_RALT,
|
|
SDLK_RMETA,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
SDLK_MODE,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
};
|
|
|
|
static const char *SDL_scancode_names[SDL_NUM_SCANCODES] = {
|
|
NULL, NULL, NULL, NULL,
|
|
"A",
|
|
"B",
|
|
"C",
|
|
"D",
|
|
"E",
|
|
"F",
|
|
"G",
|
|
"H",
|
|
"I",
|
|
"J",
|
|
"K",
|
|
"L",
|
|
"M",
|
|
"N",
|
|
"O",
|
|
"P",
|
|
"Q",
|
|
"R",
|
|
"S",
|
|
"T",
|
|
"U",
|
|
"V",
|
|
"W",
|
|
"X",
|
|
"Y",
|
|
"Z",
|
|
"1",
|
|
"2",
|
|
"3",
|
|
"4",
|
|
"5",
|
|
"6",
|
|
"7",
|
|
"8",
|
|
"9",
|
|
"0",
|
|
"Return",
|
|
"Escape",
|
|
"Backspace",
|
|
"Tab",
|
|
"Space",
|
|
"-",
|
|
"=",
|
|
"[",
|
|
"]",
|
|
"\\",
|
|
"#",
|
|
";",
|
|
"'",
|
|
"`",
|
|
",",
|
|
".",
|
|
"/",
|
|
"CapsLock",
|
|
"F1",
|
|
"F2",
|
|
"F3",
|
|
"F4",
|
|
"F5",
|
|
"F6",
|
|
"F7",
|
|
"F8",
|
|
"F9",
|
|
"F10",
|
|
"F11",
|
|
"F12",
|
|
"PrintScreen",
|
|
"ScrollLock",
|
|
"Pause",
|
|
"Insert",
|
|
"Home",
|
|
"PageUp",
|
|
"Delete",
|
|
"End",
|
|
"PageDown",
|
|
"Right",
|
|
"Left",
|
|
"Down",
|
|
"Up",
|
|
"Numlock",
|
|
"Keypad /",
|
|
"Keypad *",
|
|
"Keypad -",
|
|
"Keypad +",
|
|
"Keypad Enter",
|
|
"Keypad 1",
|
|
"Keypad 2",
|
|
"Keypad 3",
|
|
"Keypad 4",
|
|
"Keypad 5",
|
|
"Keypad 6",
|
|
"Keypad 7",
|
|
"Keypad 8",
|
|
"Keypad 9",
|
|
"Keypad 0",
|
|
"Keypad .",
|
|
NULL,
|
|
"Application",
|
|
"Power",
|
|
"Keypad =",
|
|
"F13",
|
|
"F14",
|
|
"F15",
|
|
"F16",
|
|
"F17",
|
|
"F18",
|
|
"F19",
|
|
"F20",
|
|
"F21",
|
|
"F22",
|
|
"F23",
|
|
"F24",
|
|
"Execute",
|
|
"Help",
|
|
"Menu",
|
|
"Select",
|
|
"Stop",
|
|
"Again",
|
|
"Undo",
|
|
"Cut",
|
|
"Copy",
|
|
"Paste",
|
|
"Find",
|
|
"Mute",
|
|
"VolumeUp",
|
|
"VolumeDown",
|
|
NULL, NULL, NULL,
|
|
"Keypad ,",
|
|
"Keypad = (AS400)",
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, NULL,
|
|
"AltErase",
|
|
"SysReq",
|
|
"Cancel",
|
|
"Clear",
|
|
"Prior",
|
|
"Return",
|
|
"Separator",
|
|
"Out",
|
|
"Oper",
|
|
"Clear / Again",
|
|
"CrSel",
|
|
"ExSel",
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
"Keypad 00",
|
|
"Keypad 000",
|
|
"ThousandsSeparator",
|
|
"DecimalSeparator",
|
|
"CurrencyUnit",
|
|
"CurrencySubUnit",
|
|
"Keypad (",
|
|
"Keypad )",
|
|
"Keypad {",
|
|
"Keypad }",
|
|
"Keypad Tab",
|
|
"Keypad Backspace",
|
|
"Keypad A",
|
|
"Keypad B",
|
|
"Keypad C",
|
|
"Keypad D",
|
|
"Keypad E",
|
|
"Keypad F",
|
|
"Keypad XOR",
|
|
"Keypad ^",
|
|
"Keypad %",
|
|
"Keypad <",
|
|
"Keypad >",
|
|
"Keypad &",
|
|
"Keypad &&",
|
|
"Keypad |",
|
|
"Keypad ||",
|
|
"Keypad :",
|
|
"Keypad #",
|
|
"Keypad Space",
|
|
"Keypad @",
|
|
"Keypad !",
|
|
"Keypad MemStore",
|
|
"Keypad MemRecall",
|
|
"Keypad MemClear",
|
|
"Keypad MemAdd",
|
|
"Keypad MemSubtract",
|
|
"Keypad MemMultiply",
|
|
"Keypad MemDivide",
|
|
"Keypad +/-",
|
|
"Keypad Clear",
|
|
"Keypad ClearEntry",
|
|
"Keypad Binary",
|
|
"Keypad Octal",
|
|
"Keypad Decimal",
|
|
"Keypad Hexadecimal",
|
|
NULL, NULL,
|
|
"Left Ctrl",
|
|
"Left Shift",
|
|
"Left Alt",
|
|
"Left GUI",
|
|
"Right Ctrl",
|
|
"Right Shift",
|
|
"Right Alt",
|
|
"Right GUI",
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
NULL,
|
|
"ModeSwitch",
|
|
"AudioNext",
|
|
"AudioPrev",
|
|
"AudioStop",
|
|
"AudioPlay",
|
|
"AudioMute",
|
|
"MediaSelect",
|
|
"WWW",
|
|
"Mail",
|
|
"Calculator",
|
|
"Computer",
|
|
"AC Search",
|
|
"AC Home",
|
|
"AC Back",
|
|
"AC Forward",
|
|
"AC Stop",
|
|
"AC Refresh",
|
|
"AC Bookmarks",
|
|
"BrightnessDown",
|
|
"BrightnessUp",
|
|
"DisplaySwitch",
|
|
"KBDIllumToggle",
|
|
"KBDIllumDown",
|
|
"KBDIllumUp",
|
|
"Eject",
|
|
"Sleep",
|
|
};
|
|
|
|
|
|
/**
|
|
* \brief Get the key code corresponding to the given scancode according
|
|
* to the current keyboard layout.
|
|
*
|
|
* See ::SDL_Keycode for details.
|
|
*
|
|
* \sa SDL_GetKeyName()
|
|
*/
|
|
SDLKey SDL_GetKeyFromScancode(SDL_Scancode scancode);
|
|
|
|
/**
|
|
* \brief Get the scancode corresponding to the given key code according to the
|
|
* current keyboard layout.
|
|
*
|
|
* See ::SDL_Scancode for details.
|
|
*
|
|
* \sa SDL_GetScancodeName()
|
|
*/
|
|
SDL_Scancode SDL_GetScancodeFromKey(SDLKey key);
|
|
|
|
/**
|
|
* \brief Get a human-readable name for a scancode.
|
|
*
|
|
* \return A pointer to the name for the scancode.
|
|
* If the scancode doesn't have a name, this function returns
|
|
* an empty string ("").
|
|
*
|
|
* \sa SDL_Scancode
|
|
*/
|
|
const char * SDL_GetScancodeName(SDL_Scancode scancode);
|
|
|
|
/**
|
|
* \brief Get a scancode from a human-readable name
|
|
*
|
|
* \return scancode, or SDL_SCANCODE_UNKNOWN if the name wasn't recognized
|
|
*
|
|
* \sa SDL_Scancode
|
|
*/
|
|
SDL_Scancode SDL_GetScancodeFromName(const char *name);
|
|
|
|
SDLKey
|
|
SDL_GetKeyFromScancode(SDL_Scancode scancode)
|
|
{
|
|
if (scancode < SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) {
|
|
return SDLK_UNKNOWN;
|
|
}
|
|
|
|
return (SDLKey) SDL_default_keymap[scancode];
|
|
}
|
|
|
|
SDL_Scancode
|
|
SDL_GetScancodeFromKey(SDLKey key)
|
|
{
|
|
for (int scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_NUM_SCANCODES;
|
|
++scancode) {
|
|
if (SDL_default_keymap[scancode] == key) {
|
|
return (SDL_Scancode) scancode;
|
|
}
|
|
}
|
|
return SDL_SCANCODE_UNKNOWN;
|
|
}
|
|
|
|
const char *
|
|
SDL_GetScancodeName(SDL_Scancode scancode)
|
|
{
|
|
const char *name;
|
|
if (scancode < SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) {
|
|
return "";
|
|
}
|
|
|
|
name = SDL_scancode_names[scancode];
|
|
if (name)
|
|
return name;
|
|
else
|
|
return "";
|
|
}
|
|
|
|
SDL_Scancode SDL_GetScancodeFromName(const char *name)
|
|
{
|
|
unsigned int i;
|
|
|
|
if (!name || !*name) {
|
|
return SDL_SCANCODE_UNKNOWN;
|
|
}
|
|
|
|
for (i = 0; i < SDL_arraysize(SDL_scancode_names); ++i) {
|
|
if (!SDL_scancode_names[i]) {
|
|
continue;
|
|
}
|
|
if (SDL_strcasecmp(name, SDL_scancode_names[i]) == 0) {
|
|
return (SDL_Scancode)i;
|
|
}
|
|
}
|
|
|
|
return SDL_SCANCODE_UNKNOWN;
|
|
}
|
|
|
|
SDLKey
|
|
SDL_GetKeyFromName(const char *name)
|
|
{
|
|
int key;
|
|
|
|
/* Check input */
|
|
if (name == NULL) return SDLK_UNKNOWN;
|
|
|
|
/* If it's a single UTF-8 character, then that's the keycode itself */
|
|
key = *(const unsigned char *)name;
|
|
if (key >= 0xF0) {
|
|
if (SDL_strlen(name) == 4) {
|
|
int i = 0;
|
|
key = (Uint16)(name[i]&0x07) << 18;
|
|
key |= (Uint16)(name[++i]&0x3F) << 12;
|
|
key |= (Uint16)(name[++i]&0x3F) << 6;
|
|
key |= (Uint16)(name[++i]&0x3F);
|
|
return (SDLKey) key;
|
|
}
|
|
return SDLK_UNKNOWN;
|
|
} else if (key >= 0xE0) {
|
|
if (SDL_strlen(name) == 3) {
|
|
int i = 0;
|
|
key = (Uint16)(name[i]&0x0F) << 12;
|
|
key |= (Uint16)(name[++i]&0x3F) << 6;
|
|
key |= (Uint16)(name[++i]&0x3F);
|
|
return (SDLKey) key;
|
|
}
|
|
return SDLK_UNKNOWN;
|
|
} else if (key >= 0xC0) {
|
|
if (SDL_strlen(name) == 2) {
|
|
int i = 0;
|
|
key = (Uint16)(name[i]&0x1F) << 6;
|
|
key |= (Uint16)(name[++i]&0x3F);
|
|
return (SDLKey) key;
|
|
}
|
|
return SDLK_UNKNOWN;
|
|
} else {
|
|
if (SDL_strlen(name) == 1) {
|
|
if (key >= 'A' && key <= 'Z') {
|
|
key += 32;
|
|
}
|
|
return (SDLKey) key;
|
|
}
|
|
|
|
/* Get the scancode for this name, and the associated keycode */
|
|
return (SDLKey) SDL_default_keymap[SDL_GetScancodeFromName(name)];
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/* vi: set ts=4 sw=4 expandtab: */
|