20#include "pedigree/kernel/Log.h"
21#include "pedigree/kernel/machine/HidInputManager.h"
22#include "pedigree/kernel/machine/Keyboard.h"
23#include "pedigree/kernel/machine/KeymapManager.h"
24#include "pedigree/kernel/machine/keymaps/KeymapEnUs.h"
25#include "pedigree/kernel/utilities/utility.h"
30#define KM_NOTICE NOTICE
35#define KEYMAP_INDEX(combinator, modifiers, scancode) \
36 (((combinator & 0xFF) << 11) | ((modifiers & 0xF) << 7) | (scancode & 0x7F))
37#define KEYMAP_MAX_INDEX KEYMAP_INDEX(0xFF, 0xF, 0x7F)
52 m_bHaveLoadedKeymap(false) {
53 void* sparseBuffer = ASSUME_ALIGNMENT(sparseBuff,
sizeof(
void*));
54 void* dataBuffer = ASSUME_ALIGNMENT(dataBuff,
sizeof(
void*));
57 m_pDataTable =
reinterpret_cast<KeymapEntry*
>(dataBuffer);
63 void* sparseBuffer = ASSUME_ALIGNMENT(pSparseTable,
sizeof(
void*));
64 void* dataBuffer = ASSUME_ALIGNMENT(pDataTable,
sizeof(
void*));
71 m_pDataTable =
reinterpret_cast<KeymapEntry*
>(dataBuffer);
75 ERROR(
"KeymapManager: new keymap check failed, restoring old keymap");
77 m_pDataTable = oldData;
96 uint32_t sparseTableOffset = pCompiledKeymap[0];
97 uint32_t dataTableOffset = pCompiledKeymap[1];
98 uint32_t sparseTableSize = dataTableOffset - sparseTableOffset;
99 uint32_t dataTableSize = keymapLength - dataTableOffset;
109 MemoryCopy(
m_pSparseTable, adjust_pointer(pCompiledKeymap, sparseTableOffset), sparseTableSize);
110 MemoryCopy(m_pDataTable, adjust_pointer(pCompiledKeymap, dataTableOffset), dataTableSize);
114 ERROR(
"KeymapManager: new keymap check failed, restoring old keymap");
116 m_pDataTable = oldData;
136 if (!((keyCode >= HidLeftCtrl && keyCode <= HidRightGui) || keyCode == HidCapsLock))
139 if (keyCode == HidLeftCtrl)
141 if (keyCode == HidRightCtrl)
142 m_bRightCtrl = bDown;
143 if (keyCode == HidLeftShift)
144 m_bLeftShift = bDown;
145 if (keyCode == HidRightShift)
146 m_bRightShift = bDown;
147 if (keyCode == HidLeftAlt)
149 if (keyCode == HidRightAlt)
152 if (keyCode == HidCapsLock && !bDown)
158 KM_NOTICE(
"resolveHidKeycode(" << keyCode <<
")");
162 bool bShift = m_bLeftShift || m_bRightShift;
163 bool bAlt = m_bLeftAlt, bAltGr = m_bRightAlt;
165 bool bUseUpper =
false;
173 if (!pKeymapEntry || (!pKeymapEntry->value && !pKeymapEntry->flags)) {
174 KM_NOTICE(
"keymap: falling back: -combinator");
175 pKeymapEntry =
getKeymapEntry(bCtrl, bShift, bAlt, bAltGr, 0, keyCode);
178 if (!pKeymapEntry || (!pKeymapEntry->value && !pKeymapEntry->flags)) {
179 KM_NOTICE(
"keymap: falling back: -combinator, -ctrl");
180 pKeymapEntry =
getKeymapEntry(
false, bShift, bAlt, bAltGr, 0, keyCode);
183 if (!pKeymapEntry || (!pKeymapEntry->value && !pKeymapEntry->flags)) {
184 KM_NOTICE(
"keymap: falling back: -combinator, -ctrl, -alt");
185 pKeymapEntry =
getKeymapEntry(
false, bShift,
false,
false, 0, keyCode);
188 if (!pKeymapEntry || (!pKeymapEntry->value && !pKeymapEntry->flags)) {
189 KM_NOTICE(
"keymap: falling back: -combinator, -ctrl, -alt, -shift");
190 pKeymapEntry =
getKeymapEntry(
false,
false,
false,
false, 0, keyCode);
193 if (!pKeymapEntry || (!pKeymapEntry->value && !pKeymapEntry->flags)) {
194 KM_NOTICE(
"keymap: no fallback possible, key not in keymap");
198 KM_NOTICE(
"keymap: successfully got a keymap entry");
201 uint32_t nCombinator = pKeymapEntry->flags & 0xFF;
218 uint64_t key = pKeymapEntry->value;
220 if (pKeymapEntry->flags & KeymapEntry::Special)
221 key |= Keyboard::Special;
222 else if (bUseUpper && key >=
'a' && key <=
'z')
224 else if (!bUseUpper && key >=
'A' && key <=
'Z')
228 key |= Keyboard::Ctrl;
230 key |= Keyboard::Shift;
232 key |= Keyboard::Alt;
234 key |= Keyboard::AltGr;
240 bool bAltGr, uint8_t nCombinator,
242 KM_NOTICE(
"getKeymapEntry(ctrl=" << bCtrl <<
", shift=" << bShift <<
", alt=" << bAlt
243 <<
", altgr=" << bAltGr <<
", comb=" << nCombinator
244 <<
", code=" << keyCode <<
")");
247 size_t modifiers = 0;
249 modifiers |= IndexCtrl;
251 modifiers |= IndexShift;
253 modifiers |= IndexAlt;
255 modifiers |= IndexAltGr;
256 size_t nIndex = KEYMAP_INDEX(nCombinator, modifiers, keyCode);
258 KM_NOTICE(
"idx=" << nIndex <<
", mods=" << modifiers <<
", code=" << keyCode);
261 size_t bisect = (KEYMAP_MAX_INDEX + 1) / 2;
262 size_t size = (KEYMAP_MAX_INDEX + 1) / 2;
264 size_t nDataIndex = 0;
266 if (nIndex < bisect) {
269 if (pSparse->left & SparseEntry::DataFlag) {
270 size_t nOffset = nIndex - (bisect - size);
275 bisect = bisect - size;
280 if (pSparse->right & SparseEntry::DataFlag) {
281 size_t nOffset = nIndex - bisect;
286 bisect = bisect + size;
292 return &m_pDataTable[nDataIndex /
sizeof(
KeymapEntry)];
297static const uint8_t pc102ToHidTableNormal[] = {
298 0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b,
299 0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c, 0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16,
300 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33, 0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
301 0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55, 0xe2, 0x2c, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
302 0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f, 0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
303 0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x64, 0x44, 0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
304 0x00, 0x00, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00,
305 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65};
307static const uint8_t pc102ToHidTableEscape[] = {
308 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
309 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
310 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
311 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
312 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a, 0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
313 0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
314 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
315 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
319 if (scancode == 0xE0) {
325 if (scancode == 0xE1) {
331 if (scancode == 0x1D && escape == EscapeE1) {
338 KM_NOTICE(
"keymap: using escape table to convert PC102 scancode " << scancode);
339 return pc102ToHidTableEscape[scancode & 0x7F];
341 KM_NOTICE(
"keymap: using normal table to convert PC102 scancode " << scancode);
342 return pc102ToHidTableNormal[scancode & 0x7F];
bool handleHidModifier(uint8_t keyCode, bool bDown)
static KeymapManager m_Instance
Static instance.
bool m_bLeftCtrl
State of the modifiers, true if down, false if up.
bool useCompiledKeymap(uint32_t *pCompiledKeymap, size_t keymapLength)
Changes the current keymap to the given (compiled) one.
KeymapEntry * getKeymapEntry(bool bCtrl, bool bShift, bool bAlt, bool bAltGr, uint8_t nCombinator, uint8_t keyCode)
Returns the keymap entry corresponding to given keycode and modifiers.
uint8_t m_nCombinator
Index of the current active combinator, if any.
SparseEntry * m_pSparseTable
The sparse and data tables for the current keymap.
virtual ~KeymapManager()
Default destructor.
uint8_t convertPc102ScancodeToHidKeycode(uint8_t scancode, EscapeState &escape)
Converts a pc102 scancode into a HID keycode.
bool m_bCapsLock
True if caps lock is on.
uint64_t resolveHidKeycode(uint8_t keyCode)
KeymapManager()
Default constructor.
void useKeymap(uint8_t *pSparseTable, uint8_t *pDataTable)
Changes the current keymap to the given one.
Structure representing an entry in the keymap table.
Structure representing an entry in the sparse table.