From 98bd60abe8f34dbbe538b6f85f5f5c02550b5236 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 11 Nov 2023 17:07:06 -0500 Subject: Add support for Num, Scroll, and Caps Lock --- include/pugl/pugl.h | 11 +++++++---- src/internal.c | 6 ++++++ src/mac.m | 32 ++++++++++++++++++-------------- src/win.c | 14 +++++++++----- src/x11.c | 5 ++++- test/test_utils.h | 7 +++++-- 6 files changed, 49 insertions(+), 26 deletions(-) diff --git a/include/pugl/pugl.h b/include/pugl/pugl.h index 9d2a8e1..2d7f4b4 100644 --- a/include/pugl/pugl.h +++ b/include/pugl/pugl.h @@ -415,10 +415,13 @@ typedef enum { /// Keyboard modifier flags typedef enum { - PUGL_MOD_SHIFT = 1U << 0U, ///< Shift key - PUGL_MOD_CTRL = 1U << 1U, ///< Control key - PUGL_MOD_ALT = 1U << 2U, ///< Alt/Option key - PUGL_MOD_SUPER = 1U << 3U, ///< Mod4/Command/Windows key + PUGL_MOD_SHIFT = 1U << 0U, ///< Shift pressed + PUGL_MOD_CTRL = 1U << 1U, ///< Control pressed + PUGL_MOD_ALT = 1U << 2U, ///< Alt/Option pressed + PUGL_MOD_SUPER = 1U << 3U, ///< Super/Command/Windows pressed + PUGL_MOD_NUM_LOCK = 1U << 4U, ///< Num lock enabled + PUGL_MOD_SCROLL_LOCK = 1U << 5U, ///< Scroll lock enabled + PUGL_MOD_CAPS_LOCK = 1U << 6U, ///< Caps lock enabled } PuglMod; /// Bitwise OR of #PuglMod values diff --git a/src/internal.c b/src/internal.c index ca710ce..3c4d304 100644 --- a/src/internal.c +++ b/src/internal.c @@ -132,6 +132,12 @@ puglFilterMods(const PuglMods state, const PuglKey key) case PUGL_KEY_SUPER_L: case PUGL_KEY_SUPER_R: return state & ~(PuglMods)PUGL_MOD_SUPER; + case PUGL_KEY_NUM_LOCK: + return state & ~(PuglMods)PUGL_MOD_NUM_LOCK; + case PUGL_KEY_SCROLL_LOCK: + return state & ~(PuglMods)PUGL_MOD_SCROLL_LOCK; + case PUGL_KEY_CAPS_LOCK: + return state & ~(PuglMods)PUGL_MOD_CAPS_LOCK; default: break; } diff --git a/src/mac.m b/src/mac.m index 8a89b18..cf7e8d2 100644 --- a/src/mac.m +++ b/src/mac.m @@ -372,7 +372,8 @@ getModifiers(const NSEvent* const ev) return (((modifierFlags & NSShiftKeyMask) ? PUGL_MOD_SHIFT : 0) | ((modifierFlags & NSControlKeyMask) ? PUGL_MOD_CTRL : 0) | ((modifierFlags & NSAlternateKeyMask) ? PUGL_MOD_ALT : 0) | - ((modifierFlags & NSCommandKeyMask) ? PUGL_MOD_SUPER : 0)); + ((modifierFlags & NSCommandKeyMask) ? PUGL_MOD_SUPER : 0) | + ((modifierFlags & (1U << 16U)) ? PUGL_MOD_CAPS_LOCK : 0)); } static PuglKey @@ -837,33 +838,36 @@ handleCrossing(PuglWrapperView* view, NSEvent* event, const PuglEventType type) } } +static bool +flagDiffers(const uint32_t lhs, const uint32_t rhs, const uint32_t mask) +{ + return (lhs & mask) != (rhs & mask); +} + - (void)flagsChanged:(NSEvent*)event { const uint32_t mods = getModifiers(event); - PuglEventType type = PUGL_NOTHING; PuglKey special = (PuglKey)0; const uint16_t keyCode = [event keyCode]; - if ((mods & PUGL_MOD_SHIFT) != (puglview->impl->mods & PUGL_MOD_SHIFT)) { - type = mods & PUGL_MOD_SHIFT ? PUGL_KEY_PRESS : PUGL_KEY_RELEASE; + if (flagDiffers(mods, puglview->impl->mods, PUGL_MOD_SHIFT)) { special = (keyCode == 0x3C) ? PUGL_KEY_SHIFT_R : PUGL_KEY_SHIFT_L; - } else if ((mods & PUGL_MOD_CTRL) != (puglview->impl->mods & PUGL_MOD_CTRL)) { - type = mods & PUGL_MOD_CTRL ? PUGL_KEY_PRESS : PUGL_KEY_RELEASE; + } else if (flagDiffers(mods, puglview->impl->mods, PUGL_MOD_CTRL)) { special = (keyCode == 0x3E) ? PUGL_KEY_CTRL_R : PUGL_KEY_CTRL_L; - } else if ((mods & PUGL_MOD_ALT) != (puglview->impl->mods & PUGL_MOD_ALT)) { - type = mods & PUGL_MOD_ALT ? PUGL_KEY_PRESS : PUGL_KEY_RELEASE; + } else if (flagDiffers(mods, puglview->impl->mods, PUGL_MOD_ALT)) { special = (keyCode == 0x3D) ? PUGL_KEY_ALT_R : PUGL_KEY_ALT_L; - } else if ((mods & PUGL_MOD_SUPER) != - (puglview->impl->mods & PUGL_MOD_SUPER)) { - type = mods & PUGL_MOD_SUPER ? PUGL_KEY_PRESS : PUGL_KEY_RELEASE; + } else if (flagDiffers(mods, puglview->impl->mods, PUGL_MOD_SUPER)) { special = PUGL_KEY_SUPER_L; // Left and right command are identical + } else if (flagDiffers(mods, puglview->impl->mods, PUGL_MOD_CAPS_LOCK)) { + special = PUGL_KEY_CAPS_LOCK; } if (special != 0) { - const NSPoint wloc = [self eventLocation:event]; - const NSPoint rloc = [NSEvent mouseLocation]; + const NSPoint wloc = [self eventLocation:event]; + const NSPoint rloc = [NSEvent mouseLocation]; + const bool release = [event type] == NSEventTypeKeyUp; - const PuglKeyEvent ev = {type, + const PuglKeyEvent ev = {release ? PUGL_KEY_RELEASE : PUGL_KEY_PRESS, 0, [event timestamp], wloc.x, diff --git a/src/win.c b/src/win.c index 3d245f2..1cc02e5 100644 --- a/src/win.c +++ b/src/win.c @@ -472,11 +472,15 @@ static uint32_t getModifiers(void) { // clang-format off - return (((GetKeyState(VK_SHIFT) < 0) ? (uint32_t)PUGL_MOD_SHIFT : 0U) | - ((GetKeyState(VK_CONTROL) < 0) ? (uint32_t)PUGL_MOD_CTRL : 0U) | - ((GetKeyState(VK_MENU) < 0) ? (uint32_t)PUGL_MOD_ALT : 0U) | - ((GetKeyState(VK_LWIN) < 0) ? (uint32_t)PUGL_MOD_SUPER : 0U) | - ((GetKeyState(VK_RWIN) < 0) ? (uint32_t)PUGL_MOD_SUPER : 0U)); + return ( + ((GetKeyState(VK_SHIFT) < 0) ? (uint32_t)PUGL_MOD_SHIFT : 0U) | + ((GetKeyState(VK_CONTROL) < 0) ? (uint32_t)PUGL_MOD_CTRL : 0U) | + ((GetKeyState(VK_MENU) < 0) ? (uint32_t)PUGL_MOD_ALT : 0U) | + ((GetKeyState(VK_LWIN) < 0) ? (uint32_t)PUGL_MOD_SUPER : 0U) | + ((GetKeyState(VK_RWIN) < 0) ? (uint32_t)PUGL_MOD_SUPER : 0U) | + ((GetKeyState(VK_NUMLOCK) & 1U) ? (uint32_t)PUGL_MOD_NUM_LOCK : 0U) | + ((GetKeyState(VK_SCROLL) & 1U) ? (uint32_t)PUGL_MOD_SCROLL_LOCK : 0U) | + ((GetKeyState(VK_CAPITAL) & 1U) ? (uint32_t)PUGL_MOD_CAPS_LOCK : 0U)); // clang-format on } diff --git a/src/x11.c b/src/x11.c index 19633e3..4db095e 100644 --- a/src/x11.c +++ b/src/x11.c @@ -920,7 +920,10 @@ translateModifiers(const unsigned xstate) return (((xstate & ShiftMask) ? (uint32_t)PUGL_MOD_SHIFT : 0U) | ((xstate & ControlMask) ? (uint32_t)PUGL_MOD_CTRL : 0U) | ((xstate & Mod1Mask) ? (uint32_t)PUGL_MOD_ALT : 0U) | - ((xstate & Mod4Mask) ? (uint32_t)PUGL_MOD_SUPER : 0U)); + ((xstate & Mod4Mask) ? (uint32_t)PUGL_MOD_SUPER : 0U) | + ((xstate & Mod2Mask) ? (uint32_t)PUGL_MOD_NUM_LOCK : 0U) | + ((xstate & Mod3Mask) ? (uint32_t)PUGL_MOD_SCROLL_LOCK : 0U) | + ((xstate & LockMask) ? (uint32_t)PUGL_MOD_CAPS_LOCK : 0U)); } static PuglStatus diff --git a/test/test_utils.h b/test/test_utils.h index 19ad5ba..214b360 100644 --- a/test/test_utils.h +++ b/test/test_utils.h @@ -51,11 +51,14 @@ static inline int printModifiers(const uint32_t mods) { return fprintf(stderr, - "Modifiers:%s%s%s%s\n", + "Modifiers:%s%s%s%s%s%s%s\n", (mods & PUGL_MOD_SHIFT) ? " Shift" : "", (mods & PUGL_MOD_CTRL) ? " Ctrl" : "", (mods & PUGL_MOD_ALT) ? " Alt" : "", - (mods & PUGL_MOD_SUPER) ? " Super" : ""); + (mods & PUGL_MOD_SUPER) ? " Super" : "", + (mods & PUGL_MOD_NUM_LOCK) ? " Num" : "", + (mods & PUGL_MOD_SCROLL_LOCK) ? " Scroll" : "", + (mods & PUGL_MOD_CAPS_LOCK) ? " Caps" : ""); } static inline const char* -- cgit v1.2.1