Skip to content

Commit

Permalink
Implemented host_keymaps
Browse files Browse the repository at this point in the history
host_keymaps enable defining keymaps in a natural fashion.
Instead of using Key constants like Key_A or LSHIFT(Key_A) it allows to
conveniently write "a" or "A".

The mappings between ascii and unicode characters to USB-HID keys
works by reverse engineering the host keymaps.

If the host keymap is known, then the mapping between HID-report keys like Key_A,
Key_LeftShift, etc. and the generated printable and non-printable keys
on the host is well defined. This mapping can easily be reverse
engineered, e.g. based on common keymaps like us_en but also for
any other keymap that involves non-ascii symbols.

host_keymaps also introduces unicode symbols for the most common keys on
any keyboard that commonly represent non-printable characters. This
allows for a KEYMAP(...) definition to closely resemble what would be printed on
the keys of a keyboard with the actual keymap.

The newly introduced host_keymap system is easily extensible and allows
users to define their own non-english keymaps.

A work-in-progress version of the EurKey keymap for most european
languages also comes with this commit. It is however just started and
needs some more work. It is mainly meant to demonstrate how one keymap
can be defined based on another one (here EurKey is based on us_en),
overriding only some of the keys and relying on the base keymap to take
care of handling any non-overridden keys.

Signed-off-by: Florian Fleissner <[email protected]>
  • Loading branch information
Florian Fleissner committed Nov 12, 2019
1 parent 3cb97a3 commit 897c20a
Show file tree
Hide file tree
Showing 8 changed files with 1,118 additions and 0 deletions.
58 changes: 58 additions & 0 deletions examples/Keystrokes/HostKeymap/HostKeymap.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Unicode -- Unicode input helpers
* Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <Kaleidoscope.h>

#include "kaleidoscope/host_keymap/ascii/us_en.h"
#include "kaleidoscope/host_keymap/unicode/us_en.h"

USE_HOST_KEYMAP(ascii, us_en)
USE_HOST_KEYMAP(unicode, us_en)

// *INDENT-OFF*

KEYMAPS(
[0] = KEYMAP_STACKED
(
XXX, "1", "2", "3", "4", "5", XXX,
"`", "q", "w", "e", "r", "t", "\t",
L"", "a", "s", "d", "f", "g",
L"", "z", "x", "c", "v", "b", L"",

L"", L"", L"", L"",
XXX,

XXX, "6", "7", "8", "9", "0", XXX,
L"", "y", "u", "i", "o", "p", "=",
"h", "j", "k", "l", ";", "\"",
XXX, "n", "m", ",", ".", "/", "-",

L"r⇧", L"r⌥", L"", L"r⌃",
XXX
)
)
// *INDENT-ON*

//KALEIDOSCOPE_INIT_PLUGINS();

void setup() {
Kaleidoscope.setup();
}

void loop() {
Kaleidoscope.loop();
}
87 changes: 87 additions & 0 deletions src/kaleidoscope/host_keymap/ascii/common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/* Kaleidoscope - Firmware for computer input devices
* Copyright (C) 2013-2018 Keyboard.io, Inc.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include "kaleidoscope/host_keymap/host_keymap.h"

namespace kaleidoscope {
namespace host_keymap {
namespace ascii {

struct AsciiCharProcessor {
static constexpr bool isEscapeChar(char c) {
return c == '#';
}

static constexpr bool isSeparator(char c) {
return (c == ' ')
|| (c == '\t')
|| (c == '+');
}

static constexpr bool isMirrorChar(char c) {
return c == 'r';
}
};

#define _HOST_KEYMAP_CAST_ON_MODIFIERS_ASCII(OP) \
OP('s', LSHIFT(k)) \
OP('S', LSHIFT(k)) \
OP('c', LCTRL(k)) \
OP('C', LCTRL(k)) \
OP('a', LALT(k)) \
OP('A', RALT(k)) \
OP('m', LGUI(k)) \
OP('M', LGUI(k)) \
OP('g', LGUI(k)) \
OP('G', LGUI(k))

// Define a AsciiConverter template base class that any ascii keymap converters
// are derived from by means of invoking the HOST_KEYMAP_ASCII_LANGUAGE_CONVERTER
// function macro.
//
_HOST_KEYMAP_DEFINE_CHAR_CONVERTER(
AsciiConverter, char, _HOST_KEYMAP_CAST_ON_MODIFIERS_ASCII)

#undef _HOST_KEYMAP_CAST_ON_MODIFIERS_ASCII

typedef _CharParsingStandardFallback<char> CharParsingStandardFallback;

} // namespace ascii
} // namespace host_keymap
} // namespace kaleidoscope

#define HOST_KEYMAP_ASCII_LANGUAGE_CONVERTER(LANGUAGE_KEYMAP, CHAR_PARSING_FALLBACK) \
struct Converter : public AsciiConverter<Converter, AsciiCharProcessor> \
{ \
typedef AsciiConverter<Converter, AsciiCharProcessor> Parent; \
\
using typename Parent::StringMemberType; \
using typename Parent::CharType; \
\
static constexpr bool isKeyChar(char c) { \
return LANGUAGE_KEYMAP(_HOST_KEYMAP_IS_KEY_CHAR) \
CHAR_PARSING_FALLBACK::isKeyChar(c); \
} \
\
static constexpr Key charToKey(char c) { \
return LANGUAGE_KEYMAP( \
_HOST_KEYMAP_MAP_KEY_CHAR_TO_KALEIDOSCOPE_KEY \
) \
CHAR_PARSING_FALLBACK::charToKey(c); \
} \
};
142 changes: 142 additions & 0 deletions src/kaleidoscope/host_keymap/ascii/us_en.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/* Kaleidoscope - Firmware for computer input devices
* Copyright (C) 2013-2018 Keyboard.io, Inc.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include "kaleidoscope/key_defs.h"
#include "kaleidoscope/key_defs_keyboard.h"
#include "kaleidoscope/host_keymap/ascii/common.h"

#define ASCII_US_EN_KEYMAP(OP) \
OP('\n', Key_Enter) \
OP('\t', Key_Tab) \
\
OP('!', LSHIFT(Key_1)) \
OP('@', LSHIFT(Key_2)) \
OP('#', LSHIFT(Key_3)) \
OP('$', LSHIFT(Key_4)) \
OP('%', LSHIFT(Key_5)) \
OP('&', LSHIFT(Key_7)) \
OP('\'', Key_Quote) \
OP('"', LSHIFT(Key_Quote)) \
OP('(', LSHIFT(Key_9)) \
OP(')', LSHIFT(Key_0)) \
OP('*', LSHIFT(Key_8)) \
OP('+', LSHIFT(Key_Equals)) \
OP(',', Key_Comma) \
OP('-', Key_Minus) \
OP('.', Key_Period) \
OP('/', Key_Slash) \
OP('0', Key_0) \
OP('1', Key_1) \
OP('2', Key_2) \
OP('3', Key_3) \
OP('4', Key_4) \
OP('5', Key_5) \
OP('6', Key_6) \
OP('7', Key_7) \
OP('8', Key_8) \
OP('9', Key_9) \
OP(':', LSHIFT(Key_Semicolon)) \
OP(';', Key_Semicolon) \
OP('<', LSHIFT(Key_Comma)) \
OP('=', Key_Equals) \
OP('>', LSHIFT(Key_Period)) \
OP('?', LSHIFT(Key_Slash)) \
\
OP('A', LSHIFT(Key_A)) \
OP('B', LSHIFT(Key_B)) \
OP('C', LSHIFT(Key_C)) \
OP('D', LSHIFT(Key_D)) \
OP('E', LSHIFT(Key_E)) \
OP('F', LSHIFT(Key_F)) \
OP('G', LSHIFT(Key_G)) \
OP('H', LSHIFT(Key_H)) \
OP('I', LSHIFT(Key_I)) \
OP('J', LSHIFT(Key_J)) \
OP('K', LSHIFT(Key_K)) \
OP('L', LSHIFT(Key_L)) \
OP('M', LSHIFT(Key_M)) \
OP('N', LSHIFT(Key_N)) \
OP('O', LSHIFT(Key_O)) \
OP('P', LSHIFT(Key_P)) \
OP('Q', LSHIFT(Key_Q)) \
OP('R', LSHIFT(Key_R)) \
OP('S', LSHIFT(Key_S)) \
OP('T', LSHIFT(Key_T)) \
OP('U', LSHIFT(Key_U)) \
OP('V', LSHIFT(Key_V)) \
OP('W', LSHIFT(Key_W)) \
OP('X', LSHIFT(Key_X)) \
OP('Y', LSHIFT(Key_Y)) \
OP('Z', LSHIFT(Key_Z)) \
\
OP('[', Key_LeftBracket) \
OP('\\', Key_Backslash) \
OP(']', Key_RightBracket) \
OP('^', LSHIFT(Key_6)) \
OP('_', LSHIFT(Key_Minus)) \
OP('`', Key_Backtick) \
\
OP('a', Key_A) \
OP('b', Key_B) \
OP('c', Key_C) \
OP('d', Key_D) \
OP('e', Key_E) \
OP('f', Key_F) \
OP('g', Key_G) \
OP('h', Key_H) \
OP('i', Key_I) \
OP('j', Key_J) \
OP('k', Key_K) \
OP('l', Key_L) \
OP('m', Key_M) \
OP('n', Key_N) \
OP('o', Key_O) \
OP('p', Key_P) \
OP('q', Key_Q) \
OP('r', Key_R) \
OP('s', Key_S) \
OP('t', Key_T) \
OP('u', Key_U) \
OP('v', Key_V) \
OP('w', Key_W) \
OP('x', Key_X) \
OP('y', Key_Y) \
OP('z', Key_Z) \
\
OP('{', LSHIFT(Key_LeftBracket)) \
OP('|', LSHIFT(Key_Backslash)) \
OP('}', LSHIFT(Key_RightBracket)) \
OP('~', Key_Minus) \
OP(' ', Key_Spacebar)

namespace kaleidoscope {
namespace host_keymap {
namespace ascii {
namespace us_en {

HOST_KEYMAP_ASCII_LANGUAGE_CONVERTER(
ASCII_US_EN_KEYMAP,
CharParsingStandardFallback
)

} // namespace us_en
} // namespace ascii
} // namespace host_keymap
} // namespace kaleidoscope

#undef ASCII_US_EN_KEYMAP
Loading

0 comments on commit 897c20a

Please sign in to comment.