diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
commit | c04dcc2e7d834218ef2d4194331e383402495ae1 (patch) | |
tree | 7333e38d10d75386e60f336b80c2443c1166031d /xbmc/input/KeyboardStat.cpp | |
parent | Initial commit. (diff) | |
download | kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.tar.xz kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.zip |
Adding upstream version 2:20.4+dfsg.upstream/2%20.4+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'xbmc/input/KeyboardStat.cpp')
-rw-r--r-- | xbmc/input/KeyboardStat.cpp | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/xbmc/input/KeyboardStat.cpp b/xbmc/input/KeyboardStat.cpp new file mode 100644 index 0000000..ac36fe4 --- /dev/null +++ b/xbmc/input/KeyboardStat.cpp @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2007-2018 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. + */ + +// C++ Implementation: CKeyboard + +// Comment OUT, if not really debugging!!!: +//#define DEBUG_KEYBOARD_GETCHAR + +#include "KeyboardStat.h" + +#include "ServiceBroker.h" +#include "input/InputTypes.h" +#include "input/XBMC_keytable.h" +#include "input/XBMC_vkeys.h" +#include "peripherals/Peripherals.h" +#include "peripherals/devices/PeripheralHID.h" +#include "utils/log.h" +#include "windowing/XBMC_events.h" + +using namespace KODI; +using namespace INPUT; + +bool operator==(const XBMC_keysym& lhs, const XBMC_keysym& rhs) +{ + return lhs.mod == rhs.mod && lhs.scancode == rhs.scancode && lhs.sym == rhs.sym && + lhs.unicode == rhs.unicode; +} + +CKeyboardStat::CKeyboardStat() +{ + memset(&m_lastKeysym, 0, sizeof(m_lastKeysym)); + m_lastKeyTime = {}; +} + +void CKeyboardStat::Initialize() +{ +} + +bool CKeyboardStat::LookupSymAndUnicodePeripherals(XBMC_keysym& keysym, uint8_t* key, char* unicode) +{ + using namespace PERIPHERALS; + + PeripheralVector hidDevices; + if (CServiceBroker::GetPeripherals().GetPeripheralsWithFeature(hidDevices, FEATURE_HID)) + { + for (auto& peripheral : hidDevices) + { + std::shared_ptr<CPeripheralHID> hidDevice = + std::static_pointer_cast<CPeripheralHID>(peripheral); + if (hidDevice->LookupSymAndUnicode(keysym, key, unicode)) + return true; + } + } + return false; +} + +CKey CKeyboardStat::TranslateKey(XBMC_keysym& keysym) const +{ + uint32_t keycode; + uint8_t vkey; + wchar_t unicode; + char ascii; + uint32_t modifiers; + uint32_t lockingModifiers; + std::chrono::milliseconds held; + XBMCKEYTABLE keytable; + + modifiers = 0; + if (keysym.mod & XBMCKMOD_CTRL) + modifiers |= CKey::MODIFIER_CTRL; + if (keysym.mod & XBMCKMOD_SHIFT) + modifiers |= CKey::MODIFIER_SHIFT; + if (keysym.mod & XBMCKMOD_ALT) + modifiers |= CKey::MODIFIER_ALT; + if (keysym.mod & XBMCKMOD_SUPER) + modifiers |= CKey::MODIFIER_SUPER; + if (keysym.mod & XBMCKMOD_META) + modifiers |= CKey::MODIFIER_META; + + lockingModifiers = 0; + if (keysym.mod & XBMCKMOD_NUM) + lockingModifiers |= CKey::MODIFIER_NUMLOCK; + if (keysym.mod & XBMCKMOD_CAPS) + lockingModifiers |= CKey::MODIFIER_CAPSLOCK; + if (keysym.mod & XBMCKMOD_MODE) + lockingModifiers |= CKey::MODIFIER_SCROLLLOCK; + + CLog::Log(LOGDEBUG, + "Keyboard: scancode: {:#02x}, sym: {:#04x}, unicode: {:#04x}, modifier: 0x{:x}", + keysym.scancode, keysym.sym, keysym.unicode, keysym.mod); + + // The keysym.unicode is usually valid, even if it is zero. A zero + // unicode just means this is a non-printing keypress. The ascii and + // vkey will be set below. + keycode = keysym.sym; + unicode = keysym.unicode; + ascii = 0; + vkey = 0; + held = std::chrono::milliseconds(0); + + // Start by check whether any of the HID peripherals wants to translate this keypress + if (LookupSymAndUnicodePeripherals(keysym, &vkey, &ascii)) + { + CLog::Log(LOGDEBUG, "{} - keypress translated by a HID peripheral", __FUNCTION__); + } + + // Continue by trying to match both the sym and unicode. This will identify + // the majority of keypresses + else if (KeyTableLookupSymAndUnicode(keysym.sym, keysym.unicode, &keytable)) + { + vkey = keytable.vkey; + ascii = keytable.ascii; + } + + // If we failed to match the sym and unicode try just the unicode. This + // will match keys like \ that are on different keys on regional keyboards. + else if (KeyTableLookupUnicode(keysym.unicode, &keytable)) + { + if (keycode == 0) + keycode = keytable.sym; + vkey = keytable.vkey; + ascii = keytable.ascii; + } + + // If there is still no match try the sym + else if (KeyTableLookupSym(keysym.sym, &keytable)) + { + vkey = keytable.vkey; + + // Occasionally we get non-printing keys that have a non-zero value in + // the keysym.unicode. Check for this here and replace any rogue unicode + // values. + if (keytable.unicode == 0 && unicode != 0) + unicode = 0; + else if (keysym.unicode > 32 && keysym.unicode < 128) + ascii = unicode & 0x7f; + } + + // The keysym.sym is unknown ... + else + { + if (!vkey && !ascii) + { + if (keysym.mod & XBMCKMOD_LSHIFT) + vkey = 0xa0; + else if (keysym.mod & XBMCKMOD_RSHIFT) + vkey = 0xa1; + else if (keysym.mod & XBMCKMOD_LALT) + vkey = 0xa4; + else if (keysym.mod & XBMCKMOD_RALT) + vkey = 0xa5; + else if (keysym.mod & XBMCKMOD_LCTRL) + vkey = 0xa2; + else if (keysym.mod & XBMCKMOD_RCTRL) + vkey = 0xa3; + else if (keysym.unicode > 32 && keysym.unicode < 128) + // only TRUE ASCII! (Otherwise XBMC crashes! No unicode not even latin 1!) + ascii = (char)(keysym.unicode & 0xff); + } + } + + if (keysym == m_lastKeysym) + { + auto now = std::chrono::steady_clock::now(); + + held = std::chrono::duration_cast<std::chrono::milliseconds>(now - m_lastKeyTime); + if (held.count() > HOLD_TRESHOLD) + modifiers |= CKey::MODIFIER_LONG; + } + + // For all shift-X keys except shift-A to shift-Z and shift-F1 to shift-F24 the + // shift modifier is ignored. This so that, for example, the * keypress (shift-8) + // is seen as <asterisk> not <asterisk mod="shift">. + // The A-Z keys are exempted because shift-A-Z is used for navigation in lists. + // The function keys are exempted because function keys have no shifted value and + // the Nyxboard remote uses keys like Shift-F3 for some buttons. + if (modifiers == CKey::MODIFIER_SHIFT) + if ((unicode < 'A' || unicode > 'Z') && (unicode < 'a' || unicode > 'z') && + (vkey < XBMCVK_F1 || vkey > XBMCVK_F24)) + modifiers = 0; + + // Create and return a CKey + + CKey key(keycode, vkey, unicode, ascii, modifiers, lockingModifiers, held.count()); + + return key; +} + +void CKeyboardStat::ProcessKeyDown(XBMC_keysym& keysym) +{ + if (!(m_lastKeysym == keysym)) + { + m_lastKeysym = keysym; + m_lastKeyTime = std::chrono::steady_clock::now(); + } +} + +void CKeyboardStat::ProcessKeyUp(void) +{ + memset(&m_lastKeysym, 0, sizeof(m_lastKeysym)); + m_lastKeyTime = {}; +} + +// Return the key name given a key ID +// Used to make the debug log more intelligible +// The KeyID includes the flags for ctrl, alt etc + +std::string CKeyboardStat::GetKeyName(int KeyID) +{ + int keyid; + std::string keyname; + XBMCKEYTABLE keytable; + + keyname.clear(); + + // Get modifiers + + if (KeyID & CKey::MODIFIER_CTRL) + keyname.append("ctrl-"); + if (KeyID & CKey::MODIFIER_SHIFT) + keyname.append("shift-"); + if (KeyID & CKey::MODIFIER_ALT) + keyname.append("alt-"); + if (KeyID & CKey::MODIFIER_SUPER) + keyname.append("win-"); + if (KeyID & CKey::MODIFIER_META) + keyname.append("meta-"); + if (KeyID & CKey::MODIFIER_LONG) + keyname.append("long-"); + + // Now get the key name + + keyid = KeyID & 0xFF; + bool VKeyFound = KeyTableLookupVKeyName(keyid, &keytable); + if (VKeyFound) + keyname.append(keytable.keyname); + else + keyname += std::to_string(keyid); + + // in case this might be an universalremote keyid + // we also print the possible corresponding obc code + // so users can easily find it in their universalremote + // map xml + if (VKeyFound || keyid > 255) + keyname += StringUtils::Format(" ({:#02x})", KeyID); + else // obc keys are 255 -rawid + keyname += StringUtils::Format(" ({:#02x}, obc{})", KeyID, 255 - KeyID); + + return keyname; +} |