Merge remote-tracking branch 'plugin/Unicode/f/monorepo' into f/monorepo-stage2

pull/389/head
Gergely Nagy 6 years ago
commit 350c35c75d
No known key found for this signature in database
GPG Key ID: AC1E90BAC433F68F

@ -0,0 +1,116 @@
# Kaleidoscope-Unicode
The `Unicode` extension makes it easier to write plugins that input Unicode
symbols on the host. Because inputting Unicode varies from OS to OS, this helper
library was made to hide most of the differences. All one has to do, is set up
the `HostOS` singleton properly, and the `Unicode` library will handle the rest,
by providing an easy interface for inputting Unicode symbols by their 32-bit
codepoints.
## Using the extension
Using the extension is as simple as including the header, registering it with
`Kaleidoscope.use()`, and then using any of the methods provided by the
`Unicode` singleton object.
```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-EEPROM-Settings.h>
#include <Kaleidoscope-HostOS.h>
#include <Kaleidoscope-Unicode.h>
KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings, HostOS, Unicode);
void setup() {
Kaleidoscope.setup();
Unicode.type(0x2328);
}
```
## Extension methods
The extension provides a number of methods on the `Unicode` object, but also has
symbols that can be [overridden](#overrideable-methods), to add custom
functionality.
### `.type(code_point)`
> Starts the Unicode input method using the [`.start()`](#start) method, inputs
> the `code_point` using [`.typeCode()`](#typeCode), and finishes up with
> the [`.end()`](#end) method. For each hexadecimal digit sent to the host,
> the [`.input()`](#input) method will also be called.
>
> This method is most useful when one knows the code point of the Unicode symbol
> to enter ahead of time, when the code point does not depend on anything else.
### `.typeCode(code_point)`
> Inputs the hex codes for `code_point`, and the hex codes only. Use when the
> input method is to be started and ended separately.
>
> For example, a macro that starts Unicode input, and switches to a layer full
> of macros that send the hex codes is one scenario where this function is of
> use.
### `.start()`
> Starts the Unicode input method. The way it starts it, depends on the host
> operating system.
### `.input()`
> If the host operating system requires keys being held during the Unicode
> input, this function will hold them for us.
### `.end()`
> Finishes the Unicode input method, in an OS-specific way.
## Overrideable methods
### `hexToKey(hex_digit)`
> A function that returns a `Key` struct, given a 8-bit hex digit. For most
> uses, the built-in version of this function is sufficient, but if the keymap
> on the OS-side has any of the hexadecimal symbols on other scancodes than
> QWERTY, this function should be overridden to use the correct scan codes.
### `unicodeCustomStart()`
> If the host OS type is set to `kaleidoscope::hostos::Custom`, then this function will
> be called whenever the [`.start()`](#start) method is called. The default
> implementation does nothing, and should be overridden to implement the custom
> magic needed to enter unicode input mode.
### `unicodeCustomInput()`
> If the host OS type is set to `kaleidoscope::hostos::Custom`, then this function will
> be called whenever the [`.input()`](#input) method is called. The default
> implementation does nothing, and should be overridden to implement the custom
> magic needed while inputting the hex code itself (such as holding additional
> keys).
### `unicodeCustomEnd()`
> If the host OS type is set to `kaleidoscope::hostos::Custom`, then this function will
> be called whenever the [`.end()`](#end) method is called. The default
> implementation does nothing, and should be overridden to implement the custom
> magic needed to leave unicode input mode.
## Dependencies
* [Kaleidoscope-HostOS](HostOS.md)
## Other Configuration
On OS X/macOS, you'll need to change the input method to be "Unicode Hex Input".
You can do this by going to System Preferences > Keyboard > Input Sources, clicking
the `+` button, selecting it from the list, then setting it as the active input method.
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin.
[plugin:example]: ../../examples/Unicode/Unicode.ino

@ -0,0 +1,76 @@
/* -*- 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-EEPROM-Settings.h>
#include <Kaleidoscope-HostOS.h>
#include "Kaleidoscope-Macros.h"
#include <Kaleidoscope-Unicode.h>
enum { MACRO_KEYBOARD_EMOJI };
// *INDENT-OFF*
const Key keymaps[][ROWS][COLS] PROGMEM = {
[0] = KEYMAP_STACKED
(
Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
Key_skip,
M(MACRO_KEYBOARD_EMOJI), Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
Key_skip),
};
// *INDENT-ON*
static void unicode(uint32_t character, uint8_t keyState) {
if (keyToggledOn(keyState)) {
Unicode.type(character);
}
}
const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) {
switch (macroIndex) {
case MACRO_KEYBOARD_EMOJI:
unicode(0x2328, keyState);
break;
}
return MACRO_NONE;
}
KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings,
HostOS,
Macros,
Unicode);
void setup() {
Kaleidoscope.setup();
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,20 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Unicode -- Unicode input helpers
* Copyright (C) 2016, 2017 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/plugin/Unicode.h>

@ -0,0 +1,193 @@
/* -*- 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-Unicode.h>
#include "kaleidoscope/hid.h"
namespace kaleidoscope {
namespace plugin {
void Unicode::start(void) {
switch (::HostOS.os()) {
case hostos::LINUX:
hid::pressRawKey(Key_LeftControl);
hid::pressRawKey(Key_LeftShift);
hid::pressRawKey(Key_U);
hid::sendKeyboardReport();
hid::releaseRawKey(Key_LeftControl);
hid::releaseRawKey(Key_LeftShift);
hid::releaseRawKey(Key_U);
hid::sendKeyboardReport();
break;
case hostos::WINDOWS:
hid::pressRawKey(Key_LeftAlt);
hid::sendKeyboardReport();
hid::pressRawKey(Key_KeypadAdd);
hid::sendKeyboardReport();
hid::releaseRawKey(Key_KeypadAdd);
hid::sendKeyboardReport();
break;
case hostos::OSX:
hid::pressRawKey(Key_LeftAlt);
break;
default:
unicodeCustomStart();
break;
}
}
void Unicode::input(void) {
switch (::HostOS.os()) {
case hostos::LINUX:
break;
case hostos::WINDOWS:
case hostos::OSX:
hid::pressRawKey(Key_LeftAlt);
break;
default:
unicodeCustomInput();
break;
}
}
void Unicode::end(void) {
switch (::HostOS.os()) {
case hostos::LINUX:
hid::pressRawKey(Key_Spacebar);
hid::sendKeyboardReport();
hid::releaseRawKey(Key_Spacebar);
hid::sendKeyboardReport();
break;
case hostos::WINDOWS:
case hostos::OSX:
hid::releaseRawKey(Key_LeftAlt);
hid::sendKeyboardReport();
break;
default:
unicodeCustomEnd();
break;
}
}
void Unicode::typeCode(uint32_t unicode) {
bool on_zero_start = true;
for (int8_t i = 7; i >= 0; i--) {
if (i <= 3) {
on_zero_start = false;
}
uint8_t digit = ((unicode >> (i * 4)) & 0xF);
if (digit == 0) {
if (on_zero_start == false) {
Key key;
if (::HostOS.os() == hostos::WINDOWS) {
key = hexToKeysWithNumpad(digit);
} else {
key = hexToKey(digit);
}
input();
hid::pressRawKey(key);
hid::sendKeyboardReport();
input();
hid::releaseRawKey(key);
hid::sendKeyboardReport();
}
} else {
Key key;
if (::HostOS.os() == hostos::WINDOWS) {
key = hexToKeysWithNumpad(digit);
} else {
key = hexToKey(digit);
}
input();
hid::pressRawKey(key);
hid::sendKeyboardReport();
input();
hid::releaseRawKey(key);
hid::sendKeyboardReport();
on_zero_start = false;
}
delay(5);
}
}
void Unicode::type(uint32_t unicode) {
start();
typeCode(unicode);
end();
}
}
}
__attribute__((weak)) Key hexToKey(uint8_t hex) {
uint8_t m;
if (hex == 0x0) {
return Key_0;
}
if (hex < 0xA) {
m = Key_1.keyCode + (hex - 0x1);
} else {
m = Key_A.keyCode + (hex - 0xA);
}
return { m, KEY_FLAGS };
}
__attribute__((weak)) Key hexToKeysWithNumpad(uint8_t hex) {
uint8_t m;
if (hex == 0x0) {
return Key_Keypad0;
}
if (hex < 0xA) {
m = Key_Keypad1.keyCode + (hex - 0x1);
} else {
switch (hex) {
case 0xA:
m = Key_A.keyCode;
break;
case 0xB:
m = Key_B.keyCode;
break;
case 0xC:
m = Key_C.keyCode;
break;
case 0xD:
m = Key_D.keyCode;
break;
case 0xE:
m = Key_E.keyCode;
break;
case 0xF:
m = Key_F.keyCode;
break;
default:
m = Key_NoKey.keyCode;
break;
}
}
return { m, KEY_FLAGS };
}
__attribute__((weak)) void unicodeCustomStart(void) {
}
__attribute__((weak)) void unicodeCustomEnd(void) {
}
__attribute__((weak)) void unicodeCustomInput(void) {
}
kaleidoscope::plugin::Unicode Unicode;

@ -0,0 +1,46 @@
/* -*- 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/>.
*/
#pragma once
#include <Kaleidoscope.h>
#include <Kaleidoscope-HostOS.h>
namespace kaleidoscope {
namespace plugin {
class Unicode : public kaleidoscope::Plugin {
public:
Unicode(void) {}
static void start(void);
static void input(void);
static void end(void);
static void type(uint32_t unicode);
static void typeCode(uint32_t unicode);
};
}
}
Key hexToKey(uint8_t hex);
Key hexToKeysWithNumpad(uint8_t hex);
void unicodeCustomStart(void);
void unicodeCustomEnd(void);
void unicodeCustomInput(void);
extern kaleidoscope::plugin::Unicode Unicode;
Loading…
Cancel
Save