aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/pugl/pugl.h51
-rw-r--r--src/mac.m69
-rw-r--r--src/win.c86
-rw-r--r--src/x11.c73
-rw-r--r--test/test_utils.h105
5 files changed, 256 insertions, 128 deletions
diff --git a/include/pugl/pugl.h b/include/pugl/pugl.h
index 2df04a5..39c051e 100644
--- a/include/pugl/pugl.h
+++ b/include/pugl/pugl.h
@@ -358,16 +358,22 @@ typedef enum {
PUGL_KEY_F10, ///< F10
PUGL_KEY_F11, ///< F11
PUGL_KEY_F12, ///< F12
+ PUGL_KEY_PAGE_UP = 0xE031, ///< Page Up
+ PUGL_KEY_PAGE_DOWN, ///< Page Down
+ PUGL_KEY_END, ///< End
+ PUGL_KEY_HOME, ///< Home
PUGL_KEY_LEFT, ///< Left
PUGL_KEY_UP, ///< Up
PUGL_KEY_RIGHT, ///< Right
PUGL_KEY_DOWN, ///< Down
- PUGL_KEY_PAGE_UP, ///< Page Up
- PUGL_KEY_PAGE_DOWN, ///< Page Down
- PUGL_KEY_HOME, ///< Home
- PUGL_KEY_END, ///< End
+ PUGL_KEY_PRINT_SCREEN = 0xE041U, ///< Print Screen
PUGL_KEY_INSERT, ///< Insert
- PUGL_KEY_SHIFT_L, ///< Left Shift
+ PUGL_KEY_PAUSE, ///< Pause/Break
+ PUGL_KEY_MENU, ///< Menu
+ PUGL_KEY_NUM_LOCK, ///< Num Lock
+ PUGL_KEY_SCROLL_LOCK, ///< Scroll Lock
+ PUGL_KEY_CAPS_LOCK, ///< Caps Lock
+ PUGL_KEY_SHIFT_L = 0xE051U, ///< Left Shift
PUGL_KEY_SHIFT_R, ///< Right Shift
PUGL_KEY_CTRL_L, ///< Left Control
PUGL_KEY_CTRL_R, ///< Right Control
@@ -375,12 +381,35 @@ typedef enum {
PUGL_KEY_ALT_R, ///< Right Alt / AltGr
PUGL_KEY_SUPER_L, ///< Left Super
PUGL_KEY_SUPER_R, ///< Right Super
- PUGL_KEY_MENU, ///< Menu
- PUGL_KEY_CAPS_LOCK, ///< Caps Lock
- PUGL_KEY_SCROLL_LOCK, ///< Scroll Lock
- PUGL_KEY_NUM_LOCK, ///< Num Lock
- PUGL_KEY_PRINT_SCREEN, ///< Print Screen
- PUGL_KEY_PAUSE ///< Pause
+ PUGL_KEY_PAD_0 = 0xE060U, ///< Keypad 0
+ PUGL_KEY_PAD_1, ///< Keypad 1
+ PUGL_KEY_PAD_2, ///< Keypad 2
+ PUGL_KEY_PAD_3, ///< Keypad 3
+ PUGL_KEY_PAD_4, ///< Keypad 4
+ PUGL_KEY_PAD_5, ///< Keypad 5
+ PUGL_KEY_PAD_6, ///< Keypad 6
+ PUGL_KEY_PAD_7, ///< Keypad 7
+ PUGL_KEY_PAD_8, ///< Keypad 8
+ PUGL_KEY_PAD_9, ///< Keypad 9
+ PUGL_KEY_PAD_ENTER, ///< Keypad Enter
+ PUGL_KEY_PAD_PAGE_UP = 0xE071U, ///< Keypad Page Up
+ PUGL_KEY_PAD_PAGE_DOWN, ///< Keypad Page Down
+ PUGL_KEY_PAD_END, ///< Keypad End
+ PUGL_KEY_PAD_HOME, ///< Keypad Home
+ PUGL_KEY_PAD_LEFT, ///< Keypad Left
+ PUGL_KEY_PAD_UP, ///< Keypad Up
+ PUGL_KEY_PAD_RIGHT, ///< Keypad Right
+ PUGL_KEY_PAD_DOWN, ///< Keypad Down
+ PUGL_KEY_PAD_CLEAR = 0xE09DU, ///< Keypad Clear/Begin
+ PUGL_KEY_PAD_INSERT, ///< Keypad Insert
+ PUGL_KEY_PAD_DELETE, ///< Keypad Delete
+ PUGL_KEY_PAD_EQUAL, ///< Keypad Equal
+ PUGL_KEY_PAD_MULTIPLY = 0xE0AAU, ///< Keypad Multiply
+ PUGL_KEY_PAD_ADD, ///< Keypad Add
+ PUGL_KEY_PAD_SEPARATOR, ///< Keypad Separator
+ PUGL_KEY_PAD_SUBTRACT, ///< Keypad Subtract
+ PUGL_KEY_PAD_DECIMAL, ///< Keypad Decimal
+ PUGL_KEY_PAD_DIVIDE, ///< Keypad Divide
} PuglKey;
/// Keyboard modifier flags
diff --git a/src/mac.m b/src/mac.m
index ce90b9a..fa5355f 100644
--- a/src/mac.m
+++ b/src/mac.m
@@ -379,31 +379,12 @@ keySymToSpecial(const NSEvent* const ev)
{
NSString* chars = [ev charactersIgnoringModifiers];
if ([chars length] == 1) {
- switch ([chars characterAtIndex:0]) {
- case NSF1FunctionKey:
- return PUGL_KEY_F1;
- case NSF2FunctionKey:
- return PUGL_KEY_F2;
- case NSF3FunctionKey:
- return PUGL_KEY_F3;
- case NSF4FunctionKey:
- return PUGL_KEY_F4;
- case NSF5FunctionKey:
- return PUGL_KEY_F5;
- case NSF6FunctionKey:
- return PUGL_KEY_F6;
- case NSF7FunctionKey:
- return PUGL_KEY_F7;
- case NSF8FunctionKey:
- return PUGL_KEY_F8;
- case NSF9FunctionKey:
- return PUGL_KEY_F9;
- case NSF10FunctionKey:
- return PUGL_KEY_F10;
- case NSF11FunctionKey:
- return PUGL_KEY_F11;
- case NSF12FunctionKey:
- return PUGL_KEY_F12;
+ const unichar sym = [chars characterAtIndex:0];
+ if (sym >= NSF1FunctionKey && sym <= NSF12FunctionKey) {
+ return (PuglKey)(PUGL_KEY_F1 + (sym - NSF1FunctionKey));
+ }
+
+ switch (sym) {
case NSDeleteCharacter:
return PUGL_KEY_BACKSPACE;
case NSDeleteFunctionKey:
@@ -439,6 +420,44 @@ keySymToSpecial(const NSEvent* const ev)
}
// SHIFT, CTRL, ALT, and SUPER are handled in [flagsChanged]
}
+
+ switch ([ev keyCode]) {
+ case 0x41:
+ return PUGL_KEY_PAD_DECIMAL;
+ case 0x43:
+ return PUGL_KEY_PAD_MULTIPLY;
+ case 0x45:
+ return PUGL_KEY_PAD_ADD;
+ case 0x4B:
+ return PUGL_KEY_PAD_DIVIDE;
+ case 0x4C:
+ return PUGL_KEY_PAD_ENTER;
+ case 0x4E:
+ return PUGL_KEY_PAD_SUBTRACT;
+ case 0x51:
+ return PUGL_KEY_PAD_EQUAL;
+ case 0x52:
+ return PUGL_KEY_PAD_0;
+ case 0x53:
+ return PUGL_KEY_PAD_1;
+ case 0x54:
+ return PUGL_KEY_PAD_2;
+ case 0x55:
+ return PUGL_KEY_PAD_3;
+ case 0x56:
+ return PUGL_KEY_PAD_4;
+ case 0x57:
+ return PUGL_KEY_PAD_5;
+ case 0x58:
+ return PUGL_KEY_PAD_6;
+ case 0x59:
+ return PUGL_KEY_PAD_7;
+ case 0x5B:
+ return PUGL_KEY_PAD_8;
+ case 0x5C:
+ return PUGL_KEY_PAD_9;
+ }
+
return (PuglKey)0;
}
diff --git a/src/win.c b/src/win.c
index ed78baa..e020b86 100644
--- a/src/win.c
+++ b/src/win.c
@@ -403,42 +403,35 @@ puglFreeWorldInternals(PuglWorld* world)
}
static PuglKey
+keyInRange(const WPARAM winSym,
+ const WPARAM winMin,
+ const WPARAM winMax,
+ const PuglKey puglMin)
+{
+ return (winSym >= winMin && winSym <= winMax)
+ ? (PuglKey)(puglMin + (winSym - winMin))
+ : (PuglKey)0;
+}
+
+static PuglKey
keySymToSpecial(const WPARAM sym, const bool ext)
{
+ PuglKey key = (PuglKey)0;
+ if ((key = keyInRange(sym, VK_F1, VK_F12, PUGL_KEY_F1)) ||
+ (key = keyInRange(sym,
+ VK_PRIOR,
+ VK_DOWN,
+ ext ? PUGL_KEY_PAGE_UP : PUGL_KEY_PAD_PAGE_UP)) ||
+ (key = keyInRange(sym, VK_NUMPAD0, VK_NUMPAD9, PUGL_KEY_PAD_0)) ||
+ (key = keyInRange(sym, VK_MULTIPLY, VK_DIVIDE, PUGL_KEY_PAD_MULTIPLY)) ||
+ (key = keyInRange(sym, VK_LSHIFT, VK_RMENU, PUGL_KEY_SHIFT_L))) {
+ return key;
+ }
+
// clang-format off
switch (sym) {
- case VK_F1: return PUGL_KEY_F1;
- case VK_F2: return PUGL_KEY_F2;
- case VK_F3: return PUGL_KEY_F3;
- case VK_F4: return PUGL_KEY_F4;
- case VK_F5: return PUGL_KEY_F5;
- case VK_F6: return PUGL_KEY_F6;
- case VK_F7: return PUGL_KEY_F7;
- case VK_F8: return PUGL_KEY_F8;
- case VK_F9: return PUGL_KEY_F9;
- case VK_F10: return PUGL_KEY_F10;
- case VK_F11: return PUGL_KEY_F11;
- case VK_F12: return PUGL_KEY_F12;
case VK_BACK: return PUGL_KEY_BACKSPACE;
- case VK_DELETE: return PUGL_KEY_DELETE;
- case VK_LEFT: return PUGL_KEY_LEFT;
- case VK_UP: return PUGL_KEY_UP;
- case VK_RIGHT: return PUGL_KEY_RIGHT;
- case VK_DOWN: return PUGL_KEY_DOWN;
- case VK_PRIOR: return PUGL_KEY_PAGE_UP;
- case VK_NEXT: return PUGL_KEY_PAGE_DOWN;
- case VK_HOME: return PUGL_KEY_HOME;
- case VK_END: return PUGL_KEY_END;
- case VK_INSERT: return PUGL_KEY_INSERT;
- case VK_SHIFT: return ext ? PUGL_KEY_SHIFT_L : PUGL_KEY_SHIFT_R;
- case VK_LSHIFT: return PUGL_KEY_SHIFT_L;
- case VK_RSHIFT: return PUGL_KEY_SHIFT_R;
- case VK_CONTROL: return ext ? PUGL_KEY_CTRL_L : PUGL_KEY_CTRL_R;
- case VK_LCONTROL: return PUGL_KEY_CTRL_L;
- case VK_RCONTROL: return PUGL_KEY_CTRL_R;
- case VK_MENU: return ext ? PUGL_KEY_ALT_L : PUGL_KEY_ALT_R;
- case VK_LMENU: return PUGL_KEY_ALT_L;
- case VK_RMENU: return PUGL_KEY_ALT_R;
+ case VK_CLEAR: return PUGL_KEY_PAD_CLEAR;
case VK_LWIN: return PUGL_KEY_SUPER_L;
case VK_RWIN: return PUGL_KEY_SUPER_R;
case VK_CAPITAL: return PUGL_KEY_CAPS_LOCK;
@@ -449,6 +442,29 @@ keySymToSpecial(const WPARAM sym, const bool ext)
}
// clang-format on
+ if (ext) {
+ // clang-format off
+ switch (sym) {
+ case VK_RETURN: return PUGL_KEY_PAD_ENTER;
+ case VK_INSERT: return PUGL_KEY_INSERT;
+ case VK_DELETE: return PUGL_KEY_DELETE;
+ case VK_SHIFT: return PUGL_KEY_SHIFT_L;
+ case VK_CONTROL: return PUGL_KEY_CTRL_L;
+ case VK_MENU: return PUGL_KEY_ALT_L;
+ }
+ // clang-format on
+ } else {
+ // clang-format off
+ switch (sym) {
+ case VK_INSERT: return PUGL_KEY_PAD_INSERT;
+ case VK_DELETE: return PUGL_KEY_PAD_DELETE;
+ case VK_SHIFT: return PUGL_KEY_SHIFT_R;
+ case VK_CONTROL: return PUGL_KEY_CTRL_R;
+ case VK_MENU: return PUGL_KEY_ALT_R;
+ }
+ // clang-format on
+ }
+
return (PuglKey)0;
}
@@ -561,13 +577,9 @@ initKeyEvent(PuglKeyEvent* event,
event->keycode = (uint32_t)((lParam & 0xFF0000) >> 16);
event->key = 0;
- const PuglKey special = keySymToSpecial(vkey);
+ const PuglKey special = keySymToSpecial(vkey, ext);
if (special) {
- if (ext && (special == PUGL_KEY_CTRL_L || special == PUGL_KEY_ALT_L)) {
- event->key = (uint32_t)special + 1U; // Right hand key
- } else {
- event->key = (uint32_t)special;
- }
+ event->key = (uint32_t)special;
} else if (!dead) {
// Translate unshifted key
BYTE keyboardState[256] = PUGL_INIT_STRUCT;
diff --git a/src/x11.c b/src/x11.c
index b389932..e1e948f 100644
--- a/src/x11.c
+++ b/src/x11.c
@@ -810,47 +810,48 @@ puglFreeWorldInternals(PuglWorld* const world)
}
static PuglKey
+keyInRange(const KeySym xSym,
+ const KeySym xMin,
+ const KeySym xMax,
+ const PuglKey puglMin)
+{
+ return (xSym >= xMin && xSym <= xMax) ? (PuglKey)(puglMin + (xSym - xMin))
+ : (PuglKey)0;
+}
+
+static PuglKey
keySymToSpecial(const KeySym sym)
{
+ PuglKey key = (PuglKey)0;
+ if ((key = keyInRange(sym, XK_F1, XK_F12, PUGL_KEY_F1)) ||
+ (key = keyInRange(sym, XK_Page_Up, XK_End, PUGL_KEY_PAGE_UP)) ||
+ (key = keyInRange(sym, XK_Home, XK_Down, PUGL_KEY_HOME)) ||
+ (key = keyInRange(sym, XK_Shift_L, XK_Control_R, PUGL_KEY_SHIFT_L)) ||
+ (key = keyInRange(sym, XK_Alt_L, XK_Super_R, PUGL_KEY_ALT_L)) ||
+ (key = keyInRange(sym, XK_KP_Home, XK_KP_Down, PUGL_KEY_PAD_HOME)) ||
+ (key = keyInRange(sym, XK_KP_0, XK_KP_9, PUGL_KEY_PAD_0)) ||
+ (key = keyInRange(sym, XK_KP_Begin, XK_KP_Delete, PUGL_KEY_PAD_CLEAR)) ||
+ (key = keyInRange(
+ sym, XK_KP_Multiply, XK_KP_Divide, PUGL_KEY_PAD_MULTIPLY))) {
+ return key;
+ }
+
// clang-format off
switch (sym) {
- case XK_F1: return PUGL_KEY_F1;
- case XK_F2: return PUGL_KEY_F2;
- case XK_F3: return PUGL_KEY_F3;
- case XK_F4: return PUGL_KEY_F4;
- case XK_F5: return PUGL_KEY_F5;
- case XK_F6: return PUGL_KEY_F6;
- case XK_F7: return PUGL_KEY_F7;
- case XK_F8: return PUGL_KEY_F8;
- case XK_F9: return PUGL_KEY_F9;
- case XK_F10: return PUGL_KEY_F10;
- case XK_F11: return PUGL_KEY_F11;
- case XK_F12: return PUGL_KEY_F12;
- case XK_Left: return PUGL_KEY_LEFT;
- case XK_Up: return PUGL_KEY_UP;
- case XK_Right: return PUGL_KEY_RIGHT;
- case XK_Down: return PUGL_KEY_DOWN;
- case XK_Page_Up: return PUGL_KEY_PAGE_UP;
- case XK_Page_Down: return PUGL_KEY_PAGE_DOWN;
- case XK_Home: return PUGL_KEY_HOME;
- case XK_End: return PUGL_KEY_END;
+ case XK_ISO_Level3_Shift: return PUGL_KEY_ALT_R;
+ case XK_Pause: return PUGL_KEY_PAUSE;
+ case XK_Scroll_Lock: return PUGL_KEY_SCROLL_LOCK;
+ case XK_Print: return PUGL_KEY_PRINT_SCREEN;
case XK_Insert: return PUGL_KEY_INSERT;
- case XK_Shift_L: return PUGL_KEY_SHIFT_L;
- case XK_Shift_R: return PUGL_KEY_SHIFT_R;
- case XK_Control_L: return PUGL_KEY_CTRL_L;
- case XK_Control_R: return PUGL_KEY_CTRL_R;
- case XK_Alt_L: return PUGL_KEY_ALT_L;
- case XK_ISO_Level3_Shift:
- case XK_Alt_R: return PUGL_KEY_ALT_R;
- case XK_Super_L: return PUGL_KEY_SUPER_L;
- case XK_Super_R: return PUGL_KEY_SUPER_R;
case XK_Menu: return PUGL_KEY_MENU;
- case XK_Caps_Lock: return PUGL_KEY_CAPS_LOCK;
- case XK_Scroll_Lock: return PUGL_KEY_SCROLL_LOCK;
case XK_Num_Lock: return PUGL_KEY_NUM_LOCK;
- case XK_Print: return PUGL_KEY_PRINT_SCREEN;
- case XK_Pause: return PUGL_KEY_PAUSE;
- default: break;
+ case XK_KP_Enter: return PUGL_KEY_PAD_ENTER;
+ case XK_KP_Page_Up: return PUGL_KEY_PAD_PAGE_UP;
+ case XK_KP_Page_Down: return PUGL_KEY_PAD_PAGE_DOWN;
+ case XK_KP_End: return PUGL_KEY_PAD_END;
+ case XK_KP_Equal: return PUGL_KEY_PAD_CLEAR;
+ case XK_Caps_Lock: return PUGL_KEY_CAPS_LOCK;
+ default: break;
}
// clang-format on
@@ -878,7 +879,9 @@ translateKey(PuglView* const view, XEvent* const xevent, PuglEvent* const event)
const bool filter = XFilterEvent(xevent, None);
event->key.keycode = xevent->xkey.keycode;
- xevent->xkey.state = 0;
+
+ // Mask off the shift bit to get the lowercase "main" symbol
+ xevent->xkey.state = xevent->xkey.state & ~(unsigned)ShiftMask;
// Lookup unshifted key
char ustr[8] = {0};
diff --git a/test/test_utils.h b/test/test_utils.h
index 9b486d0..45df7b4 100644
--- a/test/test_utils.h
+++ b/test/test_utils.h
@@ -160,6 +160,15 @@ keyString(const uint32_t key)
return "F11";
case PUGL_KEY_F12:
return "F12";
+
+ case PUGL_KEY_PAGE_UP:
+ return "PAGE_UP";
+ case PUGL_KEY_PAGE_DOWN:
+ return "PAGE_DOWN";
+ case PUGL_KEY_END:
+ return "END";
+ case PUGL_KEY_HOME:
+ return "HOME";
case PUGL_KEY_LEFT:
return "LEFT";
case PUGL_KEY_UP:
@@ -168,16 +177,22 @@ keyString(const uint32_t key)
return "RIGHT";
case PUGL_KEY_DOWN:
return "DOWN";
- case PUGL_KEY_PAGE_UP:
- return "PAGE_UP";
- case PUGL_KEY_PAGE_DOWN:
- return "PAGE_DOWN";
- case PUGL_KEY_HOME:
- return "HOME";
- case PUGL_KEY_END:
- return "END";
+
+ case PUGL_KEY_PRINT_SCREEN:
+ return "PRINT_SCREEN";
case PUGL_KEY_INSERT:
return "INSERT";
+ case PUGL_KEY_PAUSE:
+ return "PAUSE";
+ case PUGL_KEY_MENU:
+ return "MENU";
+ case PUGL_KEY_NUM_LOCK:
+ return "NUM_LOCK";
+ case PUGL_KEY_SCROLL_LOCK:
+ return "SCROLL_LOCK";
+ case PUGL_KEY_CAPS_LOCK:
+ return "CAPS_LOCK";
+
case PUGL_KEY_SHIFT_L:
return "SHIFT_L";
case PUGL_KEY_SHIFT_R:
@@ -194,18 +209,68 @@ keyString(const uint32_t key)
return "SUPER_L";
case PUGL_KEY_SUPER_R:
return "SUPER_R";
- case PUGL_KEY_MENU:
- return "MENU";
- case PUGL_KEY_CAPS_LOCK:
- return "CAPS_LOCK";
- case PUGL_KEY_SCROLL_LOCK:
- return "SCROLL_LOCK";
- case PUGL_KEY_NUM_LOCK:
- return "NUM_LOCK";
- case PUGL_KEY_PRINT_SCREEN:
- return "PRINT_SCREEN";
- case PUGL_KEY_PAUSE:
- return "PAUSE";
+
+ case PUGL_KEY_PAD_0:
+ return "PAD_0";
+ case PUGL_KEY_PAD_1:
+ return "PAD_1";
+ case PUGL_KEY_PAD_2:
+ return "PAD_2";
+ case PUGL_KEY_PAD_3:
+ return "PAD_3";
+ case PUGL_KEY_PAD_4:
+ return "PAD_4";
+ case PUGL_KEY_PAD_5:
+ return "PAD_5";
+ case PUGL_KEY_PAD_6:
+ return "PAD_6";
+ case PUGL_KEY_PAD_7:
+ return "PAD_7";
+ case PUGL_KEY_PAD_8:
+ return "PAD_8";
+ case PUGL_KEY_PAD_9:
+ return "PAD_9";
+ case PUGL_KEY_PAD_ENTER:
+ return "PAD_ENTER";
+
+ case PUGL_KEY_PAD_PAGE_UP:
+ return "PAD_PAGE_UP";
+ case PUGL_KEY_PAD_PAGE_DOWN:
+ return "PAD_PAGE_DOWN";
+ case PUGL_KEY_PAD_END:
+ return "PAD_END";
+ case PUGL_KEY_PAD_HOME:
+ return "PAD_HOME";
+ case PUGL_KEY_PAD_LEFT:
+ return "PAD_LEFT";
+ case PUGL_KEY_PAD_UP:
+ return "PAD_UP";
+ case PUGL_KEY_PAD_RIGHT:
+ return "PAD_RIGHT";
+ case PUGL_KEY_PAD_DOWN:
+ return "PAD_DOWN";
+
+ case PUGL_KEY_PAD_CLEAR:
+ return "PAD_CLEAR";
+ case PUGL_KEY_PAD_INSERT:
+ return "PAD_INSERT";
+ case PUGL_KEY_PAD_DELETE:
+ return "PAD_DELETE";
+ case PUGL_KEY_PAD_EQUAL:
+ return "PAD_EQUAL";
+
+ case PUGL_KEY_PAD_MULTIPLY:
+ return "PAD_MULTIPLY";
+ case PUGL_KEY_PAD_ADD:
+ return "PAD_ADD";
+ case PUGL_KEY_PAD_SEPARATOR:
+ return "PAD_SEPARATOR";
+ case PUGL_KEY_PAD_SUBTRACT:
+ return "PAD_SUBTRACT";
+ case PUGL_KEY_PAD_DECIMAL:
+ return "PAD_DECIMAL";
+ case PUGL_KEY_PAD_DIVIDE:
+ return "PAD_DIVIDE";
}
return "";