Skip to content

Commit

Permalink
key press events and love.keyboard support arbitrary non-ascii key co…
Browse files Browse the repository at this point in the history
…nstants.

Closes love2d#2012.
  • Loading branch information
slime73 committed Jun 2, 2024
1 parent d576692 commit a23d531
Show file tree
Hide file tree
Showing 6 changed files with 509 additions and 686 deletions.
233 changes: 3 additions & 230 deletions src/modules/event/sdl/Event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,11 +240,10 @@ Message *Event::convert(const SDL_Event &e)

const char *txt;
const char *txt2;
std::map<SDL_Keycode, love::keyboard::Keyboard::Key>::const_iterator keyit;

#ifndef LOVE_MACOS
love::touch::sdl::Touch *touchmodule = nullptr;
love::touch::Touch::TouchInfo touchinfo;
love::touch::Touch::TouchInfo touchinfo = {};
#endif

switch (e.type)
Expand All @@ -257,10 +256,7 @@ Message *Event::convert(const SDL_Event &e)
break;
}

keyit = keys.find(e.key.keysym.sym);
if (keyit != keys.end())
key = keyit->second;

love::keyboard::sdl::Keyboard::getConstant(e.key.keysym.sym, key);
if (!love::keyboard::Keyboard::getConstant(key, txt))
txt = "unknown";

Expand All @@ -274,10 +270,7 @@ Message *Event::convert(const SDL_Event &e)
msg = new Message("keypressed", vargs);
break;
case SDL_EVENT_KEY_UP:
keyit = keys.find(e.key.keysym.sym);
if (keyit != keys.end())
key = keyit->second;

love::keyboard::sdl::Keyboard::getConstant(e.key.keysym.sym, key);
if (!love::keyboard::Keyboard::getConstant(key, txt))
txt = "unknown";

Expand Down Expand Up @@ -842,226 +835,6 @@ Message *Event::convertWindowEvent(const SDL_Event &e)
return msg;
}

std::map<SDL_Keycode, love::keyboard::Keyboard::Key> Event::createKeyMap()
{
using love::keyboard::Keyboard;

std::map<SDL_Keycode, Keyboard::Key> k;

k[SDLK_UNKNOWN] = Keyboard::KEY_UNKNOWN;

k[SDLK_RETURN] = Keyboard::KEY_RETURN;
k[SDLK_ESCAPE] = Keyboard::KEY_ESCAPE;
k[SDLK_BACKSPACE] = Keyboard::KEY_BACKSPACE;
k[SDLK_TAB] = Keyboard::KEY_TAB;
k[SDLK_SPACE] = Keyboard::KEY_SPACE;
k[SDLK_EXCLAIM] = Keyboard::KEY_EXCLAIM;
k[SDLK_QUOTEDBL] = Keyboard::KEY_QUOTEDBL;
k[SDLK_HASH] = Keyboard::KEY_HASH;
k[SDLK_PERCENT] = Keyboard::KEY_PERCENT;
k[SDLK_DOLLAR] = Keyboard::KEY_DOLLAR;
k[SDLK_AMPERSAND] = Keyboard::KEY_AMPERSAND;
k[SDLK_QUOTE] = Keyboard::KEY_QUOTE;
k[SDLK_LEFTPAREN] = Keyboard::KEY_LEFTPAREN;
k[SDLK_RIGHTPAREN] = Keyboard::KEY_RIGHTPAREN;
k[SDLK_ASTERISK] = Keyboard::KEY_ASTERISK;
k[SDLK_PLUS] = Keyboard::KEY_PLUS;
k[SDLK_COMMA] = Keyboard::KEY_COMMA;
k[SDLK_MINUS] = Keyboard::KEY_MINUS;
k[SDLK_PERIOD] = Keyboard::KEY_PERIOD;
k[SDLK_SLASH] = Keyboard::KEY_SLASH;
k[SDLK_0] = Keyboard::KEY_0;
k[SDLK_1] = Keyboard::KEY_1;
k[SDLK_2] = Keyboard::KEY_2;
k[SDLK_3] = Keyboard::KEY_3;
k[SDLK_4] = Keyboard::KEY_4;
k[SDLK_5] = Keyboard::KEY_5;
k[SDLK_6] = Keyboard::KEY_6;
k[SDLK_7] = Keyboard::KEY_7;
k[SDLK_8] = Keyboard::KEY_8;
k[SDLK_9] = Keyboard::KEY_9;
k[SDLK_COLON] = Keyboard::KEY_COLON;
k[SDLK_SEMICOLON] = Keyboard::KEY_SEMICOLON;
k[SDLK_LESS] = Keyboard::KEY_LESS;
k[SDLK_EQUALS] = Keyboard::KEY_EQUALS;
k[SDLK_GREATER] = Keyboard::KEY_GREATER;
k[SDLK_QUESTION] = Keyboard::KEY_QUESTION;
k[SDLK_AT] = Keyboard::KEY_AT;

k[SDLK_LEFTBRACKET] = Keyboard::KEY_LEFTBRACKET;
k[SDLK_BACKSLASH] = Keyboard::KEY_BACKSLASH;
k[SDLK_RIGHTBRACKET] = Keyboard::KEY_RIGHTBRACKET;
k[SDLK_CARET] = Keyboard::KEY_CARET;
k[SDLK_UNDERSCORE] = Keyboard::KEY_UNDERSCORE;
k[SDLK_BACKQUOTE] = Keyboard::KEY_BACKQUOTE;
k[SDLK_a] = Keyboard::KEY_A;
k[SDLK_b] = Keyboard::KEY_B;
k[SDLK_c] = Keyboard::KEY_C;
k[SDLK_d] = Keyboard::KEY_D;
k[SDLK_e] = Keyboard::KEY_E;
k[SDLK_f] = Keyboard::KEY_F;
k[SDLK_g] = Keyboard::KEY_G;
k[SDLK_h] = Keyboard::KEY_H;
k[SDLK_i] = Keyboard::KEY_I;
k[SDLK_j] = Keyboard::KEY_J;
k[SDLK_k] = Keyboard::KEY_K;
k[SDLK_l] = Keyboard::KEY_L;
k[SDLK_m] = Keyboard::KEY_M;
k[SDLK_n] = Keyboard::KEY_N;
k[SDLK_o] = Keyboard::KEY_O;
k[SDLK_p] = Keyboard::KEY_P;
k[SDLK_q] = Keyboard::KEY_Q;
k[SDLK_r] = Keyboard::KEY_R;
k[SDLK_s] = Keyboard::KEY_S;
k[SDLK_t] = Keyboard::KEY_T;
k[SDLK_u] = Keyboard::KEY_U;
k[SDLK_v] = Keyboard::KEY_V;
k[SDLK_w] = Keyboard::KEY_W;
k[SDLK_x] = Keyboard::KEY_X;
k[SDLK_y] = Keyboard::KEY_Y;
k[SDLK_z] = Keyboard::KEY_Z;

k[SDLK_CAPSLOCK] = Keyboard::KEY_CAPSLOCK;

k[SDLK_F1] = Keyboard::KEY_F1;
k[SDLK_F2] = Keyboard::KEY_F2;
k[SDLK_F3] = Keyboard::KEY_F3;
k[SDLK_F4] = Keyboard::KEY_F4;
k[SDLK_F5] = Keyboard::KEY_F5;
k[SDLK_F6] = Keyboard::KEY_F6;
k[SDLK_F7] = Keyboard::KEY_F7;
k[SDLK_F8] = Keyboard::KEY_F8;
k[SDLK_F9] = Keyboard::KEY_F9;
k[SDLK_F10] = Keyboard::KEY_F10;
k[SDLK_F11] = Keyboard::KEY_F11;
k[SDLK_F12] = Keyboard::KEY_F12;

k[SDLK_PRINTSCREEN] = Keyboard::KEY_PRINTSCREEN;
k[SDLK_SCROLLLOCK] = Keyboard::KEY_SCROLLLOCK;
k[SDLK_PAUSE] = Keyboard::KEY_PAUSE;
k[SDLK_INSERT] = Keyboard::KEY_INSERT;
k[SDLK_HOME] = Keyboard::KEY_HOME;
k[SDLK_PAGEUP] = Keyboard::KEY_PAGEUP;
k[SDLK_DELETE] = Keyboard::KEY_DELETE;
k[SDLK_END] = Keyboard::KEY_END;
k[SDLK_PAGEDOWN] = Keyboard::KEY_PAGEDOWN;
k[SDLK_RIGHT] = Keyboard::KEY_RIGHT;
k[SDLK_LEFT] = Keyboard::KEY_LEFT;
k[SDLK_DOWN] = Keyboard::KEY_DOWN;
k[SDLK_UP] = Keyboard::KEY_UP;

k[SDLK_NUMLOCKCLEAR] = Keyboard::KEY_NUMLOCKCLEAR;
k[SDLK_KP_DIVIDE] = Keyboard::KEY_KP_DIVIDE;
k[SDLK_KP_MULTIPLY] = Keyboard::KEY_KP_MULTIPLY;
k[SDLK_KP_MINUS] = Keyboard::KEY_KP_MINUS;
k[SDLK_KP_PLUS] = Keyboard::KEY_KP_PLUS;
k[SDLK_KP_ENTER] = Keyboard::KEY_KP_ENTER;
k[SDLK_KP_0] = Keyboard::KEY_KP_0;
k[SDLK_KP_1] = Keyboard::KEY_KP_1;
k[SDLK_KP_2] = Keyboard::KEY_KP_2;
k[SDLK_KP_3] = Keyboard::KEY_KP_3;
k[SDLK_KP_4] = Keyboard::KEY_KP_4;
k[SDLK_KP_5] = Keyboard::KEY_KP_5;
k[SDLK_KP_6] = Keyboard::KEY_KP_6;
k[SDLK_KP_7] = Keyboard::KEY_KP_7;
k[SDLK_KP_8] = Keyboard::KEY_KP_8;
k[SDLK_KP_9] = Keyboard::KEY_KP_9;
k[SDLK_KP_PERIOD] = Keyboard::KEY_KP_PERIOD;
k[SDLK_KP_COMMA] = Keyboard::KEY_KP_COMMA;
k[SDLK_KP_EQUALS] = Keyboard::KEY_KP_EQUALS;

k[SDLK_APPLICATION] = Keyboard::KEY_APPLICATION;
k[SDLK_POWER] = Keyboard::KEY_POWER;
k[SDLK_F13] = Keyboard::KEY_F13;
k[SDLK_F14] = Keyboard::KEY_F14;
k[SDLK_F15] = Keyboard::KEY_F15;
k[SDLK_F16] = Keyboard::KEY_F16;
k[SDLK_F17] = Keyboard::KEY_F17;
k[SDLK_F18] = Keyboard::KEY_F18;
k[SDLK_F19] = Keyboard::KEY_F19;
k[SDLK_F20] = Keyboard::KEY_F20;
k[SDLK_F21] = Keyboard::KEY_F21;
k[SDLK_F22] = Keyboard::KEY_F22;
k[SDLK_F23] = Keyboard::KEY_F23;
k[SDLK_F24] = Keyboard::KEY_F24;
k[SDLK_EXECUTE] = Keyboard::KEY_EXECUTE;
k[SDLK_HELP] = Keyboard::KEY_HELP;
k[SDLK_MENU] = Keyboard::KEY_MENU;
k[SDLK_SELECT] = Keyboard::KEY_SELECT;
k[SDLK_STOP] = Keyboard::KEY_STOP;
k[SDLK_AGAIN] = Keyboard::KEY_AGAIN;
k[SDLK_UNDO] = Keyboard::KEY_UNDO;
k[SDLK_CUT] = Keyboard::KEY_CUT;
k[SDLK_COPY] = Keyboard::KEY_COPY;
k[SDLK_PASTE] = Keyboard::KEY_PASTE;
k[SDLK_FIND] = Keyboard::KEY_FIND;
k[SDLK_MUTE] = Keyboard::KEY_MUTE;
k[SDLK_VOLUMEUP] = Keyboard::KEY_VOLUMEUP;
k[SDLK_VOLUMEDOWN] = Keyboard::KEY_VOLUMEDOWN;

k[SDLK_ALTERASE] = Keyboard::KEY_ALTERASE;
k[SDLK_SYSREQ] = Keyboard::KEY_SYSREQ;
k[SDLK_CANCEL] = Keyboard::KEY_CANCEL;
k[SDLK_CLEAR] = Keyboard::KEY_CLEAR;
k[SDLK_PRIOR] = Keyboard::KEY_PRIOR;
k[SDLK_RETURN2] = Keyboard::KEY_RETURN2;
k[SDLK_SEPARATOR] = Keyboard::KEY_SEPARATOR;
k[SDLK_OUT] = Keyboard::KEY_OUT;
k[SDLK_OPER] = Keyboard::KEY_OPER;
k[SDLK_CLEARAGAIN] = Keyboard::KEY_CLEARAGAIN;

k[SDLK_THOUSANDSSEPARATOR] = Keyboard::KEY_THOUSANDSSEPARATOR;
k[SDLK_DECIMALSEPARATOR] = Keyboard::KEY_DECIMALSEPARATOR;
k[SDLK_CURRENCYUNIT] = Keyboard::KEY_CURRENCYUNIT;
k[SDLK_CURRENCYSUBUNIT] = Keyboard::KEY_CURRENCYSUBUNIT;

k[SDLK_LCTRL] = Keyboard::KEY_LCTRL;
k[SDLK_LSHIFT] = Keyboard::KEY_LSHIFT;
k[SDLK_LALT] = Keyboard::KEY_LALT;
k[SDLK_LGUI] = Keyboard::KEY_LGUI;
k[SDLK_RCTRL] = Keyboard::KEY_RCTRL;
k[SDLK_RSHIFT] = Keyboard::KEY_RSHIFT;
k[SDLK_RALT] = Keyboard::KEY_RALT;
k[SDLK_RGUI] = Keyboard::KEY_RGUI;

k[SDLK_MODE] = Keyboard::KEY_MODE;

k[SDLK_AUDIONEXT] = Keyboard::KEY_AUDIONEXT;
k[SDLK_AUDIOPREV] = Keyboard::KEY_AUDIOPREV;
k[SDLK_AUDIOSTOP] = Keyboard::KEY_AUDIOSTOP;
k[SDLK_AUDIOPLAY] = Keyboard::KEY_AUDIOPLAY;
k[SDLK_AUDIOMUTE] = Keyboard::KEY_AUDIOMUTE;
k[SDLK_MEDIASELECT] = Keyboard::KEY_MEDIASELECT;
k[SDLK_WWW] = Keyboard::KEY_WWW;
k[SDLK_MAIL] = Keyboard::KEY_MAIL;
k[SDLK_CALCULATOR] = Keyboard::KEY_CALCULATOR;
k[SDLK_COMPUTER] = Keyboard::KEY_COMPUTER;
k[SDLK_AC_SEARCH] = Keyboard::KEY_APP_SEARCH;
k[SDLK_AC_HOME] = Keyboard::KEY_APP_HOME;
k[SDLK_AC_BACK] = Keyboard::KEY_APP_BACK;
k[SDLK_AC_FORWARD] = Keyboard::KEY_APP_FORWARD;
k[SDLK_AC_STOP] = Keyboard::KEY_APP_STOP;
k[SDLK_AC_REFRESH] = Keyboard::KEY_APP_REFRESH;
k[SDLK_AC_BOOKMARKS] = Keyboard::KEY_APP_BOOKMARKS;

k[SDLK_BRIGHTNESSDOWN] = Keyboard::KEY_BRIGHTNESSDOWN;
k[SDLK_BRIGHTNESSUP] = Keyboard::KEY_BRIGHTNESSUP;
k[SDLK_DISPLAYSWITCH] = Keyboard::KEY_DISPLAYSWITCH;
k[SDLK_KBDILLUMTOGGLE] = Keyboard::KEY_KBDILLUMTOGGLE;
k[SDLK_KBDILLUMDOWN] = Keyboard::KEY_KBDILLUMDOWN;
k[SDLK_KBDILLUMUP] = Keyboard::KEY_KBDILLUMUP;
k[SDLK_EJECT] = Keyboard::KEY_EJECT;
k[SDLK_SLEEP] = Keyboard::KEY_SLEEP;

#ifdef LOVE_ANDROID
k[SDLK_AC_BACK] = Keyboard::KEY_ESCAPE;
#endif

return k;
}

std::map<SDL_Keycode, love::keyboard::Keyboard::Key> Event::keys = Event::createKeyMap();

} // sdl
} // event
} // love
6 changes: 0 additions & 6 deletions src/modules/event/sdl/Event.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@
// SDL
#include <SDL_events.h>

// STL
#include <map>

namespace love
{
namespace event
Expand Down Expand Up @@ -72,9 +69,6 @@ class Event : public love::event::Event
Message *convertJoystickEvent(const SDL_Event &e) const;
Message *convertWindowEvent(const SDL_Event &e);

static std::map<SDL_Keycode, love::keyboard::Keyboard::Key> createKeyMap();
static std::map<SDL_Keycode, love::keyboard::Keyboard::Key> keys;

}; // Event

} // sdl
Expand Down
67 changes: 63 additions & 4 deletions src/modules/keyboard/Keyboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
**/

#include "common/config.h"
#include "libraries/utf8/utf8.h"

#include "Keyboard.h"

Expand All @@ -34,12 +35,70 @@ Keyboard::Keyboard(const char *name)

bool Keyboard::getConstant(const char *in, Key &out)
{
return keys.find(in, out);
auto it = stringToKey.find(in);
if (it != stringToKey.end())
{
out = (Key)it->second;
return true;
}

std::string text(in);
uint32 codepoint = 0;

try
{
codepoint = utf8::peek_next(text.begin(), text.end());
}
catch (utf8::exception &)
{
return false;
}

if (codepoint > 0)
{
stringToKey[text] = codepoint;
out = (Key)codepoint;
}

return false;
}

bool Keyboard::getConstant(Key in, const char *&out)
{
return keys.find(in, out);
if (keyToString.empty())
{
for (const auto &kvp : stringToKey)
keyToString[kvp.second] = kvp.first;
}

auto it = keyToString.find(in);
if (it != keyToString.end())
{
out = it->second.c_str();
return true;
}

char u[5] = { 0, 0, 0, 0, 0 };
ptrdiff_t length = 0;

try
{
char *end = utf8::unchecked::append(in, u);
length = end - u;
}
catch (utf8::exception &)
{
return false;
}

if (length > 0)
{
keyToString[in] = std::string(u, length);
out = keyToString[in].c_str();
return true;
}

return false;
}

bool Keyboard::getConstant(const char *in, Scancode &out)
Expand All @@ -62,7 +121,7 @@ bool Keyboard::getConstant(ModifierKey in, const char *&out)
return modifiers.find(in, out);
}

StringMap<Keyboard::Key, Keyboard::KEY_MAX_ENUM>::Entry Keyboard::keyEntries[] =
std::map<std::string, uint32> Keyboard::stringToKey =
{
{"unknown", Keyboard::KEY_UNKNOWN},

Expand Down Expand Up @@ -270,7 +329,7 @@ StringMap<Keyboard::Key, Keyboard::KEY_MAX_ENUM>::Entry Keyboard::keyEntries[] =
{"sleep", Keyboard::KEY_SLEEP},
};

StringMap<Keyboard::Key, Keyboard::KEY_MAX_ENUM> Keyboard::keys(Keyboard::keyEntries, sizeof(Keyboard::keyEntries));
std::map<uint32, std::string> Keyboard::keyToString;

StringMap<Keyboard::Scancode, Keyboard::SCANCODE_MAX_ENUM>::Entry Keyboard::scancodeEntries[] =
{
Expand Down
Loading

0 comments on commit a23d531

Please sign in to comment.