This commit is contained in:
cbbrowne 2016-10-31 11:45:54 -04:00
commit b90366285f
4 changed files with 122 additions and 67 deletions

View File

@ -32,7 +32,9 @@ ABS_ROOT_MAKEFILE := $(abspath $(ROOT_MAKEFILE))
ABS_STARTING_DIR := $(dir $(ABS_STARTING_MAKEFILE)) ABS_STARTING_DIR := $(dir $(ABS_STARTING_MAKEFILE))
ABS_ROOT_DIR := $(dir $(ABS_ROOT_MAKEFILE)) ABS_ROOT_DIR := $(dir $(ABS_ROOT_MAKEFILE))
STARTING_DIR := $(subst $(ABS_ROOT_DIR),,$(ABS_STARTING_DIR)) STARTING_DIR := $(subst $(ABS_ROOT_DIR),,$(ABS_STARTING_DIR))
TEST_DIR := $(ROOT_DIR)/.build/test BUILD_DIR := $(ROOT_DIR)/.build
TEST_DIR := $(BUILD_DIR)/test
ERROR_FILE := $(BUILD_DIR)/error_occured
MAKEFILE_INCLUDED=yes MAKEFILE_INCLUDED=yes
@ -460,8 +462,21 @@ endef
include $(ROOT_DIR)/message.mk include $(ROOT_DIR)/message.mk
RUN_COMMAND = \ # The empty line is important here, as it will force a new shell to be created for each command
$(COMMAND_$(SILENT_MODE)_$(COMMAND)) # Otherwise the command line will become too long with a lot of keyboards and keymaps
define RUN_COMMAND
+error_occured=0;\
$(COMMAND_$(SILENT_MODE)_$(COMMAND))\
if [ $$error_occured -gt 0 ]; then echo $$error_occured > $(ERROR_FILE); fi;
endef
define RUN_TEST
+error_occured=0;\
$($(TEST)_COMMAND))\
if [ $$error_occured -gt 0 ]; then echo $$error_occured > $(ERROR_FILE); fi;
endef
# Allow specifying just the subproject, in the keyboard directory, which will compile all keymaps # Allow specifying just the subproject, in the keyboard directory, which will compile all keymaps
SUBPROJECTS := $(notdir $(patsubst %/Makefile,%,$(wildcard ./*/Makefile))) SUBPROJECTS := $(notdir $(patsubst %/Makefile,%,$(wildcard ./*/Makefile)))
@ -481,17 +496,17 @@ $(SUBPROJECTS): %: %-allkm
*) printf "$(MSG_SUBMODULE_DIRTY)";break;; \ *) printf "$(MSG_SUBMODULE_DIRTY)";break;; \
esac \ esac \
done done
rm -f $(ERROR_FILE) > /dev/null 2>&1
$(eval $(call PARSE_RULE,$@)) $(eval $(call PARSE_RULE,$@))
$(eval $(call SET_SILENT_MODE)) $(eval $(call SET_SILENT_MODE))
# Run all the commands in the same shell, notice the + at the first line # Run all the commands in the same shell, notice the + at the first line
# it has to be there to allow parallel execution of the submake # it has to be there to allow parallel execution of the submake
# This always tries to compile everything, even if error occurs in the middle # This always tries to compile everything, even if error occurs in the middle
# But we return the error code at the end, to trigger travis failures # But we return the error code at the end, to trigger travis failures
+error_occured=0; \ $(foreach COMMAND,$(COMMANDS),$(RUN_COMMAND))
$(foreach COMMAND,$(COMMANDS),$(RUN_COMMAND)) \ if [ -f $(ERROR_FILE) ]; then printf "$(MSG_ERRORS)" & exit 1; fi;
if [ $$error_occured -gt 0 ]; then printf "$(MSG_ERRORS)" & exit $$error_occured; fi;\ $(foreach TEST,$(TESTS),$(RUN_TEST))
$(foreach TEST,$(TESTS),$($(TEST)_COMMAND)) \ if [ -f $(ERROR_FILE) ]; then printf "$(MSG_ERRORS)" & exit 1; fi;
if [ $$error_occured -gt 0 ]; then printf "$(MSG_ERRORS)" & exit $$error_occured; fi;\
# All should compile everything # All should compile everything
.PHONY: all .PHONY: all

View File

@ -5,24 +5,24 @@
#include "action_layer.h" #include "action_layer.h"
#ifdef AUDIO_ENABLE #ifdef AUDIO_ENABLE
#include "audio.h" #include "audio.h"
#include "musical_notes.h"
#endif #endif
#include "eeconfig.h" #include "eeconfig.h"
#include "process_unicode.h" #include "process_unicode.h"
#include "quantum.h"
extern keymap_config_t keymap_config; extern keymap_config_t keymap_config;
// Each layer gets a name for readability, which is then used in the keymap matrix below. enum layers {
// The underscores don't mean anything - you can have a layer called STUFF or any other name. _QWERTY,
// Layer names don't all need to be of the same length, obviously, and you can also skip them _COLEMAK,
// entirely and just use numbers. _WORKMAN,
#define _QWERTY 0 _PUNC,
#define _COLEMAK 1 _NUM,
#define _WORKMAN 2 _FUNC,
#define _PUNC 9 _EMOJI,
#define _NUM 10 _GUI,
#define _FUNC 11 };
#define _EMOJI 12
#define _ADJUST 16
enum planck_keycodes { enum planck_keycodes {
// layouts // layouts
@ -35,6 +35,7 @@ enum planck_keycodes {
NUM, NUM,
FUNC, FUNC,
EMOJI, EMOJI,
GUI,
// os switchers // os switchers
LINUX, LINUX,
@ -43,10 +44,12 @@ enum planck_keycodes {
}; };
// Fillers to make layering clearer // Fillers to make layering clearer
#define _______ KC_TRNS #define _______ KC_TRNS
#define XXXXXXX KC_NO #define XXXXXXX KC_NO
// unicode map // unicode map
enum unicode_name { enum unicode_name {
GRIN, // grinning face 😊 GRIN, // grinning face 😊
TJOY, // tears of joy 😂 TJOY, // tears of joy 😂
@ -147,6 +150,18 @@ const uint32_t PROGMEM unicode_map[] = {
[SKULL] = 0x1F480, [SKULL] = 0x1F480,
}; };
// hybrid shift - =
// #undef KC_LSFT
// #define KC_LSFT MT(MOD_LSFT, KC_MINS)
// #undef KC_RSFT
// #define KC_RSFT MT(MOD_LSFT, KC_EQL)
// hybrid right-gui & scroll lock (mapped to Compose in OS)
#undef KC_RCTL
#define KC_RCTL MT(MOD_LCTL, KC_SLCK)
// keymaps // keymaps
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
@ -189,11 +204,11 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Workman /* Workman
* ,-----------------------------------------------------------------------------------. * ,-----------------------------------------------------------------------------------.
* | Tab | Q | W | F | P | G | J | L | U | Y | ; | Bksp | * | Tab | Q | D | R | W | B | J | F | U | P | ; | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------| * |------+------+------+------+------+-------------+------+------+------+------+------|
* | Esc | A | R | S | T | D | H | N | E | I | O |Enter | * | Esc | A | S | H | T | G | Y | N | E | O | I |Enter |
* |------+------+------+------+------+------|------+------+------+------+------+------| * |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| Z | X | C | V | B | K | M | , | . | / |Shift | * | Shift| Z | X | M | C | V | K | K | , | . | / |Shift |
* |------+------+------+------+------+------+------+------+------+------+------+------| * |------+------+------+------+------+------+------+------+------+------+------+------|
* | Ctrl | GUI | Alt | Punc | Num | Space | Func |Emoji |AltGr | GUI | Ctrl | * | Ctrl | GUI | Alt | Punc | Num | Space | Func |Emoji |AltGr | GUI | Ctrl |
* `-----------------------------------------------------------------------------------' * `-----------------------------------------------------------------------------------'
@ -207,56 +222,56 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Punc /* Punc
* ,-----------------------------------------------------------------------------------. * ,-----------------------------------------------------------------------------------.
* | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Bksp | * | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | ` |
* |------+------+------+------+------+-------------+------+------+------+------+------| * |------+------+------+------+------+-------------+------+------+------+------+------|
* | ` | | | | | | | | _ | + | { | } | " | * | | | \ | - | = | < | > | ( | ) | ' | | |
* |------+------+------+------+------+------|------+------+------+------+------+------| * |------+------+------+------+------+------|------+------+------+------+------+------|
* | | | | | | | \ | - | = | [ | ] | ' | * | | | | | _ | + | { | } | [ | ] | " | | |
* |------+------+------+------+------+------+------+------+------+------+------+------| * |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | < | > | | * | | | | | | | | | | | |
* `-----------------------------------------------------------------------------------' * `-----------------------------------------------------------------------------------'
*/ */
[_PUNC] = { [_PUNC] = {
{KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC}, {KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_GRV },
{KC_GRV, _______, _______, _______, _______, _______, KC_PIPE, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_DQUO}, {XXXXXXX, XXXXXXX, KC_BSLS, KC_MINS, KC_EQL, KC_LABK, KC_RABK, KC_LPRN, KC_RPRN, KC_QUOT, XXXXXXX, XXXXXXX},
{_______, _______, _______, _______, _______, _______, KC_BSLS, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_QUOT}, {XXXXXXX, XXXXXXX, KC_PIPE, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_LBRC, KC_RBRC, KC_DQUO, XXXXXXX, XXXXXXX},
{_______, _______, _______, _______, _______, KC_SPC, KC_SPC, _______, _______, KC_LABK, KC_RABK, _______} {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
}, },
/* Num /* Num
* ,-----------------------------------------------------------------------------------. * ,-----------------------------------------------------------------------------------.
* | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp | * | ^ | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------| * |------+------+------+------+------+-------------+------+------+------+------+------|
* | Esc | @ | A | B | C | [ | ] | 4 | 5 | 6 | : |Enter | * | Esc | @ | A | B | C | ( | ) | 4 | 5 | 6 | : |Enter |
* |------+------+------+------+------+------|------+------+------+------+------+------| * |------+------+------+------+------+------|------+------+------+------+------+------|
* | | | D | E | F | & | # | 1 | 2 | 3 | | | * | & | # | D | E | F | [ | ] | 1 | 2 | 3 | / | * |
* |------+------+------+------+------+------+------+------+------+------+------+------| * |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | x | | | | 0 | , | . | | | * | | | | x | | | 0 | , | . | + | - |
* `-----------------------------------------------------------------------------------' * `-----------------------------------------------------------------------------------'
*/ */
[_NUM] = { [_NUM] = {
{_______, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC}, {KC_CIRC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC},
{ KC_ESC, KC_AT, S(KC_A), S(KC_B), S(KC_C), KC_LBRC, KC_RBRC, KC_4, KC_5, KC_6, KC_COLN, KC_BSLS}, { KC_ESC, KC_AT, S(KC_A), S(KC_B), S(KC_C), KC_LPRN, KC_RPRN, KC_4, KC_5, KC_6, KC_COLN, KC_ENT},
{_______, _______, S(KC_D), S(KC_E), S(KC_F), KC_AMPR, KC_HASH, KC_1, KC_2, KC_3, _______, _______}, {KC_AMPR, KC_HASH, S(KC_D), S(KC_E), S(KC_F), KC_LBRC, KC_RBRC, KC_1, KC_2, KC_3, KC_SLSH, KC_ASTR},
{_______, _______, KC_X, _______, _______, KC_SPC, KC_SPC, KC_0, KC_COMM,KC_KP_DOT,_______, _______} {_______, _______, _______, KC_X, _______, KC_SPC, KC_SPC, KC_0, KC_COMM, KC_DOT, KC_PLUS, KC_MINS}
}, },
/* Func /* Func
* ,-----------------------------------------------------------------------------------. * ,-----------------------------------------------------------------------------------.
* | | F1 | F2 | F3 | F4 | | | PgUp | Up | PgDn | PgUp | Bksp | * | | F1 | F2 | F3 | F4 | | | PgUp | Up | PgDn | PgUp | Del |
* |------+------+------+------+------+-------------+------+------+------+------+------| * |------+------+------+------+------+-------------+------+------+------+------+------|
* | | F5 | F6 | F7 | F8 | | | Left | Down | Right| PgDn | | * | | F5 | F6 | F7 | F8 |PrtSc | | Left | Down | Right| PgDn | Ins |
* |------+------+------+------+------+------|------+------+------+------+------+------| * |------+------+------+------+------+------|------+------+------+------+------+------|
* | | F9 | F10 | F11 | F12 | | | | Home | End | | | * | | F9 | F10 | F11 | F12 | | | | Home | End | | |
* |------+------+------+------+------+------+------+------+------+------+------+------| * |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | | |Print | * | | | | | | | | | | | |
* `-----------------------------------------------------------------------------------' * `-----------------------------------------------------------------------------------'
*/ */
[_FUNC] = { [_FUNC] = {
{_______, KC_F1, KC_F2, KC_F3, KC_F4, _______, _______, KC_PGUP, KC_UP, KC_PGDN, KC_PGUP, KC_BSPC}, {XXXXXXX, KC_F1, KC_F2, KC_F3, KC_F4, XXXXXXX, XXXXXXX, KC_PGUP, KC_UP, KC_PGDN, KC_PGUP, KC_DEL},
{_______, KC_F5, KC_F6, KC_F7, KC_F8, _______, _______, KC_LEFT, KC_DOWN, KC_RGHT, KC_PGDN, _______}, {XXXXXXX, KC_F5, KC_F6, KC_F7, KC_F8,KC_PSCREEN,XXXXXXX, KC_LEFT, KC_DOWN, KC_RGHT, KC_PGDN, KC_INS},
{_______, KC_F9, KC_F10, KC_F11, KC_F12, _______, _______, _______, KC_HOME, KC_END, _______, _______}, {_______, KC_F9, KC_F10, KC_F11, KC_F12, XXXXXXX, XXXXXXX, XXXXXXX, KC_HOME, KC_END, XXXXXXX, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______,_______,KC_PSCREEN} {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
}, },
/* Emoji /* Emoji
@ -274,27 +289,26 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
{X(HART2), X(CRY2),X(WEARY),X(EYERT),X(SMIRK), X(TJOY),X(RECYC),X(UNAMU),X(MUSIC),X(OKHND),X(PENSV), X(PHEW)}, {X(HART2), X(CRY2),X(WEARY),X(EYERT),X(SMIRK), X(TJOY),X(RECYC),X(UNAMU),X(MUSIC),X(OKHND),X(PENSV), X(PHEW)},
{X(THMUP), X(PRAY),X(SMILE),X(SMIL2),X(FLUSH), X(GRIN),X(HEART), X(BYE), X(KISS),X(CELEB), X(COOL),X(NOEVS)}, {X(THMUP), X(PRAY),X(SMILE),X(SMIL2),X(FLUSH), X(GRIN),X(HEART), X(BYE), X(KISS),X(CELEB), X(COOL),X(NOEVS)},
{X(THMDN),X(SLEEP), X(CLAP), X(CRY), X(VIC),X(BHART), X(SUN),X(SMEYE), X(WINK), X(MOON),X(CONFU),X(NOEVH)}, {X(THMDN),X(SLEEP), X(CLAP), X(CRY), X(VIC),X(BHART), X(SUN),X(SMEYE), X(WINK), X(MOON),X(CONFU),X(NOEVH)},
{ X(POO), X(EYES),X(HUNRD),X(TONGU),X(SKULL),X(HORNS), X(HALO), X(FEAR), _______,X(YUMMY),X(DISAP),X(NOEVK)} { X(POO), X(EYES),X(HUNRD), _______,X(SKULL),X(HORNS), X(HALO), X(FEAR), _______,X(YUMMY),X(DISAP),X(NOEVK)}
}, },
/* Adjust /* GUI
* ,-----------------------------------------------------------------------------------. * ,-----------------------------------------------------------------------------------.
* | | |Linux | Win | OSX | | |Qwerty|Colemk|Workmm| | | * | | D1 | D2 | D3 | D4 | D5 | D6 | D7 | D8 | D9 | D10 | |
* |------+------+------+------+------+-------------+------+------+------+------+------| * |------+------+------+------+------+-------------+------+------+------+------+------|
* | | | | | | | | | | | | | * |Linux | | Vol- | Mute | Vol+ | | | D- | | D+ | |Qwerty|
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | | | | | | | | | | | | |
* |------+------+------+------+------+------+------+------+------+------+------+------| * |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | | | | * | Win | | Prev | Play | Next | | | | | | |Colmak|
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | OSX | | | | | BL- | BL+ | | | | |Workmn|
* `-----------------------------------------------------------------------------------' * `-----------------------------------------------------------------------------------'
*/ */
[_ADJUST] = { [_GUI] = {
{_______, _______, LINUX, WIN, OSX, _______, _______, QWERTY, COLEMAK, WORKMAN, _______, _______}, {_______, LGUI(KC_1),LGUI(KC_2),LGUI(KC_3),LGUI(KC_4),LGUI(KC_5),LGUI(KC_6),LGUI(KC_7),LGUI(KC_8),LGUI(KC_9),LGUI(KC_0), _______},
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}, { LINUX, _______, KC_VOLD, KC_MUTE, KC_VOLU,_______,_______,KC_WWW_BACK,_______,KC_WWW_FORWARD,_______, QWERTY},
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}, { WIN, _______, KC_MPRV, KC_MPLY, KC_MNXT, _______, _______, _______, _______, _______, _______, COLEMAK},
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______} { OSX, _______, _______, _______, _______, BL_DEC, BL_INC, _______, _______, _______, _______, WORKMAN}
} },
}; };
@ -304,6 +318,10 @@ float tone_qwerty[][2] = SONG(QWERTY_SOUND);
float tone_colemak[][2] = SONG(COLEMAK_SOUND); float tone_colemak[][2] = SONG(COLEMAK_SOUND);
float tone_workman[][2] = SONG(DVORAK_SOUND); float tone_workman[][2] = SONG(DVORAK_SOUND);
float tone_goodbye[][2] = SONG(GOODBYE_SOUND); float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
float tone_linux[][2] = SONG(CAPS_LOCK_ON_SOUND);
float tone_windows[][2] = SONG(SCROLL_LOCK_ON_SOUND);
float tone_osx[][2] = SONG(NUM_LOCK_ON_SOUND);
float tone_click[][2] = SONG(MUSICAL_NOTE(_F3, 2));
#endif #endif
void persistant_default_layer_set(uint16_t default_layer) { void persistant_default_layer_set(uint16_t default_layer) {
@ -312,6 +330,9 @@ void persistant_default_layer_set(uint16_t default_layer) {
} }
bool process_record_user(uint16_t keycode, keyrecord_t *record) { bool process_record_user(uint16_t keycode, keyrecord_t *record) {
// faux clicky
if (record->event.pressed) PLAY_NOTE_ARRAY(tone_click, false, 0);
switch (keycode) { switch (keycode) {
case QWERTY: case QWERTY:
if (record->event.pressed) { if (record->event.pressed) {
@ -343,20 +364,20 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
case PUNC: case PUNC:
if (record->event.pressed) { if (record->event.pressed) {
layer_on(_PUNC); layer_on(_PUNC);
update_tri_layer(_PUNC, _EMOJI, _ADJUST); update_tri_layer(_PUNC, _EMOJI, _GUI);
} else { } else {
layer_off(_PUNC); layer_off(_PUNC);
update_tri_layer(_PUNC, _EMOJI, _ADJUST); update_tri_layer(_PUNC, _EMOJI, _GUI);
} }
return false; return false;
break; break;
case EMOJI: case EMOJI:
if (record->event.pressed) { if (record->event.pressed) {
layer_on(_EMOJI); layer_on(_EMOJI);
update_tri_layer(_PUNC, _EMOJI, _ADJUST); update_tri_layer(_PUNC, _EMOJI, _GUI);
} else { } else {
layer_off(_EMOJI); layer_off(_EMOJI);
update_tri_layer(_PUNC, _EMOJI, _ADJUST); update_tri_layer(_PUNC, _EMOJI, _GUI);
} }
return false; return false;
break; break;
@ -378,14 +399,23 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
break; break;
case LINUX: case LINUX:
set_unicode_input_mode(UC_LNX); set_unicode_input_mode(UC_LNX);
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_linux, false, 0);
#endif
return false; return false;
break; break;
case WIN: case WIN:
set_unicode_input_mode(UC_WIN); set_unicode_input_mode(UC_WINC);
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_windows, false, 0);
#endif
return false; return false;
break; break;
case OSX: case OSX:
set_unicode_input_mode(UC_OSX); set_unicode_input_mode(UC_OSX);
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_osx, false, 0);
#endif
return false; return false;
break; break;
} }

View File

@ -1 +1,11 @@
# Priyadi's Planck Layout # Priyadi's Planck Layout
Features:
- Supports QWERTY, Colemak and Workman layouts.
- Cursor and nav cluster on home row.
- Hybrid number row and numpad, located on home row.
- Number layer supports hexadecimal input.
- Left and right side modifiers.
- Emoji layer. An entire layer filled with common emojis.
- Faux-clickey (poor man's replacement for Cherry blue switches)

View File

@ -906,7 +906,7 @@ In `quantum/keymap_extras/`, you'll see various language files - these work the
## Unicode support ## Unicode support
You can currently send 4 hex digits with your OS-specific modifier key (RALT for OSX with the "Unicode Hex Input" layout) - this is currently limited to supporting one OS at a time, and requires a recompile for switching. 8 digit hex codes are being worked on. The keycode function is `UC(n)`, where *n* is a 4 digit hexidecimal. Enable from the Makefile. You can currently send 4 hex digits with your OS-specific modifier key (RALT for OSX with the "Unicode Hex Input" layout, see [this article](http://www.poynton.com/notes/misc/mac-unicode-hex-input.html) to learn more) - this is currently limited to supporting one OS at a time, and requires a recompile for switching. 8 digit hex codes are being worked on. The keycode function is `UC(n)`, where *n* is a 4 digit hexidecimal. Enable from the Makefile.
## Backlight Breathing ## Backlight Breathing