aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/treedata/common/tests.txt1
-rw-r--r--xbmc/games/controllers/ControllerTranslator.cpp577
-rw-r--r--xbmc/games/controllers/ControllerTranslator.h19
-rw-r--r--xbmc/games/controllers/input/PhysicalFeature.cpp3
-rw-r--r--xbmc/input/keyboard/CMakeLists.txt3
-rw-r--r--xbmc/input/keyboard/KeyboardSymbols.h171
-rw-r--r--xbmc/input/keyboard/KeyboardTranslator.cpp461
-rw-r--r--xbmc/input/keyboard/KeyboardTranslator.h50
-rw-r--r--xbmc/input/keyboard/test/CMakeLists.txt4
-rw-r--r--xbmc/input/keyboard/test/TestKeyboardTranslator.cpp60
-rw-r--r--xbmc/peripherals/addons/PeripheralAddonTranslator.cpp7
11 files changed, 756 insertions, 600 deletions
diff --git a/cmake/treedata/common/tests.txt b/cmake/treedata/common/tests.txt
index e0dbb96337..1a55b5c6ec 100644
--- a/cmake/treedata/common/tests.txt
+++ b/cmake/treedata/common/tests.txt
@@ -6,6 +6,7 @@ xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/test test/videoshaders
xbmc/filesystem/test test/filesystem
xbmc/games/addons/input/test test/games/addons/input
xbmc/games/controllers/input/test test/games/controllers/input
+xbmc/input/keyboard/test test/input/keyboard
xbmc/interfaces/python/test test/python
xbmc/music/tags/test test/music_tags
xbmc/network/test test/network
diff --git a/xbmc/games/controllers/ControllerTranslator.cpp b/xbmc/games/controllers/ControllerTranslator.cpp
index 08128c77bb..f46727fa3b 100644
--- a/xbmc/games/controllers/ControllerTranslator.cpp
+++ b/xbmc/games/controllers/ControllerTranslator.cpp
@@ -169,580 +169,3 @@ INPUT_TYPE CControllerTranslator::TranslateInputType(const std::string& strType)
return INPUT_TYPE::UNKNOWN;
}
-
-KEYBOARD::XBMCKey CControllerTranslator::TranslateKeysym(const std::string& symbol)
-{
- if (symbol == "backspace")
- return XBMCK_BACKSPACE;
- if (symbol == "tab")
- return XBMCK_TAB;
- if (symbol == "clear")
- return XBMCK_CLEAR;
- if (symbol == "enter")
- return XBMCK_RETURN;
- if (symbol == "pause")
- return XBMCK_PAUSE;
- if (symbol == "escape")
- return XBMCK_ESCAPE;
- if (symbol == "space")
- return XBMCK_SPACE;
- if (symbol == "exclaim")
- return XBMCK_EXCLAIM;
- if (symbol == "doublequote")
- return XBMCK_QUOTEDBL;
- if (symbol == "hash")
- return XBMCK_HASH;
- if (symbol == "dollar")
- return XBMCK_DOLLAR;
- if (symbol == "ampersand")
- return XBMCK_AMPERSAND;
- if (symbol == "quote")
- return XBMCK_QUOTE;
- if (symbol == "leftparen")
- return XBMCK_LEFTPAREN;
- if (symbol == "rightparen")
- return XBMCK_RIGHTPAREN;
- if (symbol == "asterisk")
- return XBMCK_ASTERISK;
- if (symbol == "plus")
- return XBMCK_PLUS;
- if (symbol == "comma")
- return XBMCK_COMMA;
- if (symbol == "minus")
- return XBMCK_MINUS;
- if (symbol == "period")
- return XBMCK_PERIOD;
- if (symbol == "slash")
- return XBMCK_SLASH;
- if (symbol == "0")
- return XBMCK_0;
- if (symbol == "1")
- return XBMCK_1;
- if (symbol == "2")
- return XBMCK_2;
- if (symbol == "3")
- return XBMCK_3;
- if (symbol == "4")
- return XBMCK_4;
- if (symbol == "5")
- return XBMCK_5;
- if (symbol == "6")
- return XBMCK_6;
- if (symbol == "7")
- return XBMCK_7;
- if (symbol == "8")
- return XBMCK_8;
- if (symbol == "9")
- return XBMCK_9;
- if (symbol == "colon")
- return XBMCK_COLON;
- if (symbol == "semicolon")
- return XBMCK_SEMICOLON;
- if (symbol == "less")
- return XBMCK_LESS;
- if (symbol == "equals")
- return XBMCK_EQUALS;
- if (symbol == "greater")
- return XBMCK_GREATER;
- if (symbol == "question")
- return XBMCK_QUESTION;
- if (symbol == "at")
- return XBMCK_AT;
- if (symbol == "leftbracket")
- return XBMCK_LEFTBRACKET;
- if (symbol == "backslash")
- return XBMCK_BACKSLASH;
- if (symbol == "rightbracket")
- return XBMCK_RIGHTBRACKET;
- if (symbol == "caret")
- return XBMCK_CARET;
- if (symbol == "underscore")
- return XBMCK_UNDERSCORE;
- if (symbol == "grave")
- return XBMCK_BACKQUOTE;
- if (symbol == "a")
- return XBMCK_a;
- if (symbol == "b")
- return XBMCK_b;
- if (symbol == "c")
- return XBMCK_c;
- if (symbol == "d")
- return XBMCK_d;
- if (symbol == "e")
- return XBMCK_e;
- if (symbol == "f")
- return XBMCK_f;
- if (symbol == "g")
- return XBMCK_g;
- if (symbol == "h")
- return XBMCK_h;
- if (symbol == "i")
- return XBMCK_i;
- if (symbol == "j")
- return XBMCK_j;
- if (symbol == "k")
- return XBMCK_k;
- if (symbol == "l")
- return XBMCK_l;
- if (symbol == "m")
- return XBMCK_m;
- if (symbol == "n")
- return XBMCK_n;
- if (symbol == "o")
- return XBMCK_o;
- if (symbol == "p")
- return XBMCK_p;
- if (symbol == "q")
- return XBMCK_q;
- if (symbol == "r")
- return XBMCK_r;
- if (symbol == "s")
- return XBMCK_s;
- if (symbol == "t")
- return XBMCK_t;
- if (symbol == "u")
- return XBMCK_u;
- if (symbol == "v")
- return XBMCK_v;
- if (symbol == "w")
- return XBMCK_w;
- if (symbol == "x")
- return XBMCK_x;
- if (symbol == "y")
- return XBMCK_y;
- if (symbol == "z")
- return XBMCK_z;
- if (symbol == "leftbrace")
- return XBMCK_LEFTBRACE;
- if (symbol == "bar")
- return XBMCK_PIPE;
- if (symbol == "rightbrace")
- return XBMCK_RIGHTBRACE;
- if (symbol == "tilde")
- return XBMCK_TILDE;
- if (symbol == "delete")
- return XBMCK_DELETE;
- if (symbol == "kp0")
- return XBMCK_KP0;
- if (symbol == "kp1")
- return XBMCK_KP1;
- if (symbol == "kp2")
- return XBMCK_KP2;
- if (symbol == "kp3")
- return XBMCK_KP3;
- if (symbol == "kp4")
- return XBMCK_KP4;
- if (symbol == "kp5")
- return XBMCK_KP5;
- if (symbol == "kp6")
- return XBMCK_KP6;
- if (symbol == "kp7")
- return XBMCK_KP7;
- if (symbol == "kp8")
- return XBMCK_KP8;
- if (symbol == "kp9")
- return XBMCK_KP9;
- if (symbol == "kpperiod")
- return XBMCK_KP_PERIOD;
- if (symbol == "kpdivide")
- return XBMCK_KP_DIVIDE;
- if (symbol == "kpmultiply")
- return XBMCK_KP_MULTIPLY;
- if (symbol == "kpminus")
- return XBMCK_KP_MINUS;
- if (symbol == "kpplus")
- return XBMCK_KP_PLUS;
- if (symbol == "kpenter")
- return XBMCK_KP_ENTER;
- if (symbol == "kpequals")
- return XBMCK_KP_EQUALS;
- if (symbol == "up")
- return XBMCK_UP;
- if (symbol == "down")
- return XBMCK_DOWN;
- if (symbol == "right")
- return XBMCK_RIGHT;
- if (symbol == "left")
- return XBMCK_LEFT;
- if (symbol == "insert")
- return XBMCK_INSERT;
- if (symbol == "home")
- return XBMCK_HOME;
- if (symbol == "end")
- return XBMCK_END;
- if (symbol == "pageup")
- return XBMCK_PAGEUP;
- if (symbol == "pagedown")
- return XBMCK_PAGEDOWN;
- if (symbol == "f1")
- return XBMCK_F1;
- if (symbol == "f2")
- return XBMCK_F2;
- if (symbol == "f3")
- return XBMCK_F3;
- if (symbol == "f4")
- return XBMCK_F4;
- if (symbol == "f5")
- return XBMCK_F5;
- if (symbol == "f6")
- return XBMCK_F6;
- if (symbol == "f7")
- return XBMCK_F7;
- if (symbol == "f8")
- return XBMCK_F8;
- if (symbol == "f9")
- return XBMCK_F9;
- if (symbol == "f10")
- return XBMCK_F10;
- if (symbol == "f11")
- return XBMCK_F11;
- if (symbol == "f12")
- return XBMCK_F12;
- if (symbol == "f13")
- return XBMCK_F13;
- if (symbol == "f14")
- return XBMCK_F14;
- if (symbol == "f15")
- return XBMCK_F15;
- if (symbol == "numlock")
- return XBMCK_NUMLOCK;
- if (symbol == "capslock")
- return XBMCK_CAPSLOCK;
- if (symbol == "scrolllock")
- return XBMCK_SCROLLOCK;
- if (symbol == "leftshift")
- return XBMCK_LSHIFT;
- if (symbol == "rightshift")
- return XBMCK_RSHIFT;
- if (symbol == "leftctrl")
- return XBMCK_LCTRL;
- if (symbol == "rightctrl")
- return XBMCK_RCTRL;
- if (symbol == "leftalt")
- return XBMCK_LALT;
- if (symbol == "rightalt")
- return XBMCK_RALT;
- if (symbol == "leftmeta")
- return XBMCK_LMETA;
- if (symbol == "rightmeta")
- return XBMCK_RMETA;
- if (symbol == "leftsuper")
- return XBMCK_LSUPER;
- if (symbol == "rightsuper")
- return XBMCK_RSUPER;
- if (symbol == "mode")
- return XBMCK_MODE;
- if (symbol == "compose")
- return XBMCK_COMPOSE;
- if (symbol == "help")
- return XBMCK_HELP;
- if (symbol == "printscreen")
- return XBMCK_PRINT;
- if (symbol == "sysreq")
- return XBMCK_SYSREQ;
- if (symbol == "break")
- return XBMCK_BREAK;
- if (symbol == "menu")
- return XBMCK_MENU;
- if (symbol == "power")
- return XBMCK_POWER;
- if (symbol == "euro")
- return XBMCK_EURO;
- if (symbol == "undo")
- return XBMCK_UNDO;
- if (symbol == "oem102")
- return XBMCK_OEM_102;
-
- return XBMCK_UNKNOWN;
-}
-
-const char* CControllerTranslator::TranslateKeycode(KEYBOARD::XBMCKey keycode)
-{
- switch (keycode)
- {
- case XBMCK_BACKSPACE:
- return "backspace";
- case XBMCK_TAB:
- return "tab";
- case XBMCK_CLEAR:
- return "clear";
- case XBMCK_RETURN:
- return "enter";
- case XBMCK_PAUSE:
- return "pause";
- case XBMCK_ESCAPE:
- return "escape";
- case XBMCK_SPACE:
- return "space";
- case XBMCK_EXCLAIM:
- return "exclaim";
- case XBMCK_QUOTEDBL:
- return "doublequote";
- case XBMCK_HASH:
- return "hash";
- case XBMCK_DOLLAR:
- return "dollar";
- case XBMCK_AMPERSAND:
- return "ampersand";
- case XBMCK_QUOTE:
- return "quote";
- case XBMCK_LEFTPAREN:
- return "leftparen";
- case XBMCK_RIGHTPAREN:
- return "rightparen";
- case XBMCK_ASTERISK:
- return "asterisk";
- case XBMCK_PLUS:
- return "plus";
- case XBMCK_COMMA:
- return "comma";
- case XBMCK_MINUS:
- return "minus";
- case XBMCK_PERIOD:
- return "period";
- case XBMCK_SLASH:
- return "slash";
- case XBMCK_0:
- return "0";
- case XBMCK_1:
- return "1";
- case XBMCK_2:
- return "2";
- case XBMCK_3:
- return "3";
- case XBMCK_4:
- return "4";
- case XBMCK_5:
- return "5";
- case XBMCK_6:
- return "6";
- case XBMCK_7:
- return "7";
- case XBMCK_8:
- return "8";
- case XBMCK_9:
- return "9";
- case XBMCK_COLON:
- return "colon";
- case XBMCK_SEMICOLON:
- return "semicolon";
- case XBMCK_LESS:
- return "less";
- case XBMCK_EQUALS:
- return "equals";
- case XBMCK_GREATER:
- return "greater";
- case XBMCK_QUESTION:
- return "question";
- case XBMCK_AT:
- return "at";
- case XBMCK_LEFTBRACKET:
- return "leftbracket";
- case XBMCK_BACKSLASH:
- return "backslash";
- case XBMCK_RIGHTBRACKET:
- return "rightbracket";
- case XBMCK_CARET:
- return "caret";
- case XBMCK_UNDERSCORE:
- return "underscore";
- case XBMCK_BACKQUOTE:
- return "grave";
- case XBMCK_a:
- return "a";
- case XBMCK_b:
- return "b";
- case XBMCK_c:
- return "c";
- case XBMCK_d:
- return "d";
- case XBMCK_e:
- return "e";
- case XBMCK_f:
- return "f";
- case XBMCK_g:
- return "g";
- case XBMCK_h:
- return "h";
- case XBMCK_i:
- return "i";
- case XBMCK_j:
- return "j";
- case XBMCK_k:
- return "k";
- case XBMCK_l:
- return "l";
- case XBMCK_m:
- return "m";
- case XBMCK_n:
- return "n";
- case XBMCK_o:
- return "o";
- case XBMCK_p:
- return "p";
- case XBMCK_q:
- return "q";
- case XBMCK_r:
- return "r";
- case XBMCK_s:
- return "s";
- case XBMCK_t:
- return "t";
- case XBMCK_u:
- return "u";
- case XBMCK_v:
- return "v";
- case XBMCK_w:
- return "w";
- case XBMCK_x:
- return "x";
- case XBMCK_y:
- return "y";
- case XBMCK_z:
- return "z";
- case XBMCK_LEFTBRACE:
- return "leftbrace";
- case XBMCK_PIPE:
- return "bar";
- case XBMCK_RIGHTBRACE:
- return "rightbrace";
- case XBMCK_TILDE:
- return "tilde";
- case XBMCK_DELETE:
- return "delete";
- case XBMCK_KP0:
- return "kp0";
- case XBMCK_KP1:
- return "kp1";
- case XBMCK_KP2:
- return "kp2";
- case XBMCK_KP3:
- return "kp3";
- case XBMCK_KP4:
- return "kp4";
- case XBMCK_KP5:
- return "kp5";
- case XBMCK_KP6:
- return "kp6";
- case XBMCK_KP7:
- return "kp7";
- case XBMCK_KP8:
- return "kp8";
- case XBMCK_KP9:
- return "kp9";
- case XBMCK_KP_PERIOD:
- return "kpperiod";
- case XBMCK_KP_DIVIDE:
- return "kpdivide";
- case XBMCK_KP_MULTIPLY:
- return "kpmultiply";
- case XBMCK_KP_MINUS:
- return "kpminus";
- case XBMCK_KP_PLUS:
- return "kpplus";
- case XBMCK_KP_ENTER:
- return "kpenter";
- case XBMCK_KP_EQUALS:
- return "kpequals";
- case XBMCK_UP:
- return "up";
- case XBMCK_DOWN:
- return "down";
- case XBMCK_RIGHT:
- return "right";
- case XBMCK_LEFT:
- return "left";
- case XBMCK_INSERT:
- return "insert";
- case XBMCK_HOME:
- return "home";
- case XBMCK_END:
- return "end";
- case XBMCK_PAGEUP:
- return "pageup";
- case XBMCK_PAGEDOWN:
- return "pagedown";
- case XBMCK_F1:
- return "f1";
- case XBMCK_F2:
- return "f2";
- case XBMCK_F3:
- return "f3";
- case XBMCK_F4:
- return "f4";
- case XBMCK_F5:
- return "f5";
- case XBMCK_F6:
- return "f6";
- case XBMCK_F7:
- return "f7";
- case XBMCK_F8:
- return "f8";
- case XBMCK_F9:
- return "f9";
- case XBMCK_F10:
- return "f10";
- case XBMCK_F11:
- return "f11";
- case XBMCK_F12:
- return "f12";
- case XBMCK_F13:
- return "f13";
- case XBMCK_F14:
- return "f14";
- case XBMCK_F15:
- return "f15";
- case XBMCK_NUMLOCK:
- return "numlock";
- case XBMCK_CAPSLOCK:
- return "capslock";
- case XBMCK_SCROLLOCK:
- return "scrolllock";
- case XBMCK_LSHIFT:
- return "leftshift";
- case XBMCK_RSHIFT:
- return "rightshift";
- case XBMCK_LCTRL:
- return "leftctrl";
- case XBMCK_RCTRL:
- return "rightctrl";
- case XBMCK_LALT:
- return "leftalt";
- case XBMCK_RALT:
- return "rightalt";
- case XBMCK_LMETA:
- return "leftmeta";
- case XBMCK_RMETA:
- return "rightmeta";
- case XBMCK_LSUPER:
- return "leftsuper";
- case XBMCK_RSUPER:
- return "rightsuper";
- case XBMCK_MODE:
- return "mode";
- case XBMCK_COMPOSE:
- return "compose";
- case XBMCK_HELP:
- return "help";
- case XBMCK_PRINT:
- return "printscreen";
- case XBMCK_SYSREQ:
- return "sysreq";
- case XBMCK_BREAK:
- return "break";
- case XBMCK_MENU:
- return "menu";
- case XBMCK_POWER:
- return "power";
- case XBMCK_EURO:
- return "euro";
- case XBMCK_UNDO:
- return "undo";
- case XBMCK_OEM_102:
- return "oem102";
- default:
- break;
- }
-
- return "";
-}
diff --git a/xbmc/games/controllers/ControllerTranslator.h b/xbmc/games/controllers/ControllerTranslator.h
index 4bccd24145..22cea1215b 100644
--- a/xbmc/games/controllers/ControllerTranslator.h
+++ b/xbmc/games/controllers/ControllerTranslator.h
@@ -9,7 +9,6 @@
#pragma once
#include "input/joysticks/JoystickTypes.h"
-#include "input/keyboard/KeyboardTypes.h"
#include <string>
@@ -32,24 +31,6 @@ public:
static const char* TranslateInputType(JOYSTICK::INPUT_TYPE type);
static JOYSTICK::INPUT_TYPE TranslateInputType(const std::string& strType);
-
- /*!
- * \brief Translate a keyboard symbol to a Kodi key code
- *
- * \param symbol The key's symbol, defined in the kodi-game-controllers project
- *
- * \return The layout-independent keycode associated with the key
- */
- static KEYBOARD::XBMCKey TranslateKeysym(const std::string& symbol);
-
- /*!
- * \brief Translate a Kodi key code to a keyboard symbol
- *
- * \param keycode The Kodi key code
- *
- * \return The key's symbol, or an empty string if no symbol is defined for the keycode
- */
- static const char* TranslateKeycode(KEYBOARD::XBMCKey keycode);
};
} // namespace GAME
diff --git a/xbmc/games/controllers/input/PhysicalFeature.cpp b/xbmc/games/controllers/input/PhysicalFeature.cpp
index 6dfb049cb4..9f9291d952 100644
--- a/xbmc/games/controllers/input/PhysicalFeature.cpp
+++ b/xbmc/games/controllers/input/PhysicalFeature.cpp
@@ -12,6 +12,7 @@
#include "games/controllers/ControllerDefinitions.h"
#include "games/controllers/ControllerTranslator.h"
#include "guilib/LocalizeStrings.h"
+#include "input/keyboard/KeyboardTranslator.h"
#include "utils/XMLUtils.h"
#include "utils/log.h"
@@ -147,7 +148,7 @@ bool CPhysicalFeature::Deserialize(const tinyxml2::XMLElement* pElement,
}
else
{
- m_keycode = CControllerTranslator::TranslateKeysym(strSymbol);
+ m_keycode = KEYBOARD::CKeyboardTranslator::TranslateKeysym(strSymbol);
if (m_keycode == XBMCK_UNKNOWN)
{
CLog::Log(LOGERROR, "<{}> tag - attribute \"{}\" is invalid: \"{}\"", strType,
diff --git a/xbmc/input/keyboard/CMakeLists.txt b/xbmc/input/keyboard/CMakeLists.txt
index b39b88a9ce..a95a876a0a 100644
--- a/xbmc/input/keyboard/CMakeLists.txt
+++ b/xbmc/input/keyboard/CMakeLists.txt
@@ -3,6 +3,7 @@ set(SOURCES Key.cpp
KeyboardLayout.cpp
KeyboardLayoutManager.cpp
KeyboardStat.cpp
+ KeyboardTranslator.cpp
XBMC_keytable.cpp
)
@@ -11,6 +12,8 @@ set(HEADERS Key.h
KeyboardLayout.h
KeyboardLayoutManager.h
KeyboardStat.h
+ KeyboardSymbols.h
+ KeyboardTranslator.h
KeyboardTypes.h
KeyIDs.h
XBMC_keyboard.h
diff --git a/xbmc/input/keyboard/KeyboardSymbols.h b/xbmc/input/keyboard/KeyboardSymbols.h
new file mode 100644
index 0000000000..bdb9be5759
--- /dev/null
+++ b/xbmc/input/keyboard/KeyboardSymbols.h
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2024 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+#include <string>
+
+namespace KODI
+{
+namespace KEYBOARD
+{
+
+/*!
+ * \brief Keyboard symbols are hardware-independent virtual key representations. They
+ * are used to help facilitate keyboard mapping.
+ *
+ * Symbol names are defined by the Controller Topology Project. See:
+ *
+ * https://github.com/kodi-game/controller-topology-project/blob/master/Readme-Keyboard.md
+ *
+ */
+using SymbolName = std::string;
+
+constexpr auto KEY_SYMBOL_BACKSPACE = "backspace";
+constexpr auto KEY_SYMBOL_TAB = "tab";
+constexpr auto KEY_SYMBOL_CLEAR = "clear";
+constexpr auto KEY_SYMBOL_ENTER = "enter";
+constexpr auto KEY_SYMBOL_PAUSE = "pause";
+constexpr auto KEY_SYMBOL_ESCAPE = "escape";
+constexpr auto KEY_SYMBOL_SPACE = "space";
+constexpr auto KEY_SYMBOL_EXCLAIM = "exclaim";
+constexpr auto KEY_SYMBOL_DOUBLEQUOTE = "doublequote";
+constexpr auto KEY_SYMBOL_HASH = "hash";
+constexpr auto KEY_SYMBOL_DOLLAR = "dollar";
+constexpr auto KEY_SYMBOL_AMPERSAND = "ampersand";
+constexpr auto KEY_SYMBOL_QUOTE = "quote";
+constexpr auto KEY_SYMBOL_LEFTPAREN = "leftparen";
+constexpr auto KEY_SYMBOL_RIGHTPAREN = "rightparen";
+constexpr auto KEY_SYMBOL_ASTERISK = "asterisk";
+constexpr auto KEY_SYMBOL_PLUS = "plus";
+constexpr auto KEY_SYMBOL_COMMA = "comma";
+constexpr auto KEY_SYMBOL_MINUS = "minus";
+constexpr auto KEY_SYMBOL_PERIOD = "period";
+constexpr auto KEY_SYMBOL_SLASH = "slash";
+constexpr auto KEY_SYMBOL_0 = "0";
+constexpr auto KEY_SYMBOL_1 = "1";
+constexpr auto KEY_SYMBOL_2 = "2";
+constexpr auto KEY_SYMBOL_3 = "3";
+constexpr auto KEY_SYMBOL_4 = "4";
+constexpr auto KEY_SYMBOL_5 = "5";
+constexpr auto KEY_SYMBOL_6 = "6";
+constexpr auto KEY_SYMBOL_7 = "7";
+constexpr auto KEY_SYMBOL_8 = "8";
+constexpr auto KEY_SYMBOL_9 = "9";
+constexpr auto KEY_SYMBOL_COLON = "colon";
+constexpr auto KEY_SYMBOL_SEMICOLON = "semicolon";
+constexpr auto KEY_SYMBOL_LESS = "less";
+constexpr auto KEY_SYMBOL_EQUALS = "equals";
+constexpr auto KEY_SYMBOL_GREATER = "greater";
+constexpr auto KEY_SYMBOL_QUESTION = "question";
+constexpr auto KEY_SYMBOL_AT = "at";
+constexpr auto KEY_SYMBOL_LEFTBRACKET = "leftbracket";
+constexpr auto KEY_SYMBOL_BACKSLASH = "backslash";
+constexpr auto KEY_SYMBOL_RIGHTBRACKET = "rightbracket";
+constexpr auto KEY_SYMBOL_CARET = "caret";
+constexpr auto KEY_SYMBOL_UNDERSCORE = "underscore";
+constexpr auto KEY_SYMBOL_GRAVE = "grave";
+constexpr auto KEY_SYMBOL_A = "a";
+constexpr auto KEY_SYMBOL_B = "b";
+constexpr auto KEY_SYMBOL_C = "c";
+constexpr auto KEY_SYMBOL_D = "d";
+constexpr auto KEY_SYMBOL_E = "e";
+constexpr auto KEY_SYMBOL_F = "f";
+constexpr auto KEY_SYMBOL_G = "g";
+constexpr auto KEY_SYMBOL_H = "h";
+constexpr auto KEY_SYMBOL_I = "i";
+constexpr auto KEY_SYMBOL_J = "j";
+constexpr auto KEY_SYMBOL_K = "k";
+constexpr auto KEY_SYMBOL_L = "l";
+constexpr auto KEY_SYMBOL_M = "m";
+constexpr auto KEY_SYMBOL_N = "n";
+constexpr auto KEY_SYMBOL_O = "o";
+constexpr auto KEY_SYMBOL_P = "p";
+constexpr auto KEY_SYMBOL_Q = "q";
+constexpr auto KEY_SYMBOL_R = "r";
+constexpr auto KEY_SYMBOL_S = "s";
+constexpr auto KEY_SYMBOL_T = "t";
+constexpr auto KEY_SYMBOL_U = "u";
+constexpr auto KEY_SYMBOL_V = "v";
+constexpr auto KEY_SYMBOL_W = "w";
+constexpr auto KEY_SYMBOL_X = "x";
+constexpr auto KEY_SYMBOL_Y = "y";
+constexpr auto KEY_SYMBOL_Z = "z";
+constexpr auto KEY_SYMBOL_LEFTBRACE = "leftbrace";
+constexpr auto KEY_SYMBOL_BAR = "bar";
+constexpr auto KEY_SYMBOL_RIGHTBRACE = "rightbrace";
+constexpr auto KEY_SYMBOL_TILDE = "tilde";
+constexpr auto KEY_SYMBOL_DELETE = "delete";
+constexpr auto KEY_SYMBOL_KP0 = "kp0";
+constexpr auto KEY_SYMBOL_KP1 = "kp1";
+constexpr auto KEY_SYMBOL_KP2 = "kp2";
+constexpr auto KEY_SYMBOL_KP3 = "kp3";
+constexpr auto KEY_SYMBOL_KP4 = "kp4";
+constexpr auto KEY_SYMBOL_KP5 = "kp5";
+constexpr auto KEY_SYMBOL_KP6 = "kp6";
+constexpr auto KEY_SYMBOL_KP7 = "kp7";
+constexpr auto KEY_SYMBOL_KP8 = "kp8";
+constexpr auto KEY_SYMBOL_KP9 = "kp9";
+constexpr auto KEY_SYMBOL_KPPERIOD = "kpperiod";
+constexpr auto KEY_SYMBOL_KPDIVIDE = "kpdivide";
+constexpr auto KEY_SYMBOL_KPMULTIPLY = "kpmultiply";
+constexpr auto KEY_SYMBOL_KPMINUS = "kpminus";
+constexpr auto KEY_SYMBOL_KPPLUS = "kpplus";
+constexpr auto KEY_SYMBOL_KPENTER = "kpenter";
+constexpr auto KEY_SYMBOL_KPEQUALS = "kpequals";
+constexpr auto KEY_SYMBOL_UP = "up";
+constexpr auto KEY_SYMBOL_DOWN = "down";
+constexpr auto KEY_SYMBOL_RIGHT = "right";
+constexpr auto KEY_SYMBOL_LEFT = "left";
+constexpr auto KEY_SYMBOL_INSERT = "insert";
+constexpr auto KEY_SYMBOL_HOME = "home";
+constexpr auto KEY_SYMBOL_END = "end";
+constexpr auto KEY_SYMBOL_PAGEUP = "pageup";
+constexpr auto KEY_SYMBOL_PAGEDOWN = "pagedown";
+constexpr auto KEY_SYMBOL_F1 = "f1";
+constexpr auto KEY_SYMBOL_F2 = "f2";
+constexpr auto KEY_SYMBOL_F3 = "f3";
+constexpr auto KEY_SYMBOL_F4 = "f4";
+constexpr auto KEY_SYMBOL_F5 = "f5";
+constexpr auto KEY_SYMBOL_F6 = "f6";
+constexpr auto KEY_SYMBOL_F7 = "f7";
+constexpr auto KEY_SYMBOL_F8 = "f8";
+constexpr auto KEY_SYMBOL_F9 = "f9";
+constexpr auto KEY_SYMBOL_F10 = "f10";
+constexpr auto KEY_SYMBOL_F11 = "f11";
+constexpr auto KEY_SYMBOL_F12 = "f12";
+constexpr auto KEY_SYMBOL_F13 = "f13";
+constexpr auto KEY_SYMBOL_F14 = "f14";
+constexpr auto KEY_SYMBOL_F15 = "f15";
+constexpr auto KEY_SYMBOL_NUMLOCK = "numlock";
+constexpr auto KEY_SYMBOL_CAPSLOCK = "capslock";
+constexpr auto KEY_SYMBOL_SCROLLLOCK = "scrolllock";
+constexpr auto KEY_SYMBOL_LEFTSHIFT = "leftshift";
+constexpr auto KEY_SYMBOL_RIGHTSHIFT = "rightshift";
+constexpr auto KEY_SYMBOL_LEFTCTRL = "leftctrl";
+constexpr auto KEY_SYMBOL_RIGHTCTRL = "rightctrl";
+constexpr auto KEY_SYMBOL_LEFTALT = "leftalt";
+constexpr auto KEY_SYMBOL_RIGHTALT = "rightalt";
+constexpr auto KEY_SYMBOL_LEFTMETA = "leftmeta";
+constexpr auto KEY_SYMBOL_RIGHTMETA = "rightmeta";
+constexpr auto KEY_SYMBOL_LEFTSUPER = "leftsuper";
+constexpr auto KEY_SYMBOL_RIGHTSUPER = "rightsuper";
+constexpr auto KEY_SYMBOL_MODE = "mode";
+constexpr auto KEY_SYMBOL_COMPOSE = "compose";
+constexpr auto KEY_SYMBOL_HELP = "help";
+constexpr auto KEY_SYMBOL_PRINTSCREEN = "printscreen";
+constexpr auto KEY_SYMBOL_SYSREQ = "sysreq";
+constexpr auto KEY_SYMBOL_BREAK = "break";
+constexpr auto KEY_SYMBOL_MENU = "menu";
+constexpr auto KEY_SYMBOL_POWER = "power";
+constexpr auto KEY_SYMBOL_EURO = "euro";
+constexpr auto KEY_SYMBOL_UNDO = "undo";
+constexpr auto KEY_SYMBOL_OEM102 = "oem102";
+
+} // namespace KEYBOARD
+} // namespace KODI
diff --git a/xbmc/input/keyboard/KeyboardTranslator.cpp b/xbmc/input/keyboard/KeyboardTranslator.cpp
new file mode 100644
index 0000000000..cd47da2c45
--- /dev/null
+++ b/xbmc/input/keyboard/KeyboardTranslator.cpp
@@ -0,0 +1,461 @@
+/*
+ * Copyright (C) 2024 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "KeyboardTranslator.h"
+
+#include <map>
+#include <string_view>
+
+using namespace KODI;
+using namespace KEYBOARD;
+
+namespace
+{
+static const std::map<std::string_view, XBMCKey> KeyboardSymbols = {
+ {KEY_SYMBOL_BACKSPACE, XBMCK_BACKSPACE},
+ {KEY_SYMBOL_TAB, XBMCK_TAB},
+ {KEY_SYMBOL_CLEAR, XBMCK_CLEAR},
+ {KEY_SYMBOL_ENTER, XBMCK_RETURN},
+ {KEY_SYMBOL_PAUSE, XBMCK_PAUSE},
+ {KEY_SYMBOL_ESCAPE, XBMCK_ESCAPE},
+ {KEY_SYMBOL_SPACE, XBMCK_SPACE},
+ {KEY_SYMBOL_EXCLAIM, XBMCK_EXCLAIM},
+ {KEY_SYMBOL_DOUBLEQUOTE, XBMCK_QUOTEDBL},
+ {KEY_SYMBOL_HASH, XBMCK_HASH},
+ {KEY_SYMBOL_DOLLAR, XBMCK_DOLLAR},
+ {KEY_SYMBOL_AMPERSAND, XBMCK_AMPERSAND},
+ {KEY_SYMBOL_QUOTE, XBMCK_QUOTE},
+ {KEY_SYMBOL_LEFTPAREN, XBMCK_LEFTPAREN},
+ {KEY_SYMBOL_RIGHTPAREN, XBMCK_RIGHTPAREN},
+ {KEY_SYMBOL_ASTERISK, XBMCK_ASTERISK},
+ {KEY_SYMBOL_PLUS, XBMCK_PLUS},
+ {KEY_SYMBOL_COMMA, XBMCK_COMMA},
+ {KEY_SYMBOL_MINUS, XBMCK_MINUS},
+ {KEY_SYMBOL_PERIOD, XBMCK_PERIOD},
+ {KEY_SYMBOL_SLASH, XBMCK_SLASH},
+ {KEY_SYMBOL_0, XBMCK_0},
+ {KEY_SYMBOL_1, XBMCK_1},
+ {KEY_SYMBOL_2, XBMCK_2},
+ {KEY_SYMBOL_3, XBMCK_3},
+ {KEY_SYMBOL_4, XBMCK_4},
+ {KEY_SYMBOL_5, XBMCK_5},
+ {KEY_SYMBOL_6, XBMCK_6},
+ {KEY_SYMBOL_7, XBMCK_7},
+ {KEY_SYMBOL_8, XBMCK_8},
+ {KEY_SYMBOL_9, XBMCK_9},
+ {KEY_SYMBOL_COLON, XBMCK_COLON},
+ {KEY_SYMBOL_SEMICOLON, XBMCK_SEMICOLON},
+ {KEY_SYMBOL_LESS, XBMCK_LESS},
+ {KEY_SYMBOL_EQUALS, XBMCK_EQUALS},
+ {KEY_SYMBOL_GREATER, XBMCK_GREATER},
+ {KEY_SYMBOL_QUESTION, XBMCK_QUESTION},
+ {KEY_SYMBOL_AT, XBMCK_AT},
+ {KEY_SYMBOL_LEFTBRACKET, XBMCK_LEFTBRACKET},
+ {KEY_SYMBOL_BACKSLASH, XBMCK_BACKSLASH},
+ {KEY_SYMBOL_RIGHTBRACKET, XBMCK_RIGHTBRACKET},
+ {KEY_SYMBOL_CARET, XBMCK_CARET},
+ {KEY_SYMBOL_UNDERSCORE, XBMCK_UNDERSCORE},
+ {KEY_SYMBOL_GRAVE, XBMCK_BACKQUOTE},
+ {KEY_SYMBOL_A, XBMCK_a},
+ {KEY_SYMBOL_B, XBMCK_b},
+ {KEY_SYMBOL_C, XBMCK_c},
+ {KEY_SYMBOL_D, XBMCK_d},
+ {KEY_SYMBOL_E, XBMCK_e},
+ {KEY_SYMBOL_F, XBMCK_f},
+ {KEY_SYMBOL_G, XBMCK_g},
+ {KEY_SYMBOL_H, XBMCK_h},
+ {KEY_SYMBOL_I, XBMCK_i},
+ {KEY_SYMBOL_J, XBMCK_j},
+ {KEY_SYMBOL_K, XBMCK_k},
+ {KEY_SYMBOL_L, XBMCK_l},
+ {KEY_SYMBOL_M, XBMCK_m},
+ {KEY_SYMBOL_N, XBMCK_n},
+ {KEY_SYMBOL_O, XBMCK_o},
+ {KEY_SYMBOL_P, XBMCK_p},
+ {KEY_SYMBOL_Q, XBMCK_q},
+ {KEY_SYMBOL_R, XBMCK_r},
+ {KEY_SYMBOL_S, XBMCK_s},
+ {KEY_SYMBOL_T, XBMCK_t},
+ {KEY_SYMBOL_U, XBMCK_u},
+ {KEY_SYMBOL_V, XBMCK_v},
+ {KEY_SYMBOL_W, XBMCK_w},
+ {KEY_SYMBOL_X, XBMCK_x},
+ {KEY_SYMBOL_Y, XBMCK_y},
+ {KEY_SYMBOL_Z, XBMCK_z},
+ {KEY_SYMBOL_LEFTBRACE, XBMCK_LEFTBRACE},
+ {KEY_SYMBOL_BAR, XBMCK_PIPE},
+ {KEY_SYMBOL_RIGHTBRACE, XBMCK_RIGHTBRACE},
+ {KEY_SYMBOL_TILDE, XBMCK_TILDE},
+ {KEY_SYMBOL_DELETE, XBMCK_DELETE},
+ {KEY_SYMBOL_KP0, XBMCK_KP0},
+ {KEY_SYMBOL_KP1, XBMCK_KP1},
+ {KEY_SYMBOL_KP2, XBMCK_KP2},
+ {KEY_SYMBOL_KP3, XBMCK_KP3},
+ {KEY_SYMBOL_KP4, XBMCK_KP4},
+ {KEY_SYMBOL_KP5, XBMCK_KP5},
+ {KEY_SYMBOL_KP6, XBMCK_KP6},
+ {KEY_SYMBOL_KP7, XBMCK_KP7},
+ {KEY_SYMBOL_KP8, XBMCK_KP8},
+ {KEY_SYMBOL_KP9, XBMCK_KP9},
+ {KEY_SYMBOL_KPPERIOD, XBMCK_KP_PERIOD},
+ {KEY_SYMBOL_KPDIVIDE, XBMCK_KP_DIVIDE},
+ {KEY_SYMBOL_KPMULTIPLY, XBMCK_KP_MULTIPLY},
+ {KEY_SYMBOL_KPMINUS, XBMCK_KP_MINUS},
+ {KEY_SYMBOL_KPPLUS, XBMCK_KP_PLUS},
+ {KEY_SYMBOL_KPENTER, XBMCK_KP_ENTER},
+ {KEY_SYMBOL_KPEQUALS, XBMCK_KP_EQUALS},
+ {KEY_SYMBOL_UP, XBMCK_UP},
+ {KEY_SYMBOL_DOWN, XBMCK_DOWN},
+ {KEY_SYMBOL_RIGHT, XBMCK_RIGHT},
+ {KEY_SYMBOL_LEFT, XBMCK_LEFT},
+ {KEY_SYMBOL_INSERT, XBMCK_INSERT},
+ {KEY_SYMBOL_HOME, XBMCK_HOME},
+ {KEY_SYMBOL_END, XBMCK_END},
+ {KEY_SYMBOL_PAGEUP, XBMCK_PAGEUP},
+ {KEY_SYMBOL_PAGEDOWN, XBMCK_PAGEDOWN},
+ {KEY_SYMBOL_F1, XBMCK_F1},
+ {KEY_SYMBOL_F2, XBMCK_F2},
+ {KEY_SYMBOL_F3, XBMCK_F3},
+ {KEY_SYMBOL_F4, XBMCK_F4},
+ {KEY_SYMBOL_F5, XBMCK_F5},
+ {KEY_SYMBOL_F6, XBMCK_F6},
+ {KEY_SYMBOL_F7, XBMCK_F7},
+ {KEY_SYMBOL_F8, XBMCK_F8},
+ {KEY_SYMBOL_F9, XBMCK_F9},
+ {KEY_SYMBOL_F10, XBMCK_F10},
+ {KEY_SYMBOL_F11, XBMCK_F11},
+ {KEY_SYMBOL_F12, XBMCK_F12},
+ {KEY_SYMBOL_F13, XBMCK_F13},
+ {KEY_SYMBOL_F14, XBMCK_F14},
+ {KEY_SYMBOL_F15, XBMCK_F15},
+ {KEY_SYMBOL_NUMLOCK, XBMCK_NUMLOCK},
+ {KEY_SYMBOL_CAPSLOCK, XBMCK_CAPSLOCK},
+ {KEY_SYMBOL_SCROLLLOCK, XBMCK_SCROLLOCK},
+ {KEY_SYMBOL_LEFTSHIFT, XBMCK_LSHIFT},
+ {KEY_SYMBOL_RIGHTSHIFT, XBMCK_RSHIFT},
+ {KEY_SYMBOL_LEFTCTRL, XBMCK_LCTRL},
+ {KEY_SYMBOL_RIGHTCTRL, XBMCK_RCTRL},
+ {KEY_SYMBOL_LEFTALT, XBMCK_LALT},
+ {KEY_SYMBOL_RIGHTALT, XBMCK_RALT},
+ {KEY_SYMBOL_LEFTMETA, XBMCK_LMETA},
+ {KEY_SYMBOL_RIGHTMETA, XBMCK_RMETA},
+ {KEY_SYMBOL_LEFTSUPER, XBMCK_LSUPER},
+ {KEY_SYMBOL_RIGHTSUPER, XBMCK_RSUPER},
+ {KEY_SYMBOL_MODE, XBMCK_MODE},
+ {KEY_SYMBOL_COMPOSE, XBMCK_COMPOSE},
+ {KEY_SYMBOL_HELP, XBMCK_HELP},
+ {KEY_SYMBOL_PRINTSCREEN, XBMCK_PRINT},
+ {KEY_SYMBOL_SYSREQ, XBMCK_SYSREQ},
+ {KEY_SYMBOL_BREAK, XBMCK_BREAK},
+ {KEY_SYMBOL_MENU, XBMCK_MENU},
+ {KEY_SYMBOL_POWER, XBMCK_POWER},
+ {KEY_SYMBOL_EURO, XBMCK_EURO},
+ {KEY_SYMBOL_UNDO, XBMCK_UNDO},
+ {KEY_SYMBOL_OEM102, XBMCK_OEM_102},
+};
+} // namespace
+
+XBMCKey CKeyboardTranslator::TranslateKeysym(const SymbolName& symbolName)
+{
+ const auto it = KeyboardSymbols.find(symbolName);
+ if (it != KeyboardSymbols.end())
+ return it->second;
+
+ return XBMCK_UNKNOWN;
+}
+
+const char* CKeyboardTranslator::TranslateKeycode(XBMCKey keycode)
+{
+ switch (keycode)
+ {
+ case XBMCK_BACKSPACE:
+ return KEY_SYMBOL_BACKSPACE;
+ case XBMCK_TAB:
+ return KEY_SYMBOL_TAB;
+ case XBMCK_CLEAR:
+ return KEY_SYMBOL_CLEAR;
+ case XBMCK_RETURN:
+ return KEY_SYMBOL_ENTER;
+ case XBMCK_PAUSE:
+ return KEY_SYMBOL_PAUSE;
+ case XBMCK_ESCAPE:
+ return KEY_SYMBOL_ESCAPE;
+ case XBMCK_SPACE:
+ return KEY_SYMBOL_SPACE;
+ case XBMCK_EXCLAIM:
+ return KEY_SYMBOL_EXCLAIM;
+ case XBMCK_QUOTEDBL:
+ return KEY_SYMBOL_DOUBLEQUOTE;
+ case XBMCK_HASH:
+ return KEY_SYMBOL_HASH;
+ case XBMCK_DOLLAR:
+ return KEY_SYMBOL_DOLLAR;
+ case XBMCK_AMPERSAND:
+ return KEY_SYMBOL_AMPERSAND;
+ case XBMCK_QUOTE:
+ return KEY_SYMBOL_QUOTE;
+ case XBMCK_LEFTPAREN:
+ return KEY_SYMBOL_LEFTPAREN;
+ case XBMCK_RIGHTPAREN:
+ return KEY_SYMBOL_RIGHTPAREN;
+ case XBMCK_ASTERISK:
+ return KEY_SYMBOL_ASTERISK;
+ case XBMCK_PLUS:
+ return KEY_SYMBOL_PLUS;
+ case XBMCK_COMMA:
+ return KEY_SYMBOL_COMMA;
+ case XBMCK_MINUS:
+ return KEY_SYMBOL_MINUS;
+ case XBMCK_PERIOD:
+ return KEY_SYMBOL_PERIOD;
+ case XBMCK_SLASH:
+ return KEY_SYMBOL_SLASH;
+ case XBMCK_0:
+ return KEY_SYMBOL_0;
+ case XBMCK_1:
+ return KEY_SYMBOL_1;
+ case XBMCK_2:
+ return KEY_SYMBOL_2;
+ case XBMCK_3:
+ return KEY_SYMBOL_3;
+ case XBMCK_4:
+ return KEY_SYMBOL_4;
+ case XBMCK_5:
+ return KEY_SYMBOL_5;
+ case XBMCK_6:
+ return KEY_SYMBOL_6;
+ case XBMCK_7:
+ return KEY_SYMBOL_7;
+ case XBMCK_8:
+ return KEY_SYMBOL_8;
+ case XBMCK_9:
+ return KEY_SYMBOL_9;
+ case XBMCK_COLON:
+ return KEY_SYMBOL_COLON;
+ case XBMCK_SEMICOLON:
+ return KEY_SYMBOL_SEMICOLON;
+ case XBMCK_LESS:
+ return KEY_SYMBOL_LESS;
+ case XBMCK_EQUALS:
+ return KEY_SYMBOL_EQUALS;
+ case XBMCK_GREATER:
+ return KEY_SYMBOL_GREATER;
+ case XBMCK_QUESTION:
+ return KEY_SYMBOL_QUESTION;
+ case XBMCK_AT:
+ return KEY_SYMBOL_AT;
+ case XBMCK_LEFTBRACKET:
+ return KEY_SYMBOL_LEFTBRACKET;
+ case XBMCK_BACKSLASH:
+ return KEY_SYMBOL_BACKSLASH;
+ case XBMCK_RIGHTBRACKET:
+ return KEY_SYMBOL_RIGHTBRACKET;
+ case XBMCK_CARET:
+ return KEY_SYMBOL_CARET;
+ case XBMCK_UNDERSCORE:
+ return KEY_SYMBOL_UNDERSCORE;
+ case XBMCK_BACKQUOTE:
+ return KEY_SYMBOL_GRAVE;
+ case XBMCK_a:
+ return KEY_SYMBOL_A;
+ case XBMCK_b:
+ return KEY_SYMBOL_B;
+ case XBMCK_c:
+ return KEY_SYMBOL_C;
+ case XBMCK_d:
+ return KEY_SYMBOL_D;
+ case XBMCK_e:
+ return KEY_SYMBOL_E;
+ case XBMCK_f:
+ return KEY_SYMBOL_F;
+ case XBMCK_g:
+ return KEY_SYMBOL_G;
+ case XBMCK_h:
+ return KEY_SYMBOL_H;
+ case XBMCK_i:
+ return KEY_SYMBOL_I;
+ case XBMCK_j:
+ return KEY_SYMBOL_J;
+ case XBMCK_k:
+ return KEY_SYMBOL_K;
+ case XBMCK_l:
+ return KEY_SYMBOL_L;
+ case XBMCK_m:
+ return KEY_SYMBOL_M;
+ case XBMCK_n:
+ return KEY_SYMBOL_N;
+ case XBMCK_o:
+ return KEY_SYMBOL_O;
+ case XBMCK_p:
+ return KEY_SYMBOL_P;
+ case XBMCK_q:
+ return KEY_SYMBOL_Q;
+ case XBMCK_r:
+ return KEY_SYMBOL_R;
+ case XBMCK_s:
+ return KEY_SYMBOL_S;
+ case XBMCK_t:
+ return KEY_SYMBOL_T;
+ case XBMCK_u:
+ return KEY_SYMBOL_U;
+ case XBMCK_v:
+ return KEY_SYMBOL_V;
+ case XBMCK_w:
+ return KEY_SYMBOL_W;
+ case XBMCK_x:
+ return KEY_SYMBOL_X;
+ case XBMCK_y:
+ return KEY_SYMBOL_Y;
+ case XBMCK_z:
+ return KEY_SYMBOL_Z;
+ case XBMCK_LEFTBRACE:
+ return KEY_SYMBOL_LEFTBRACE;
+ case XBMCK_PIPE:
+ return KEY_SYMBOL_BAR;
+ case XBMCK_RIGHTBRACE:
+ return KEY_SYMBOL_RIGHTBRACE;
+ case XBMCK_TILDE:
+ return KEY_SYMBOL_TILDE;
+ case XBMCK_DELETE:
+ return KEY_SYMBOL_DELETE;
+ case XBMCK_KP0:
+ return KEY_SYMBOL_KP0;
+ case XBMCK_KP1:
+ return KEY_SYMBOL_KP1;
+ case XBMCK_KP2:
+ return KEY_SYMBOL_KP2;
+ case XBMCK_KP3:
+ return KEY_SYMBOL_KP3;
+ case XBMCK_KP4:
+ return KEY_SYMBOL_KP4;
+ case XBMCK_KP5:
+ return KEY_SYMBOL_KP5;
+ case XBMCK_KP6:
+ return KEY_SYMBOL_KP6;
+ case XBMCK_KP7:
+ return KEY_SYMBOL_KP7;
+ case XBMCK_KP8:
+ return KEY_SYMBOL_KP8;
+ case XBMCK_KP9:
+ return KEY_SYMBOL_KP9;
+ case XBMCK_KP_PERIOD:
+ return KEY_SYMBOL_KPPERIOD;
+ case XBMCK_KP_DIVIDE:
+ return KEY_SYMBOL_KPDIVIDE;
+ case XBMCK_KP_MULTIPLY:
+ return KEY_SYMBOL_KPMULTIPLY;
+ case XBMCK_KP_MINUS:
+ return KEY_SYMBOL_KPMINUS;
+ case XBMCK_KP_PLUS:
+ return KEY_SYMBOL_KPPLUS;
+ case XBMCK_KP_ENTER:
+ return KEY_SYMBOL_KPENTER;
+ case XBMCK_KP_EQUALS:
+ return KEY_SYMBOL_KPEQUALS;
+ case XBMCK_UP:
+ return KEY_SYMBOL_UP;
+ case XBMCK_DOWN:
+ return KEY_SYMBOL_DOWN;
+ case XBMCK_RIGHT:
+ return KEY_SYMBOL_RIGHT;
+ case XBMCK_LEFT:
+ return KEY_SYMBOL_LEFT;
+ case XBMCK_INSERT:
+ return KEY_SYMBOL_INSERT;
+ case XBMCK_HOME:
+ return KEY_SYMBOL_HOME;
+ case XBMCK_END:
+ return KEY_SYMBOL_END;
+ case XBMCK_PAGEUP:
+ return KEY_SYMBOL_PAGEUP;
+ case XBMCK_PAGEDOWN:
+ return KEY_SYMBOL_PAGEDOWN;
+ case XBMCK_F1:
+ return KEY_SYMBOL_F1;
+ case XBMCK_F2:
+ return KEY_SYMBOL_F2;
+ case XBMCK_F3:
+ return KEY_SYMBOL_F3;
+ case XBMCK_F4:
+ return KEY_SYMBOL_F4;
+ case XBMCK_F5:
+ return KEY_SYMBOL_F5;
+ case XBMCK_F6:
+ return KEY_SYMBOL_F6;
+ case XBMCK_F7:
+ return KEY_SYMBOL_F7;
+ case XBMCK_F8:
+ return KEY_SYMBOL_F8;
+ case XBMCK_F9:
+ return KEY_SYMBOL_F9;
+ case XBMCK_F10:
+ return KEY_SYMBOL_F10;
+ case XBMCK_F11:
+ return KEY_SYMBOL_F11;
+ case XBMCK_F12:
+ return KEY_SYMBOL_F12;
+ case XBMCK_F13:
+ return KEY_SYMBOL_F13;
+ case XBMCK_F14:
+ return KEY_SYMBOL_F14;
+ case XBMCK_F15:
+ return KEY_SYMBOL_F15;
+ case XBMCK_NUMLOCK:
+ return KEY_SYMBOL_NUMLOCK;
+ case XBMCK_CAPSLOCK:
+ return KEY_SYMBOL_CAPSLOCK;
+ case XBMCK_SCROLLOCK:
+ return KEY_SYMBOL_SCROLLLOCK;
+ case XBMCK_LSHIFT:
+ return KEY_SYMBOL_LEFTSHIFT;
+ case XBMCK_RSHIFT:
+ return KEY_SYMBOL_RIGHTSHIFT;
+ case XBMCK_LCTRL:
+ return KEY_SYMBOL_LEFTCTRL;
+ case XBMCK_RCTRL:
+ return KEY_SYMBOL_RIGHTCTRL;
+ case XBMCK_LALT:
+ return KEY_SYMBOL_LEFTALT;
+ case XBMCK_RALT:
+ return KEY_SYMBOL_RIGHTALT;
+ case XBMCK_LMETA:
+ return KEY_SYMBOL_LEFTMETA;
+ case XBMCK_RMETA:
+ return KEY_SYMBOL_RIGHTMETA;
+ case XBMCK_LSUPER:
+ return KEY_SYMBOL_LEFTSUPER;
+ case XBMCK_RSUPER:
+ return KEY_SYMBOL_RIGHTSUPER;
+ case XBMCK_MODE:
+ return KEY_SYMBOL_MODE;
+ case XBMCK_COMPOSE:
+ return KEY_SYMBOL_COMPOSE;
+ case XBMCK_HELP:
+ return KEY_SYMBOL_HELP;
+ case XBMCK_PRINT:
+ return KEY_SYMBOL_PRINTSCREEN;
+ case XBMCK_SYSREQ:
+ return KEY_SYMBOL_SYSREQ;
+ case XBMCK_BREAK:
+ return KEY_SYMBOL_BREAK;
+ case XBMCK_MENU:
+ return KEY_SYMBOL_MENU;
+ case XBMCK_POWER:
+ return KEY_SYMBOL_POWER;
+ case XBMCK_EURO:
+ return KEY_SYMBOL_EURO;
+ case XBMCK_UNDO:
+ return KEY_SYMBOL_UNDO;
+ case XBMCK_OEM_102:
+ return KEY_SYMBOL_OEM102;
+ default:
+ break;
+ }
+
+ return "";
+}
diff --git a/xbmc/input/keyboard/KeyboardTranslator.h b/xbmc/input/keyboard/KeyboardTranslator.h
new file mode 100644
index 0000000000..295308ffaa
--- /dev/null
+++ b/xbmc/input/keyboard/KeyboardTranslator.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2024 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+#include "KeyboardSymbols.h"
+#include "KeyboardTypes.h"
+#include "XBMC_keysym.h"
+
+namespace KODI
+{
+namespace KEYBOARD
+{
+
+/*!
+ * \brief Keyboard translation utilities
+ */
+class CKeyboardTranslator
+{
+public:
+ /*!
+ * \brief Translate a keyboard symbol to a Kodi key code
+ *
+ * Keyboard symbols are hardware-independent virtual key representations.
+ * They are used to help facilitate keyboard mapping.
+ *
+ * \param symbol The key's symbol, defined in the Controller Topology Project:
+ * https://github.com/kodi-game/controller-topology-project/blob/master/Readme-Keyboard.md
+ *
+ * \return The layout-independent keycode associated with the key
+ */
+ static XBMCKey TranslateKeysym(const SymbolName& symbolName);
+
+ /*!
+ * \brief Translate a Kodi key code to a keyboard symbol
+ *
+ * \param keycode The Kodi key code
+ *
+ * \return The key's symbol, or an empty string if no symbol is defined for the keycode
+ */
+ static const char* TranslateKeycode(XBMCKey keycode);
+};
+
+} // namespace KEYBOARD
+} // namespace KODI
diff --git a/xbmc/input/keyboard/test/CMakeLists.txt b/xbmc/input/keyboard/test/CMakeLists.txt
new file mode 100644
index 0000000000..82f20db085
--- /dev/null
+++ b/xbmc/input/keyboard/test/CMakeLists.txt
@@ -0,0 +1,4 @@
+set(SOURCES TestKeyboardTranslator.cpp
+)
+
+core_add_test_library(test_input_keyboard)
diff --git a/xbmc/input/keyboard/test/TestKeyboardTranslator.cpp b/xbmc/input/keyboard/test/TestKeyboardTranslator.cpp
new file mode 100644
index 0000000000..5e6e891aeb
--- /dev/null
+++ b/xbmc/input/keyboard/test/TestKeyboardTranslator.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2024 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "ServiceBroker.h"
+#include "addons/AddonManager.h"
+#include "addons/addoninfo/AddonType.h"
+#include "games/controllers/Controller.h"
+#include "games/controllers/ControllerIDs.h"
+#include "games/controllers/input/PhysicalFeature.h"
+#include "input/keyboard/KeyboardTranslator.h"
+
+#include <gtest/gtest.h>
+
+using namespace KODI;
+using namespace KEYBOARD;
+
+TEST(TestKeyboardTranslator, TranslateKeys)
+{
+ ADDON::CAddonMgr& addonManager = CServiceBroker::GetAddonMgr();
+
+ // Load add-on info
+ ADDON::AddonPtr addon;
+ EXPECT_TRUE(addonManager.GetAddon(DEFAULT_KEYBOARD_ID, addon, ADDON::AddonType::GAME_CONTROLLER,
+ ADDON::OnlyEnabled::CHOICE_YES));
+
+ // Convert to game controller
+ GAME::ControllerPtr controller = std::static_pointer_cast<GAME::CController>(addon);
+ ASSERT_NE(controller.get(), nullptr);
+ EXPECT_EQ(controller->ID(), DEFAULT_KEYBOARD_ID);
+
+ // Load controller profile
+ EXPECT_TRUE(controller->LoadLayout());
+ EXPECT_EQ(controller->Features().size(), 140);
+
+ //
+ // Spec: Should translate all keyboard symbols
+ //
+ unsigned int count = 0;
+
+ for (const GAME::CPhysicalFeature& feature : controller->Features())
+ {
+ const KEYBOARD::XBMCKey keycode = feature.Keycode();
+ EXPECT_NE(keycode, KEYBOARD::XBMCKey::XBMCK_UNKNOWN);
+
+ const char* symbolName = CKeyboardTranslator::TranslateKeycode(keycode);
+ EXPECT_STRNE(symbolName, "");
+
+ const KEYBOARD::XBMCKey keycode2 = CKeyboardTranslator::TranslateKeysym(symbolName);
+ EXPECT_EQ(keycode, keycode2);
+
+ ++count;
+ }
+
+ EXPECT_EQ(count, 140);
+}
diff --git a/xbmc/peripherals/addons/PeripheralAddonTranslator.cpp b/xbmc/peripherals/addons/PeripheralAddonTranslator.cpp
index 81554050af..965fecc9df 100644
--- a/xbmc/peripherals/addons/PeripheralAddonTranslator.cpp
+++ b/xbmc/peripherals/addons/PeripheralAddonTranslator.cpp
@@ -8,8 +8,8 @@
#include "PeripheralAddonTranslator.h"
-#include "games/controllers/ControllerTranslator.h"
#include "input/joysticks/JoystickUtils.h"
+#include "input/keyboard/KeyboardTranslator.h"
#include <algorithm>
#include <iterator>
@@ -113,7 +113,8 @@ CDriverPrimitive CPeripheralAddonTranslator::TranslatePrimitive(
}
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_KEY:
{
- KEYBOARD::XBMCKey keycode = GAME::CControllerTranslator::TranslateKeysym(primitive.Keycode());
+ KEYBOARD::XBMCKey keycode =
+ KEYBOARD::CKeyboardTranslator::TranslateKeysym(primitive.Keycode());
retVal = CDriverPrimitive(keycode);
break;
}
@@ -166,7 +167,7 @@ kodi::addon::DriverPrimitive CPeripheralAddonTranslator::TranslatePrimitive(
}
case PRIMITIVE_TYPE::KEY:
{
- std::string keysym = GAME::CControllerTranslator::TranslateKeycode(primitive.Keycode());
+ std::string keysym = KEYBOARD::CKeyboardTranslator::TranslateKeycode(primitive.Keycode());
retVal = kodi::addon::DriverPrimitive(keysym);
break;
}