From 321397d1dd86b2a2a308221609dd93308f2bd6cd Mon Sep 17 00:00:00 2001 From: Miku AuahDark Date: Sat, 16 Apr 2022 11:12:48 +0800 Subject: [PATCH] Add love.keyboard.isModifierActive. --- changes.txt | 1 + src/modules/keyboard/Keyboard.cpp | 20 ++++++++++++++++++++ src/modules/keyboard/Keyboard.h | 25 +++++++++++++++++++++++++ src/modules/keyboard/sdl/Keyboard.cpp | 26 ++++++++++++++++++++++++++ src/modules/keyboard/sdl/Keyboard.h | 1 + src/modules/keyboard/wrap_Keyboard.cpp | 12 ++++++++++++ 6 files changed, 85 insertions(+) diff --git a/changes.txt b/changes.txt index a30a5f322..2b98cbc6e 100644 --- a/changes.txt +++ b/changes.txt @@ -42,6 +42,7 @@ Released: N/A * Added a variant of love.graphics.setColorMask which accepts a single boolean. * Added new 'clampone' wrap mode. * Added a variant of Font:getWidth which takes a codepoint number argument. +* Added love.keyboard.isModifierActive. * Added love.system.getPreferredLocales. * Added love.localechanged callback. diff --git a/src/modules/keyboard/Keyboard.cpp b/src/modules/keyboard/Keyboard.cpp index 47f5baf69..05c4bed70 100644 --- a/src/modules/keyboard/Keyboard.cpp +++ b/src/modules/keyboard/Keyboard.cpp @@ -47,6 +47,16 @@ bool Keyboard::getConstant(Scancode in, const char *&out) return scancodes.find(in, out); } +bool Keyboard::getConstant(const char *in, ModifierKey &out) +{ + return modifiers.find(in, out); +} + +bool Keyboard::getConstant(ModifierKey in, const char *&out) +{ + return modifiers.find(in, out); +} + StringMap::Entry Keyboard::keyEntries[] = { {"unknown", Keyboard::KEY_UNKNOWN}, @@ -521,5 +531,15 @@ StringMap::Entry Keyboard::scan StringMap Keyboard::scancodes(Keyboard::scancodeEntries, sizeof(Keyboard::scancodeEntries)); +StringMap::Entry Keyboard::modifierEntries[] = +{ + {"numlock", MODKEY_NUMLOCK}, + {"capslock", MODKEY_CAPSLOCK}, + {"scrolllock", MODKEY_SCROLLLOCK}, + {"mode", MODKEY_MODE}, +}; + +StringMap Keyboard::modifiers(Keyboard::modifierEntries, sizeof(Keyboard::modifierEntries)); + } // keyboard } // love diff --git a/src/modules/keyboard/Keyboard.h b/src/modules/keyboard/Keyboard.h index d28c561e8..73ea3faeb 100644 --- a/src/modules/keyboard/Keyboard.h +++ b/src/modules/keyboard/Keyboard.h @@ -519,6 +519,18 @@ public: SCANCODE_MAX_ENUM }; + /** + * Modifier keys. These are special keys that temporarily modifies the normal function of a button when active. + **/ + enum ModifierKey { + MODKEY_NUMLOCK, + MODKEY_CAPSLOCK, + MODKEY_SCROLLLOCK, + MODKEY_MODE, + + MODKEY_MAX_ENUM + }; + virtual ~Keyboard() {} // Implements Module. @@ -550,6 +562,13 @@ public: **/ virtual bool isScancodeDown(const std::vector &scancodelist) const = 0; + /** + * Checks whether specific modifier key is active or not. + * @param key Modifier key to check. + * @return Whether the specified modifier key is active. + **/ + virtual bool isModifierActive(ModifierKey key) const = 0; + /** * Gets the key corresponding to the specified scancode according to the * current keyboard layout. @@ -592,6 +611,9 @@ public: static bool getConstant(const char *in, Scancode &out); static bool getConstant(Scancode in, const char *&out); + static bool getConstant(const char *in, ModifierKey &out); + static bool getConstant(ModifierKey in, const char *&out); + private: static StringMap::Entry keyEntries[]; @@ -600,6 +622,9 @@ private: static StringMap::Entry scancodeEntries[]; static StringMap scancodes; + static StringMap::Entry modifierEntries[]; + static StringMap modifiers; + }; // Keyboard } // keyboard diff --git a/src/modules/keyboard/sdl/Keyboard.cpp b/src/modules/keyboard/sdl/Keyboard.cpp index 51150e7fe..1abb0858d 100644 --- a/src/modules/keyboard/sdl/Keyboard.cpp +++ b/src/modules/keyboard/sdl/Keyboard.cpp @@ -18,9 +18,16 @@ * 3. This notice may not be removed or altered from any source distribution. **/ +#include + #include "Keyboard.h" #include "window/Window.h" +// SDL before 2.0.18 lack KMOD_SCROLL. Use KMOD_RESERVED instead. +#if !SDL_VERSION_ATLEAST(2, 0, 18) +#define KMOD_SCROLL KMOD_RESERVED +#endif // !SDL_VERSION_ATLEAST(2, 0, 18) + namespace love { namespace keyboard @@ -78,6 +85,25 @@ bool Keyboard::isScancodeDown(const std::vector &scancodelist) const return false; } +bool Keyboard::isModifierActive(ModifierKey key) const +{ + int modstate = SDL_GetModState(); + + switch (key) + { + case MODKEY_NUMLOCK: + return (modstate & KMOD_NUM) != 0; + case MODKEY_CAPSLOCK: + return (modstate & KMOD_CAPS) != 0; + case MODKEY_SCROLLLOCK: + return (modstate & KMOD_SCROLL) != 0; + case MODKEY_MODE: + return (modstate & KMOD_MODE) != 0; + } + + return false; +} + Keyboard::Key Keyboard::getKeyFromScancode(Scancode scancode) const { SDL_Scancode sdlscancode = SDL_SCANCODE_UNKNOWN; diff --git a/src/modules/keyboard/sdl/Keyboard.h b/src/modules/keyboard/sdl/Keyboard.h index e3e889f86..776b9789e 100644 --- a/src/modules/keyboard/sdl/Keyboard.h +++ b/src/modules/keyboard/sdl/Keyboard.h @@ -48,6 +48,7 @@ public: bool hasKeyRepeat() const; bool isDown(const std::vector &keylist) const; bool isScancodeDown(const std::vector &scancodelist) const; + bool isModifierActive(ModifierKey key) const; Key getKeyFromScancode(Scancode scancode) const; Scancode getScancodeFromKey(Key key) const; diff --git a/src/modules/keyboard/wrap_Keyboard.cpp b/src/modules/keyboard/wrap_Keyboard.cpp index 1e0def63c..64c9728b1 100644 --- a/src/modules/keyboard/wrap_Keyboard.cpp +++ b/src/modules/keyboard/wrap_Keyboard.cpp @@ -187,6 +187,17 @@ int w_hasScreenKeyboard(lua_State *L) return 1; } +int w_isModifierActive(lua_State* L) +{ + const char *keystr = luaL_checkstring(L, 1); + Keyboard::ModifierKey key; + if (!Keyboard::getConstant(keystr, key)) + return luax_enumerror(L, "modifier keys", keystr); + + luax_pushboolean(L, instance()->isModifierActive(key)); + return 1; +} + // List of functions to wrap. static const luaL_Reg functions[] = { @@ -199,6 +210,7 @@ static const luaL_Reg functions[] = { "isScancodeDown", w_isScancodeDown }, { "getScancodeFromKey", w_getScancodeFromKey }, { "getKeyFromScancode", w_getKeyFromScancode }, + { "isModifierActive", w_isModifierActive }, { 0, 0 } };