| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093 |
- /*
- Simple DirectMedia Layer
- Copyright (C) 1997-2020 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_internal.h"
- /* General keyboard handling code for SDL */
- #include "SDL_timer.h"
- #include "SDL_events.h"
- #include "SDL_events_c.h"
- #include "SDL_assert.h"
- #include "../video/SDL_sysvideo.h"
- /* #define DEBUG_KEYBOARD */
- /* Global keyboard information */
- #define KEYBOARD_HARDWARE 0x01
- #define KEYBOARD_AUTORELEASE 0x02
- typedef struct SDL_Keyboard SDL_Keyboard;
- struct SDL_Keyboard
- {
- /* Data common to all keyboards */
- SDL_Window *focus;
- Uint16 modstate;
- Uint8 keysource[SDL_NUM_SCANCODES];
- Uint8 keystate[SDL_NUM_SCANCODES];
- SDL_Keycode keymap[SDL_NUM_SCANCODES];
- SDL_bool autorelease_pending;
- };
- static SDL_Keyboard SDL_keyboard;
- static const SDL_Keycode 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_PRINTSCREEN,
- SDLK_SCROLLLOCK,
- SDLK_PAUSE,
- SDLK_INSERT,
- SDLK_HOME,
- SDLK_PAGEUP,
- SDLK_DELETE,
- SDLK_END,
- SDLK_PAGEDOWN,
- SDLK_RIGHT,
- SDLK_LEFT,
- SDLK_DOWN,
- SDLK_UP,
- SDLK_NUMLOCKCLEAR,
- SDLK_KP_DIVIDE,
- SDLK_KP_MULTIPLY,
- SDLK_KP_MINUS,
- SDLK_KP_PLUS,
- SDLK_KP_ENTER,
- SDLK_KP_1,
- SDLK_KP_2,
- SDLK_KP_3,
- SDLK_KP_4,
- SDLK_KP_5,
- SDLK_KP_6,
- SDLK_KP_7,
- SDLK_KP_8,
- SDLK_KP_9,
- SDLK_KP_0,
- SDLK_KP_PERIOD,
- 0,
- SDLK_APPLICATION,
- SDLK_POWER,
- SDLK_KP_EQUALS,
- SDLK_F13,
- SDLK_F14,
- SDLK_F15,
- SDLK_F16,
- SDLK_F17,
- SDLK_F18,
- SDLK_F19,
- SDLK_F20,
- SDLK_F21,
- SDLK_F22,
- SDLK_F23,
- SDLK_F24,
- SDLK_EXECUTE,
- SDLK_HELP,
- SDLK_MENU,
- SDLK_SELECT,
- SDLK_STOP,
- SDLK_AGAIN,
- SDLK_UNDO,
- SDLK_CUT,
- SDLK_COPY,
- SDLK_PASTE,
- SDLK_FIND,
- SDLK_MUTE,
- SDLK_VOLUMEUP,
- SDLK_VOLUMEDOWN,
- 0, 0, 0,
- SDLK_KP_COMMA,
- SDLK_KP_EQUALSAS400,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- SDLK_ALTERASE,
- SDLK_SYSREQ,
- SDLK_CANCEL,
- SDLK_CLEAR,
- SDLK_PRIOR,
- SDLK_RETURN2,
- SDLK_SEPARATOR,
- SDLK_OUT,
- SDLK_OPER,
- SDLK_CLEARAGAIN,
- SDLK_CRSEL,
- SDLK_EXSEL,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- SDLK_KP_00,
- SDLK_KP_000,
- SDLK_THOUSANDSSEPARATOR,
- SDLK_DECIMALSEPARATOR,
- SDLK_CURRENCYUNIT,
- SDLK_CURRENCYSUBUNIT,
- SDLK_KP_LEFTPAREN,
- SDLK_KP_RIGHTPAREN,
- SDLK_KP_LEFTBRACE,
- SDLK_KP_RIGHTBRACE,
- SDLK_KP_TAB,
- SDLK_KP_BACKSPACE,
- SDLK_KP_A,
- SDLK_KP_B,
- SDLK_KP_C,
- SDLK_KP_D,
- SDLK_KP_E,
- SDLK_KP_F,
- SDLK_KP_XOR,
- SDLK_KP_POWER,
- SDLK_KP_PERCENT,
- SDLK_KP_LESS,
- SDLK_KP_GREATER,
- SDLK_KP_AMPERSAND,
- SDLK_KP_DBLAMPERSAND,
- SDLK_KP_VERTICALBAR,
- SDLK_KP_DBLVERTICALBAR,
- SDLK_KP_COLON,
- SDLK_KP_HASH,
- SDLK_KP_SPACE,
- SDLK_KP_AT,
- SDLK_KP_EXCLAM,
- SDLK_KP_MEMSTORE,
- SDLK_KP_MEMRECALL,
- SDLK_KP_MEMCLEAR,
- SDLK_KP_MEMADD,
- SDLK_KP_MEMSUBTRACT,
- SDLK_KP_MEMMULTIPLY,
- SDLK_KP_MEMDIVIDE,
- SDLK_KP_PLUSMINUS,
- SDLK_KP_CLEAR,
- SDLK_KP_CLEARENTRY,
- SDLK_KP_BINARY,
- SDLK_KP_OCTAL,
- SDLK_KP_DECIMAL,
- SDLK_KP_HEXADECIMAL,
- 0, 0,
- SDLK_LCTRL,
- SDLK_LSHIFT,
- SDLK_LALT,
- SDLK_LGUI,
- SDLK_RCTRL,
- SDLK_RSHIFT,
- SDLK_RALT,
- SDLK_RGUI,
- 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,
- SDLK_AUDIONEXT,
- SDLK_AUDIOPREV,
- SDLK_AUDIOSTOP,
- SDLK_AUDIOPLAY,
- SDLK_AUDIOMUTE,
- SDLK_MEDIASELECT,
- SDLK_WWW,
- SDLK_MAIL,
- SDLK_CALCULATOR,
- SDLK_COMPUTER,
- SDLK_AC_SEARCH,
- SDLK_AC_HOME,
- SDLK_AC_BACK,
- SDLK_AC_FORWARD,
- SDLK_AC_STOP,
- SDLK_AC_REFRESH,
- SDLK_AC_BOOKMARKS,
- SDLK_BRIGHTNESSDOWN,
- SDLK_BRIGHTNESSUP,
- SDLK_DISPLAYSWITCH,
- SDLK_KBDILLUMTOGGLE,
- SDLK_KBDILLUMDOWN,
- SDLK_KBDILLUMUP,
- SDLK_EJECT,
- SDLK_SLEEP,
- SDLK_APP1,
- SDLK_APP2,
- SDLK_AUDIOREWIND,
- SDLK_AUDIOFASTFORWARD,
- };
- 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",
- "App1",
- "App2",
- "AudioRewind",
- "AudioFastForward",
- };
- /* Taken from SDL_iconv() */
- char *
- SDL_UCS4ToUTF8(Uint32 ch, char *dst)
- {
- Uint8 *p = (Uint8 *) dst;
- if (ch <= 0x7F) {
- *p = (Uint8) ch;
- ++dst;
- } else if (ch <= 0x7FF) {
- p[0] = 0xC0 | (Uint8) ((ch >> 6) & 0x1F);
- p[1] = 0x80 | (Uint8) (ch & 0x3F);
- dst += 2;
- } else if (ch <= 0xFFFF) {
- p[0] = 0xE0 | (Uint8) ((ch >> 12) & 0x0F);
- p[1] = 0x80 | (Uint8) ((ch >> 6) & 0x3F);
- p[2] = 0x80 | (Uint8) (ch & 0x3F);
- dst += 3;
- } else if (ch <= 0x1FFFFF) {
- p[0] = 0xF0 | (Uint8) ((ch >> 18) & 0x07);
- p[1] = 0x80 | (Uint8) ((ch >> 12) & 0x3F);
- p[2] = 0x80 | (Uint8) ((ch >> 6) & 0x3F);
- p[3] = 0x80 | (Uint8) (ch & 0x3F);
- dst += 4;
- } else if (ch <= 0x3FFFFFF) {
- p[0] = 0xF8 | (Uint8) ((ch >> 24) & 0x03);
- p[1] = 0x80 | (Uint8) ((ch >> 18) & 0x3F);
- p[2] = 0x80 | (Uint8) ((ch >> 12) & 0x3F);
- p[3] = 0x80 | (Uint8) ((ch >> 6) & 0x3F);
- p[4] = 0x80 | (Uint8) (ch & 0x3F);
- dst += 5;
- } else {
- p[0] = 0xFC | (Uint8) ((ch >> 30) & 0x01);
- p[1] = 0x80 | (Uint8) ((ch >> 24) & 0x3F);
- p[2] = 0x80 | (Uint8) ((ch >> 18) & 0x3F);
- p[3] = 0x80 | (Uint8) ((ch >> 12) & 0x3F);
- p[4] = 0x80 | (Uint8) ((ch >> 6) & 0x3F);
- p[5] = 0x80 | (Uint8) (ch & 0x3F);
- dst += 6;
- }
- return dst;
- }
- /* Public functions */
- int
- SDL_KeyboardInit(void)
- {
- SDL_Keyboard *keyboard = &SDL_keyboard;
- /* Set the default keymap */
- SDL_memcpy(keyboard->keymap, SDL_default_keymap, sizeof(SDL_default_keymap));
- return (0);
- }
- void
- SDL_ResetKeyboard(void)
- {
- SDL_Keyboard *keyboard = &SDL_keyboard;
- SDL_Scancode scancode;
- #ifdef DEBUG_KEYBOARD
- printf("Resetting keyboard\n");
- #endif
- for (scancode = (SDL_Scancode) 0; scancode < SDL_NUM_SCANCODES; ++scancode) {
- if (keyboard->keystate[scancode] == SDL_PRESSED) {
- SDL_SendKeyboardKey(SDL_RELEASED, scancode);
- }
- }
- }
- void
- SDL_GetDefaultKeymap(SDL_Keycode * keymap)
- {
- SDL_memcpy(keymap, SDL_default_keymap, sizeof(SDL_default_keymap));
- }
- void
- SDL_SetKeymap(int start, SDL_Keycode * keys, int length)
- {
- SDL_Keyboard *keyboard = &SDL_keyboard;
- SDL_Scancode scancode;
- if (start < 0 || start + length > SDL_NUM_SCANCODES) {
- return;
- }
- SDL_memcpy(&keyboard->keymap[start], keys, sizeof(*keys) * length);
- /* The number key scancodes always map to the number key keycodes.
- * On AZERTY layouts these technically are symbols, but users (and games)
- * always think of them and view them in UI as number keys.
- */
- keyboard->keymap[SDL_SCANCODE_0] = SDLK_0;
- for (scancode = SDL_SCANCODE_1; scancode <= SDL_SCANCODE_9; ++scancode) {
- keyboard->keymap[scancode] = SDLK_1 + (scancode - SDL_SCANCODE_1);
- }
- }
- void
- SDL_SetScancodeName(SDL_Scancode scancode, const char *name)
- {
- SDL_scancode_names[scancode] = name;
- }
- SDL_Window *
- SDL_GetKeyboardFocus(void)
- {
- SDL_Keyboard *keyboard = &SDL_keyboard;
- return keyboard->focus;
- }
- void
- SDL_SetKeyboardFocus(SDL_Window * window)
- {
- SDL_Keyboard *keyboard = &SDL_keyboard;
- if (keyboard->focus && !window) {
- /* We won't get anymore keyboard messages, so reset keyboard state */
- SDL_ResetKeyboard();
- }
- /* See if the current window has lost focus */
- if (keyboard->focus && keyboard->focus != window) {
- /* new window shouldn't think it has mouse captured. */
- SDL_assert(!window || !(window->flags & SDL_WINDOW_MOUSE_CAPTURE));
- /* old window must lose an existing mouse capture. */
- if (keyboard->focus->flags & SDL_WINDOW_MOUSE_CAPTURE) {
- SDL_CaptureMouse(SDL_FALSE); /* drop the capture. */
- SDL_assert(!(keyboard->focus->flags & SDL_WINDOW_MOUSE_CAPTURE));
- }
- SDL_SendWindowEvent(keyboard->focus, SDL_WINDOWEVENT_FOCUS_LOST,
- 0, 0);
- /* Ensures IME compositions are committed */
- if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
- SDL_VideoDevice *video = SDL_GetVideoDevice();
- if (video && video->StopTextInput) {
- video->StopTextInput(video);
- }
- }
- }
- keyboard->focus = window;
- if (keyboard->focus) {
- SDL_SendWindowEvent(keyboard->focus, SDL_WINDOWEVENT_FOCUS_GAINED,
- 0, 0);
- if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
- SDL_VideoDevice *video = SDL_GetVideoDevice();
- if (video && video->StartTextInput) {
- video->StartTextInput(video);
- }
- }
- }
- }
- static int
- SDL_SendKeyboardKeyInternal(Uint8 source, Uint8 state, SDL_Scancode scancode)
- {
- SDL_Keyboard *keyboard = &SDL_keyboard;
- int posted;
- SDL_Keymod modifier;
- SDL_Keycode keycode;
- Uint32 type;
- Uint8 repeat = SDL_FALSE;
- if (scancode == SDL_SCANCODE_UNKNOWN) {
- return 0;
- }
- #ifdef DEBUG_KEYBOARD
- printf("The '%s' key has been %s\n", SDL_GetScancodeName(scancode),
- state == SDL_PRESSED ? "pressed" : "released");
- #endif
- /* Figure out what type of event this is */
- switch (state) {
- case SDL_PRESSED:
- type = SDL_KEYDOWN;
- break;
- case SDL_RELEASED:
- type = SDL_KEYUP;
- break;
- default:
- /* Invalid state -- bail */
- return 0;
- }
- /* Drop events that don't change state */
- if (state) {
- if (keyboard->keystate[scancode]) {
- if (!(keyboard->keysource[scancode] & source)) {
- keyboard->keysource[scancode] |= source;
- return 0;
- }
- repeat = SDL_TRUE;
- }
- keyboard->keysource[scancode] |= source;
- } else {
- if (!keyboard->keystate[scancode]) {
- return 0;
- }
- keyboard->keysource[scancode] = 0;
- }
- /* Update internal keyboard state */
- keyboard->keystate[scancode] = state;
- keycode = keyboard->keymap[scancode];
- if (source == KEYBOARD_AUTORELEASE) {
- keyboard->autorelease_pending = SDL_TRUE;
- }
- /* Update modifiers state if applicable */
- switch (keycode) {
- case SDLK_LCTRL:
- modifier = KMOD_LCTRL;
- break;
- case SDLK_RCTRL:
- modifier = KMOD_RCTRL;
- break;
- case SDLK_LSHIFT:
- modifier = KMOD_LSHIFT;
- break;
- case SDLK_RSHIFT:
- modifier = KMOD_RSHIFT;
- break;
- case SDLK_LALT:
- modifier = KMOD_LALT;
- break;
- case SDLK_RALT:
- modifier = KMOD_RALT;
- break;
- case SDLK_LGUI:
- modifier = KMOD_LGUI;
- break;
- case SDLK_RGUI:
- modifier = KMOD_RGUI;
- break;
- case SDLK_MODE:
- modifier = KMOD_MODE;
- break;
- default:
- modifier = KMOD_NONE;
- break;
- }
- if (SDL_KEYDOWN == type) {
- switch (keycode) {
- case SDLK_NUMLOCKCLEAR:
- keyboard->modstate ^= KMOD_NUM;
- break;
- case SDLK_CAPSLOCK:
- keyboard->modstate ^= KMOD_CAPS;
- break;
- default:
- keyboard->modstate |= modifier;
- break;
- }
- } else {
- keyboard->modstate &= ~modifier;
- }
- /* Post the event, if desired */
- posted = 0;
- if (SDL_GetEventState(type) == SDL_ENABLE) {
- SDL_Event event;
- event.key.type = type;
- event.key.state = state;
- event.key.repeat = repeat;
- event.key.keysym.scancode = scancode;
- event.key.keysym.sym = keycode;
- event.key.keysym.mod = keyboard->modstate;
- event.key.windowID = keyboard->focus ? keyboard->focus->id : 0;
- posted = (SDL_PushEvent(&event) > 0);
- }
- return (posted);
- }
- int
- SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
- {
- return SDL_SendKeyboardKeyInternal(KEYBOARD_HARDWARE, state, scancode);
- }
- int
- SDL_SendKeyboardKeyAutoRelease(SDL_Scancode scancode)
- {
- return SDL_SendKeyboardKeyInternal(KEYBOARD_AUTORELEASE, SDL_PRESSED, scancode);
- }
- void
- SDL_ReleaseAutoReleaseKeys(void)
- {
- SDL_Keyboard *keyboard = &SDL_keyboard;
- SDL_Scancode scancode;
- if (keyboard->autorelease_pending) {
- for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_NUM_SCANCODES; ++scancode) {
- if (keyboard->keysource[scancode] == KEYBOARD_AUTORELEASE) {
- SDL_SendKeyboardKeyInternal(KEYBOARD_AUTORELEASE, SDL_RELEASED, scancode);
- }
- }
- keyboard->autorelease_pending = SDL_FALSE;
- }
- }
- SDL_bool
- SDL_HardwareKeyboardKeyPressed(void)
- {
- SDL_Keyboard *keyboard = &SDL_keyboard;
- SDL_Scancode scancode;
- for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_NUM_SCANCODES; ++scancode) {
- if ((keyboard->keysource[scancode] & KEYBOARD_HARDWARE) != 0) {
- return SDL_TRUE;
- }
- }
- return SDL_FALSE;
- }
- int
- SDL_SendKeyboardText(const char *text)
- {
- SDL_Keyboard *keyboard = &SDL_keyboard;
- int posted;
- /* Don't post text events for unprintable characters */
- if ((unsigned char)*text < ' ' || *text == 127) {
- return 0;
- }
- /* Post the event, if desired */
- posted = 0;
- if (SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE) {
- SDL_Event event;
- event.text.type = SDL_TEXTINPUT;
- event.text.windowID = keyboard->focus ? keyboard->focus->id : 0;
- SDL_utf8strlcpy(event.text.text, text, SDL_arraysize(event.text.text));
- posted = (SDL_PushEvent(&event) > 0);
- }
- return (posted);
- }
- int
- SDL_SendEditingText(const char *text, int start, int length)
- {
- SDL_Keyboard *keyboard = &SDL_keyboard;
- int posted;
- /* Post the event, if desired */
- posted = 0;
- if (SDL_GetEventState(SDL_TEXTEDITING) == SDL_ENABLE) {
- SDL_Event event;
- event.edit.type = SDL_TEXTEDITING;
- event.edit.windowID = keyboard->focus ? keyboard->focus->id : 0;
- event.edit.start = start;
- event.edit.length = length;
- SDL_utf8strlcpy(event.edit.text, text, SDL_arraysize(event.edit.text));
- posted = (SDL_PushEvent(&event) > 0);
- }
- return (posted);
- }
- void
- SDL_KeyboardQuit(void)
- {
- }
- const Uint8 *
- SDL_GetKeyboardState(int *numkeys)
- {
- SDL_Keyboard *keyboard = &SDL_keyboard;
- if (numkeys != (int *) 0) {
- *numkeys = SDL_NUM_SCANCODES;
- }
- return keyboard->keystate;
- }
- SDL_Keymod
- SDL_GetModState(void)
- {
- SDL_Keyboard *keyboard = &SDL_keyboard;
- return (SDL_Keymod) keyboard->modstate;
- }
- void
- SDL_SetModState(SDL_Keymod modstate)
- {
- SDL_Keyboard *keyboard = &SDL_keyboard;
- keyboard->modstate = modstate;
- }
- /* Note that SDL_ToggleModState() is not a public API. SDL_SetModState() is. */
- void
- SDL_ToggleModState(const SDL_Keymod modstate, const SDL_bool toggle)
- {
- SDL_Keyboard *keyboard = &SDL_keyboard;
- if (toggle) {
- keyboard->modstate |= modstate;
- } else {
- keyboard->modstate &= ~modstate;
- }
- }
- SDL_Keycode
- SDL_GetKeyFromScancode(SDL_Scancode scancode)
- {
- SDL_Keyboard *keyboard = &SDL_keyboard;
- if (((int)scancode) < SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) {
- SDL_InvalidParamError("scancode");
- return 0;
- }
- return keyboard->keymap[scancode];
- }
- SDL_Scancode
- SDL_GetScancodeFromKey(SDL_Keycode key)
- {
- SDL_Keyboard *keyboard = &SDL_keyboard;
- SDL_Scancode scancode;
- for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_NUM_SCANCODES;
- ++scancode) {
- if (keyboard->keymap[scancode] == key) {
- return scancode;
- }
- }
- return SDL_SCANCODE_UNKNOWN;
- }
- const char *
- SDL_GetScancodeName(SDL_Scancode scancode)
- {
- const char *name;
- if (((int)scancode) < SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) {
- SDL_InvalidParamError("scancode");
- return "";
- }
- name = SDL_scancode_names[scancode];
- if (name)
- return name;
- else
- return "";
- }
- SDL_Scancode SDL_GetScancodeFromName(const char *name)
- {
- int i;
- if (!name || !*name) {
- SDL_InvalidParamError("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;
- }
- }
- SDL_InvalidParamError("name");
- return SDL_SCANCODE_UNKNOWN;
- }
- const char *
- SDL_GetKeyName(SDL_Keycode key)
- {
- static char name[8];
- char *end;
- if (key & SDLK_SCANCODE_MASK) {
- return
- SDL_GetScancodeName((SDL_Scancode) (key & ~SDLK_SCANCODE_MASK));
- }
- switch (key) {
- case SDLK_RETURN:
- return SDL_GetScancodeName(SDL_SCANCODE_RETURN);
- case SDLK_ESCAPE:
- return SDL_GetScancodeName(SDL_SCANCODE_ESCAPE);
- case SDLK_BACKSPACE:
- return SDL_GetScancodeName(SDL_SCANCODE_BACKSPACE);
- case SDLK_TAB:
- return SDL_GetScancodeName(SDL_SCANCODE_TAB);
- case SDLK_SPACE:
- return SDL_GetScancodeName(SDL_SCANCODE_SPACE);
- case SDLK_DELETE:
- return SDL_GetScancodeName(SDL_SCANCODE_DELETE);
- default:
- /* Unaccented letter keys on latin keyboards are normally
- labeled in upper case (and probably on others like Greek or
- Cyrillic too, so if you happen to know for sure, please
- adapt this). */
- if (key >= 'a' && key <= 'z') {
- key -= 32;
- }
- end = SDL_UCS4ToUTF8((Uint32) key, name);
- *end = '\0';
- return name;
- }
- }
- SDL_Keycode
- SDL_GetKeyFromName(const char *name)
- {
- SDL_Keycode 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 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 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 key;
- }
- return SDLK_UNKNOWN;
- } else {
- if (SDL_strlen(name) == 1) {
- if (key >= 'A' && key <= 'Z') {
- key += 32;
- }
- return key;
- }
- /* Get the scancode for this name, and the associated keycode */
- return SDL_default_keymap[SDL_GetScancodeFromName(name)];
- }
- }
- /* vi: set ts=4 sw=4 expandtab: */
|