20 #include "pedigree/kernel/machine/KeymapManager.h" 21 #include "pedigree/kernel/Log.h" 22 #include "pedigree/kernel/machine/HidInputManager.h" 23 #include "pedigree/kernel/machine/Keyboard.h" 24 #include "pedigree/kernel/machine/keymaps/KeymapEnUs.h" 25 #include "pedigree/kernel/utilities/utility.h" 30 #define KM_NOTICE NOTICE 32 #define KM_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) 42 : m_pSparseTable(0), m_pDataTable(0), m_bLeftCtrl(false),
43 m_bLeftShift(false), m_bLeftAlt(false), m_bRightCtrl(false),
44 m_bRightShift(false), m_bRightAlt(false), m_bCapsLock(false),
45 m_nCombinator(0), m_bHaveLoadedKeymap(false)
47 void *sparseBuffer = ASSUME_ALIGNMENT(sparseBuff,
sizeof(
void *));
48 void *dataBuffer = ASSUME_ALIGNMENT(dataBuff,
sizeof(
void *));
51 m_pDataTable =
reinterpret_cast<KeymapEntry *
>(dataBuffer);
60 void *sparseBuffer = ASSUME_ALIGNMENT(pSparseTable,
sizeof(
void *));
61 void *dataBuffer = ASSUME_ALIGNMENT(pDataTable,
sizeof(
void *));
68 m_pDataTable =
reinterpret_cast<KeymapEntry *
>(dataBuffer);
73 ERROR(
"KeymapManager: new keymap check failed, restoring old keymap");
75 m_pDataTable = oldData;
92 uint32_t *pCompiledKeymap,
size_t keymapLength)
98 uint32_t sparseTableOffset = pCompiledKeymap[0];
99 uint32_t dataTableOffset = pCompiledKeymap[1];
100 uint32_t sparseTableSize = dataTableOffset - sparseTableOffset;
101 uint32_t dataTableSize = keymapLength - dataTableOffset;
112 m_pSparseTable, adjust_pointer(pCompiledKeymap, sparseTableOffset),
115 m_pDataTable, adjust_pointer(pCompiledKeymap, dataTableOffset),
121 ERROR(
"KeymapManager: new keymap check failed, restoring old keymap");
123 m_pDataTable = oldData;
146 if (!((keyCode >= HidLeftCtrl && keyCode <= HidRightGui) ||
147 keyCode == HidCapsLock))
150 if (keyCode == HidLeftCtrl)
152 if (keyCode == HidRightCtrl)
153 m_bRightCtrl = bDown;
154 if (keyCode == HidLeftShift)
155 m_bLeftShift = bDown;
156 if (keyCode == HidRightShift)
157 m_bRightShift = bDown;
158 if (keyCode == HidLeftAlt)
160 if (keyCode == HidRightAlt)
163 if (keyCode == HidCapsLock && !bDown)
170 KM_NOTICE(
"resolveHidKeycode(" << keyCode <<
")");
174 bool bShift = m_bLeftShift || m_bRightShift;
175 bool bAlt = m_bLeftAlt, bAltGr = m_bRightAlt;
177 bool bUseUpper =
false;
186 if (!pKeymapEntry || (!pKeymapEntry->value && !pKeymapEntry->flags))
188 KM_NOTICE(
"keymap: falling back: -combinator");
189 pKeymapEntry =
getKeymapEntry(bCtrl, bShift, bAlt, bAltGr, 0, keyCode);
192 if (!pKeymapEntry || (!pKeymapEntry->value && !pKeymapEntry->flags))
194 KM_NOTICE(
"keymap: falling back: -combinator, -ctrl");
195 pKeymapEntry =
getKeymapEntry(
false, bShift, bAlt, bAltGr, 0, keyCode);
198 if (!pKeymapEntry || (!pKeymapEntry->value && !pKeymapEntry->flags))
200 KM_NOTICE(
"keymap: falling back: -combinator, -ctrl, -alt");
201 pKeymapEntry =
getKeymapEntry(
false, bShift,
false,
false, 0, keyCode);
204 if (!pKeymapEntry || (!pKeymapEntry->value && !pKeymapEntry->flags))
206 KM_NOTICE(
"keymap: falling back: -combinator, -ctrl, -alt, -shift");
207 pKeymapEntry =
getKeymapEntry(
false,
false,
false,
false, 0, keyCode);
210 if (!pKeymapEntry || (!pKeymapEntry->value && !pKeymapEntry->flags))
212 KM_NOTICE(
"keymap: no fallback possible, key not in keymap");
216 KM_NOTICE(
"keymap: successfully got a keymap entry");
219 uint32_t nCombinator = pKeymapEntry->flags & 0xFF;
242 uint64_t key = pKeymapEntry->value;
244 if (pKeymapEntry->flags & KeymapEntry::Special)
245 key |= Keyboard::Special;
246 else if (bUseUpper && key >=
'a' && key <=
'z')
248 else if (!bUseUpper && key >=
'A' && key <=
'Z')
252 key |= Keyboard::Ctrl;
254 key |= Keyboard::Shift;
256 key |= Keyboard::Alt;
258 key |= Keyboard::AltGr;
264 bool bCtrl,
bool bShift,
bool bAlt,
bool bAltGr, uint8_t nCombinator,
268 "getKeymapEntry(ctrl=" << bCtrl <<
", shift=" << bShift
269 <<
", alt=" << bAlt <<
", altgr=" << bAltGr
270 <<
", comb=" << nCombinator
271 <<
", code=" << keyCode <<
")");
274 size_t modifiers = 0;
276 modifiers |= IndexCtrl;
278 modifiers |= IndexShift;
280 modifiers |= IndexAlt;
282 modifiers |= IndexAltGr;
283 size_t nIndex = KEYMAP_INDEX(nCombinator, modifiers, keyCode);
286 "idx=" << nIndex <<
", mods=" << modifiers <<
", code=" << keyCode);
289 size_t bisect = (KEYMAP_MAX_INDEX + 1) / 2;
290 size_t size = (KEYMAP_MAX_INDEX + 1) / 2;
292 size_t nDataIndex = 0;
299 if (pSparse->left & SparseEntry::DataFlag)
301 size_t nOffset = nIndex - (bisect - size);
302 nDataIndex = (pSparse->left & ~
SparseEntry::DataFlag) +
307 bisect = bisect - size;
314 if (pSparse->right & SparseEntry::DataFlag)
316 size_t nOffset = nIndex - bisect;
317 nDataIndex = (pSparse->right & ~
SparseEntry::DataFlag) +
322 bisect = bisect + size;
328 return &m_pDataTable[nDataIndex /
sizeof(
KeymapEntry)];
333 static const uint8_t pc102ToHidTableNormal[] = {
334 0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
335 0x2d, 0x2e, 0x2a, 0x2b, 0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c,
336 0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16, 0x07, 0x09, 0x0a, 0x0b,
337 0x0d, 0x0e, 0x0f, 0x33, 0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
338 0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55, 0xe2, 0x2c, 0x39, 0x3a,
339 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
340 0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59, 0x5a, 0x5b, 0x62, 0x63,
341 0x00, 0x00, 0x64, 0x44, 0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
342 0x00, 0x00, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85,
343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
344 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65};
346 static const uint8_t pc102ToHidTableEscape[] = {
347 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
348 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
349 0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
350 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
351 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46, 0xe6, 0x00, 0x00, 0x00,
352 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a,
353 0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d, 0x51, 0x4e, 0x49, 0x4c,
354 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
355 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
356 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
357 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
360 uint8_t scancode, EscapeState &escape)
363 if (scancode == 0xE0)
370 if (scancode == 0xE1)
377 if (scancode == 0x1D && escape == EscapeE1)
387 "keymap: using escape table to convert PC102 scancode " 389 return pc102ToHidTableEscape[scancode & 0x7F];
394 "keymap: using normal table to convert PC102 scancode " 396 return pc102ToHidTableNormal[scancode & 0x7F];
virtual ~KeymapManager()
Default destructor.
KeymapManager()
Default constructor.
void useKeymap(uint8_t *pSparseTable, uint8_t *pDataTable)
Changes the current keymap to the given one.
uint64_t resolveHidKeycode(uint8_t keyCode)
bool m_bCapsLock
True if caps lock is on.
uint8_t convertPc102ScancodeToHidKeycode(uint8_t scancode, EscapeState &escape)
Converts a pc102 scancode into a HID keycode.
static KeymapManager m_Instance
Static instance.
bool handleHidModifier(uint8_t keyCode, bool bDown)
uint8_t m_nCombinator
Index of the current active combinator, if any.
Structure representing an entry in the sparse table.
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.
SparseEntry * m_pSparseTable
The sparse and data tables for the current keymap.
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.
Structure representing an entry in the keymap table.