From aa1388da1733c06a29968b1f9bbf7548fd0ac37c Mon Sep 17 00:00:00 2001 From: Michael Dewberry Date: Tue, 3 Oct 2023 12:37:46 -0400 Subject: [PATCH] Support shift-mod remapping, add UK keyboard layout as a test --- res/keymaps/uk.json | 119 ++++++++++++++++++ src/plugin.cpp | 2 +- .../{screen => }/TeletypeKeyboard.cpp | 56 +++++++-- .../{screen => }/TeletypeKeyboard.hpp | 0 src/teletype/TeletypeWidget.cpp | 2 +- 5 files changed, 167 insertions(+), 12 deletions(-) create mode 100644 res/keymaps/uk.json rename src/teletype/{screen => }/TeletypeKeyboard.cpp (91%) rename src/teletype/{screen => }/TeletypeKeyboard.hpp (100%) diff --git a/res/keymaps/uk.json b/res/keymaps/uk.json new file mode 100644 index 0000000..b2c5785 --- /dev/null +++ b/res/keymaps/uk.json @@ -0,0 +1,119 @@ +{ + "name": "UK", + "keymap": [ + { "input": "GLFW_KEY_SPACE", "output": "HID_SPACEBAR" }, + { "input": "GLFW_KEY_APOSTROPHE", "output": "HID_QUOTE" }, + { "input": "GLFW_KEY_APOSTROPHE", "input_shift": true, "output": "HID_2", "output_shift": true }, + { "input": "GLFW_KEY_COMMA", "output": "HID_COMMA" }, + { "input": "GLFW_KEY_MINUS", "output": "HID_UNDERSCORE" }, + { "input": "GLFW_KEY_PERIOD", "output": "HID_DOT" }, + { "input": "GLFW_KEY_SLASH", "output": "HID_SLASH" }, + { "input": "GLFW_KEY_0", "output": "HID_0" }, + { "input": "GLFW_KEY_1", "output": "HID_1" }, + { "input": "GLFW_KEY_2", "output": "HID_2" }, + { "input": "GLFW_KEY_2", "input_shift": true, "output": "HID_QUOTE", "output_shift": true }, + { "input": "GLFW_KEY_3", "output": "HID_3" }, + { "input": "GLFW_KEY_3", "input_shift": true, "output": "HID_TILDE" }, + { "input": "GLFW_KEY_4", "output": "HID_4" }, + { "input": "GLFW_KEY_5", "output": "HID_5" }, + { "input": "GLFW_KEY_6", "output": "HID_6" }, + { "input": "GLFW_KEY_7", "output": "HID_7" }, + { "input": "GLFW_KEY_8", "output": "HID_8" }, + { "input": "GLFW_KEY_9", "output": "HID_9" }, + { "input": "GLFW_KEY_SEMICOLON", "output": "HID_COLON" }, + { "input": "GLFW_KEY_EQUAL", "output": "HID_PLUS" }, + { "input": "GLFW_KEY_A", "output": "HID_A" }, + { "input": "GLFW_KEY_B", "output": "HID_B" }, + { "input": "GLFW_KEY_C", "output": "HID_C" }, + { "input": "GLFW_KEY_D", "output": "HID_D" }, + { "input": "GLFW_KEY_E", "output": "HID_E" }, + { "input": "GLFW_KEY_F", "output": "HID_F" }, + { "input": "GLFW_KEY_G", "output": "HID_G" }, + { "input": "GLFW_KEY_H", "output": "HID_H" }, + { "input": "GLFW_KEY_I", "output": "HID_I" }, + { "input": "GLFW_KEY_J", "output": "HID_J" }, + { "input": "GLFW_KEY_K", "output": "HID_K" }, + { "input": "GLFW_KEY_L", "output": "HID_L" }, + { "input": "GLFW_KEY_M", "output": "HID_M" }, + { "input": "GLFW_KEY_N", "output": "HID_N" }, + { "input": "GLFW_KEY_O", "output": "HID_O" }, + { "input": "GLFW_KEY_P", "output": "HID_P" }, + { "input": "GLFW_KEY_Q", "output": "HID_Q" }, + { "input": "GLFW_KEY_R", "output": "HID_R" }, + { "input": "GLFW_KEY_S", "output": "HID_S" }, + { "input": "GLFW_KEY_T", "output": "HID_T" }, + { "input": "GLFW_KEY_U", "output": "HID_U" }, + { "input": "GLFW_KEY_V", "output": "HID_V" }, + { "input": "GLFW_KEY_W", "output": "HID_W" }, + { "input": "GLFW_KEY_X", "output": "HID_X" }, + { "input": "GLFW_KEY_Y", "output": "HID_Y" }, + { "input": "GLFW_KEY_Z", "output": "HID_Z" }, + { "input": "GLFW_KEY_LEFT_BRACKET", "output": "HID_OPEN_BRACKET" }, + { "input": "GLFW_KEY_BACKSLASH", "output": "HID_3", "output_shift": true }, + { "input": "GLFW_KEY_BACKSLASH", "input_shift": true, "output": "HID_TILDE", "output_shift": true }, + { "input": "GLFW_KEY_RIGHT_BRACKET", "output": "HID_CLOSE_BRACKET" }, + { "input": "GLFW_KEY_GRAVE_ACCENT", "output": "HID_TILDE" }, + { "input": "GLFW_KEY_WORLD_1", "output": "" }, + { "input": "GLFW_KEY_WORLD_2", "output": "" }, + { "input": "GLFW_KEY_ESCAPE", "output": "HID_ESCAPE" }, + { "input": "GLFW_KEY_ENTER", "output": "HID_ENTER" }, + { "input": "GLFW_KEY_TAB", "output": "HID_TAB" }, + { "input": "GLFW_KEY_BACKSPACE", "output": "HID_BACKSPACE" }, + { "input": "GLFW_KEY_INSERT", "output": "HID_INSERT" }, + { "input": "GLFW_KEY_DELETE", "output": "HID_DELETE" }, + { "input": "GLFW_KEY_RIGHT", "output": "HID_RIGHT" }, + { "input": "GLFW_KEY_LEFT", "output": "HID_LEFT" }, + { "input": "GLFW_KEY_DOWN", "output": "HID_DOWN" }, + { "input": "GLFW_KEY_UP", "output": "HID_UP" }, + { "input": "GLFW_KEY_PAGE_UP", "output": "HID_PAGEUP" }, + { "input": "GLFW_KEY_PAGE_DOWN", "output": "HID_PAGEDOWN" }, + { "input": "GLFW_KEY_HOME", "output": "HID_HOME" }, + { "input": "GLFW_KEY_END", "output": "HID_END" }, + { "input": "GLFW_KEY_CAPS_LOCK", "output": "HID_CAPS_LOCK" }, + { "input": "GLFW_KEY_SCROLL_LOCK", "output": "HID_SCROLL_LOCK" }, + { "input": "GLFW_KEY_NUM_LOCK", "output": "HID_KEYPAD_NUM_LOCK" }, + { "input": "GLFW_KEY_PRINT_SCREEN", "output": "HID_PRINTSCREEN" }, + { "input": "GLFW_KEY_PAUSE", "output": "HID_PAUSE" }, + { "input": "GLFW_KEY_F1", "output": "HID_F1" }, + { "input": "GLFW_KEY_F2", "output": "HID_F2" }, + { "input": "GLFW_KEY_F3", "output": "HID_F3" }, + { "input": "GLFW_KEY_F4", "output": "HID_F4" }, + { "input": "GLFW_KEY_F5", "output": "HID_F5" }, + { "input": "GLFW_KEY_F6", "output": "HID_F6" }, + { "input": "GLFW_KEY_F7", "output": "HID_F7" }, + { "input": "GLFW_KEY_F8", "output": "HID_F8" }, + { "input": "GLFW_KEY_F9", "output": "HID_F9" }, + { "input": "GLFW_KEY_F10", "output": "HID_F10" }, + { "input": "GLFW_KEY_F11", "output": "HID_F11" }, + { "input": "GLFW_KEY_F12", "output": "HID_F12" }, + { "input": "GLFW_KEY_F13", "output": "HID_F13" }, + { "input": "GLFW_KEY_F14", "output": "HID_F14" }, + { "input": "GLFW_KEY_F15", "output": "HID_F15" }, + { "input": "GLFW_KEY_F16", "output": "HID_F16" }, + { "input": "GLFW_KEY_F17", "output": "HID_F17" }, + { "input": "GLFW_KEY_F18", "output": "HID_F18" }, + { "input": "GLFW_KEY_F19", "output": "HID_F19" }, + { "input": "GLFW_KEY_F20", "output": "HID_F20" }, + { "input": "GLFW_KEY_F21", "output": "HID_F21" }, + { "input": "GLFW_KEY_F22", "output": "HID_F22" }, + { "input": "GLFW_KEY_F23", "output": "HID_F23" }, + { "input": "GLFW_KEY_F24", "output": "HID_F24" }, + { "input": "GLFW_KEY_KP_0", "output": "HID_KEYPAD_0" }, + { "input": "GLFW_KEY_KP_1", "output": "HID_KEYPAD_1" }, + { "input": "GLFW_KEY_KP_2", "output": "HID_KEYPAD_2" }, + { "input": "GLFW_KEY_KP_3", "output": "HID_KEYPAD_3" }, + { "input": "GLFW_KEY_KP_4", "output": "HID_KEYPAD_4" }, + { "input": "GLFW_KEY_KP_5", "output": "HID_KEYPAD_5" }, + { "input": "GLFW_KEY_KP_6", "output": "HID_KEYPAD_6" }, + { "input": "GLFW_KEY_KP_7", "output": "HID_KEYPAD_7" }, + { "input": "GLFW_KEY_KP_8", "output": "HID_KEYPAD_8" }, + { "input": "GLFW_KEY_KP_9", "output": "HID_KEYPAD_9" }, + { "input": "GLFW_KEY_KP_DECIMAL", "output": "HID_KEYPAD_DECIMAL" }, + { "input": "GLFW_KEY_KP_DIVIDE", "output": "HID_KEYPAD_DIVIDE" }, + { "input": "GLFW_KEY_KP_MULTIPLY", "output": "HID_KEYPAD_MULTIPLY" }, + { "input": "GLFW_KEY_KP_SUBTRACT", "output": "HID_KEYPAD_MINUS" }, + { "input": "GLFW_KEY_KP_ADD", "output": "HID_KEYPAD_PLUS" }, + { "input": "GLFW_KEY_KP_ENTER", "output": "HID_KEYPAD_ENTER" }, + { "input": "GLFW_KEY_KP_EQUAL", "output": "" } + ] +} \ No newline at end of file diff --git a/src/plugin.cpp b/src/plugin.cpp index bd74076..227dd57 100644 --- a/src/plugin.cpp +++ b/src/plugin.cpp @@ -13,7 +13,7 @@ #include "VirtualGridWidget.hpp" #include "WhiteWhaleModule.hpp" #include "WhiteWhaleWidget.hpp" -#include "screen/TeletypeKeyboard.hpp" +#include "TeletypeKeyboard.hpp" using namespace rack; diff --git a/src/teletype/screen/TeletypeKeyboard.cpp b/src/teletype/TeletypeKeyboard.cpp similarity index 91% rename from src/teletype/screen/TeletypeKeyboard.cpp rename to src/teletype/TeletypeKeyboard.cpp index c8d1905..f4d5eab 100644 --- a/src/teletype/screen/TeletypeKeyboard.cpp +++ b/src/teletype/TeletypeKeyboard.cpp @@ -77,7 +77,23 @@ void TeletypeKeyboard::loadMap() uint8_t outputCode = stringToHIDCode(std::string(json_string_value(outputJ))); if (inputCode != GLFW_KEY_UNKNOWN && outputCode != 0) { - keycodeMap.insert(std::make_pair(std::make_pair(inputCode, 0), std::make_pair(outputCode, 0))); + int inputMod = 0; + uint8_t outputMod = 0; + + json_t* inputShift = json_object_get(mapEntryJ, "input_shift"); + json_t* outputShift = json_object_get(mapEntryJ, "output_shift"); + + if (inputShift && json_boolean_value(inputShift)) + { + inputMod |= GLFW_MOD_SHIFT; + } + + if (outputShift && json_boolean_value(outputShift)) + { + outputMod |= 0x02; + } + + keycodeMap.insert(std::make_pair(std::make_pair(inputCode, inputMod), std::make_pair(outputCode, outputMod))); } } } @@ -91,11 +107,39 @@ bool TeletypeKeyboard::process(const rack::event::SelectKey& e, uint8_t* pKey, u uint8_t key = 0; uint8_t mod = 0; + bool found = false; + bool shiftConsumed = false; + + // Look for a mapping with shift explicitly set + if (e.mods & GLFW_MOD_SHIFT) + { + auto result = keycodeMap.find(std::make_pair(e.key, GLFW_MOD_SHIFT)); + if (result != keycodeMap.end()) + { + key = result->second.first; + mod = result->second.second; + found = true; + shiftConsumed = true; + } + } + + // Look for a mapping of the keycode with no modifiers + if (!found) + { + auto result = keycodeMap.find(std::make_pair(e.key, 0)); + if (result != keycodeMap.end()) + { + key = result->second.first; + mod = result->second.second; + found = true; + } + } + if (e.mods & GLFW_MOD_CONTROL) { mod |= 0x1; } - if (e.mods & GLFW_MOD_SHIFT) + if ((e.mods & GLFW_MOD_SHIFT) && !shiftConsumed) { mod |= 0x2; } @@ -108,14 +152,6 @@ bool TeletypeKeyboard::process(const rack::event::SelectKey& e, uint8_t* pKey, u mod |= 0x8; } - bool found = false; - auto result = keycodeMap.find(std::make_pair(e.key, 0)); - if (result != keycodeMap.end()) - { - key = result->second.first; - found = true; - } - if (found) { if (pKey) diff --git a/src/teletype/screen/TeletypeKeyboard.hpp b/src/teletype/TeletypeKeyboard.hpp similarity index 100% rename from src/teletype/screen/TeletypeKeyboard.hpp rename to src/teletype/TeletypeKeyboard.hpp diff --git a/src/teletype/TeletypeWidget.cpp b/src/teletype/TeletypeWidget.cpp index 693894d..4d14736 100644 --- a/src/teletype/TeletypeWidget.cpp +++ b/src/teletype/TeletypeWidget.cpp @@ -1,9 +1,9 @@ #include "TeletypeWidget.hpp" #include "SifamTPM.hpp" +#include "TeletypeKeyboard.hpp" #include "TeletypeModule.hpp" #include "USBAJack.hpp" #include "scene/TeletypeSceneIOMenu.hpp" -#include "screen/TeletypeKeyboard.hpp" #include "screen/TeletypeScreenWidget.hpp" #include