Merge remote-tracking branch 'upstream/master'

example_keyboards
Stick 8 years ago
commit fa96d64f37

5
.gitignore vendored

@ -34,3 +34,8 @@ CMakeLists.txt
util/Win_Check_Output.txt util/Win_Check_Output.txt
.vscode .vscode
.stfolder .stfolder
# ignore image files
*.png
*.jpg
*.gif

6
.gitmodules vendored

@ -1,12 +1,12 @@
[submodule "lib/chibios"] [submodule "lib/chibios"]
path = lib/chibios path = lib/chibios
url = https://github.com/ChibiOS/ChibiOS.git url = https://github.com/qmk/ChibiOS
[submodule "lib/chibios-contrib"] [submodule "lib/chibios-contrib"]
path = lib/chibios-contrib path = lib/chibios-contrib
url = https://github.com/ChibiOS/ChibiOS-Contrib.git url = https://github.com/qmk/ChibiOS-Contrib
[submodule "lib/ugfx"] [submodule "lib/ugfx"]
path = lib/ugfx path = lib/ugfx
url = https://bitbucket.org/Tectu/ugfx url = https://github.com/qmk/uGFX
[submodule "lib/googletest"] [submodule "lib/googletest"]
path = lib/googletest path = lib/googletest
url = https://github.com/google/googletest url = https://github.com/google/googletest

@ -1,6 +1,7 @@
os: linux os: linux
dist: trusty dist: trusty
sudo: required sudo: required
group: edge
language: c language: c
branches: branches:
except: except:

@ -419,7 +419,7 @@ define BUILD_TEST
MAKE_TARGET := $2 MAKE_TARGET := $2
COMMAND := $1 COMMAND := $1
MAKE_CMD := $$(MAKE) -r -R -C $(ROOT_DIR) -f build_test.mk $$(MAKE_TARGET) MAKE_CMD := $$(MAKE) -r -R -C $(ROOT_DIR) -f build_test.mk $$(MAKE_TARGET)
MAKE_VARS := TEST=$$(TEST_NAME) MAKE_VARS := TEST=$$(TEST_NAME) FULL_TESTS=$$(FULL_TESTS)
MAKE_MSG := $$(MSG_MAKE_TEST) MAKE_MSG := $$(MSG_MAKE_TEST)
$$(eval $$(call BUILD)) $$(eval $$(call BUILD))
ifneq ($$(MAKE_TARGET),clean) ifneq ($$(MAKE_TARGET),clean)

@ -1,6 +1,7 @@
{ {
"structure": { "structure": {
"readme": "Home.md" "readme": "home.md",
"summary": "_summary.md"
}, },
"plugins" : ["toolbar", "edit-link", "anchors"], "plugins" : ["toolbar", "edit-link", "anchors"],
"pluginsConfig": { "pluginsConfig": {

@ -0,0 +1,30 @@
# Copyright 2017 Fred Sundvik
#
# 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, either version 2 of the License, or
# (at your option) any later version.
#
# 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 $(TMK_PATH)/protocol.mk
TEST_PATH=tests/$(TEST)
$(TEST)_SRC= \
$(TEST_PATH)/test.cpp \
$(TMK_COMMON_SRC) \
$(QUANTUM_SRC) \
tests/test_common/matrix.c \
tests/test_common/test_driver.cpp \
tests/test_common/keyboard_report_util.cpp \
tests/test_common/test_fixture.cpp
$(TEST)_DEFS=$(TMK_COMMON_DEFS)
$(TEST)_CONFIG=$(TEST_PATH)/config.h
VPATH+=$(TOP_DIR)/tests/test_common

@ -31,8 +31,6 @@ $(error MASTER does not have a valid value(left/right))
endif endif
endif endif
KEYBOARD_PATH := keyboards/$(KEYBOARD) KEYBOARD_PATH := keyboards/$(KEYBOARD)
KEYBOARD_C := $(KEYBOARD_PATH)/$(KEYBOARD).c KEYBOARD_C := $(KEYBOARD_PATH)/$(KEYBOARD).c
@ -42,7 +40,6 @@ else
$(error "$(KEYBOARD_C)" does not exist) $(error "$(KEYBOARD_C)" does not exist)
endif endif
ifneq ($(SUBPROJECT),) ifneq ($(SUBPROJECT),)
SUBPROJECT_PATH := keyboards/$(KEYBOARD)/$(SUBPROJECT) SUBPROJECT_PATH := keyboards/$(KEYBOARD)/$(SUBPROJECT)
SUBPROJECT_C := $(SUBPROJECT_PATH)/$(SUBPROJECT).c SUBPROJECT_C := $(SUBPROJECT_PATH)/$(SUBPROJECT).c
@ -118,139 +115,12 @@ endif
# # project specific files # # project specific files
SRC += $(KEYBOARD_C) \ SRC += $(KEYBOARD_C) \
$(KEYMAP_C) \ $(KEYMAP_C) \
$(QUANTUM_DIR)/quantum.c \ $(QUANTUM_SRC)
$(QUANTUM_DIR)/keymap_common.c \
$(QUANTUM_DIR)/keycode_config.c \
$(QUANTUM_DIR)/process_keycode/process_leader.c
ifneq ($(SUBPROJECT),) ifneq ($(SUBPROJECT),)
SRC += $(SUBPROJECT_C) SRC += $(SUBPROJECT_C)
endif endif
ifndef CUSTOM_MATRIX
SRC += $(QUANTUM_DIR)/matrix.c
endif
ifeq ($(strip $(API_SYSEX_ENABLE)), yes)
OPT_DEFS += -DAPI_SYSEX_ENABLE
SRC += $(QUANTUM_DIR)/api/api_sysex.c
OPT_DEFS += -DAPI_ENABLE
SRC += $(QUANTUM_DIR)/api.c
MIDI_ENABLE=yes
endif
MUSIC_ENABLE := 0
ifeq ($(strip $(AUDIO_ENABLE)), yes)
OPT_DEFS += -DAUDIO_ENABLE
MUSIC_ENABLE := 1
SRC += $(QUANTUM_DIR)/process_keycode/process_audio.c
SRC += $(QUANTUM_DIR)/audio/audio.c
SRC += $(QUANTUM_DIR)/audio/voices.c
SRC += $(QUANTUM_DIR)/audio/luts.c
endif
ifeq ($(strip $(MIDI_ENABLE)), yes)
OPT_DEFS += -DMIDI_ENABLE
MUSIC_ENABLE := 1
SRC += $(QUANTUM_DIR)/process_keycode/process_midi.c
endif
ifeq ($(MUSIC_ENABLE), 1)
SRC += $(QUANTUM_DIR)/process_keycode/process_music.c
endif
ifeq ($(strip $(COMBO_ENABLE)), yes)
OPT_DEFS += -DCOMBO_ENABLE
SRC += $(QUANTUM_DIR)/process_keycode/process_combo.c
endif
ifeq ($(strip $(VIRTSER_ENABLE)), yes)
OPT_DEFS += -DVIRTSER_ENABLE
endif
ifeq ($(strip $(FAUXCLICKY_ENABLE)), yes)
OPT_DEFS += -DFAUXCLICKY_ENABLE
SRC += $(QUANTUM_DIR)/fauxclicky.c
endif
ifeq ($(strip $(UCIS_ENABLE)), yes)
OPT_DEFS += -DUCIS_ENABLE
UNICODE_COMMON = yes
SRC += $(QUANTUM_DIR)/process_keycode/process_ucis.c
endif
ifeq ($(strip $(UNICODEMAP_ENABLE)), yes)
OPT_DEFS += -DUNICODEMAP_ENABLE
UNICODE_COMMON = yes
SRC += $(QUANTUM_DIR)/process_keycode/process_unicodemap.c
endif
ifeq ($(strip $(UNICODE_ENABLE)), yes)
OPT_DEFS += -DUNICODE_ENABLE
UNICODE_COMMON = yes
SRC += $(QUANTUM_DIR)/process_keycode/process_unicode.c
endif
ifeq ($(strip $(UNICODE_COMMON)), yes)
SRC += $(QUANTUM_DIR)/process_keycode/process_unicode_common.c
endif
ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
OPT_DEFS += -DRGBLIGHT_ENABLE
SRC += $(QUANTUM_DIR)/light_ws2812.c
SRC += $(QUANTUM_DIR)/rgblight.c
CIE1931_CURVE = yes
LED_BREATHING_TABLE = yes
endif
ifeq ($(strip $(TAP_DANCE_ENABLE)), yes)
OPT_DEFS += -DTAP_DANCE_ENABLE
SRC += $(QUANTUM_DIR)/process_keycode/process_tap_dance.c
endif
ifeq ($(strip $(PRINTING_ENABLE)), yes)
OPT_DEFS += -DPRINTING_ENABLE
SRC += $(QUANTUM_DIR)/process_keycode/process_printer.c
SRC += $(TMK_DIR)/protocol/serial_uart.c
endif
ifeq ($(strip $(SERIAL_LINK_ENABLE)), yes)
SRC += $(patsubst $(QUANTUM_PATH)/%,%,$(SERIAL_SRC))
OPT_DEFS += $(SERIAL_DEFS)
VAPTH += $(SERIAL_PATH)
endif
ifneq ($(strip $(VARIABLE_TRACE)),)
SRC += $(QUANTUM_DIR)/variable_trace.c
OPT_DEFS += -DNUM_TRACED_VARIABLES=$(strip $(VARIABLE_TRACE))
ifneq ($(strip $(MAX_VARIABLE_TRACE_SIZE)),)
OPT_DEFS += -DMAX_VARIABLE_TRACE_SIZE=$(strip $(MAX_VARIABLE_TRACE_SIZE))
endif
endif
ifeq ($(strip $(LCD_ENABLE)), yes)
CIE1931_CURVE = yes
endif
ifeq ($(strip $(LED_ENABLE)), yes)
CIE1931_CURVE = yes
endif
ifeq ($(strip $(CIE1931_CURVE)), yes)
OPT_DEFS += -DUSE_CIE1931_CURVE
LED_TABLES = yes
endif
ifeq ($(strip $(LED_BREATHING_TABLE)), yes)
OPT_DEFS += -DUSE_LED_BREATHING_TABLE
LED_TABLES = yes
endif
ifeq ($(strip $(LED_TABLES)), yes)
SRC += $(QUANTUM_DIR)/led_tables.c
endif
# Optimize size but this may cause error "relocation truncated to fit" # Optimize size but this may cause error "relocation truncated to fit"
#EXTRALDFLAGS = -Wl,--relax #EXTRALDFLAGS = -Wl,--relax
@ -262,9 +132,10 @@ endif
VPATH += $(KEYBOARD_PATH) VPATH += $(KEYBOARD_PATH)
VPATH += $(COMMON_VPATH) VPATH += $(COMMON_VPATH)
include common_features.mk
include $(TMK_PATH)/protocol.mk include $(TMK_PATH)/protocol.mk
include $(TMK_PATH)/common.mk include $(TMK_PATH)/common.mk
SRC += $(TMK_COMMON_SRC) SRC += $(TMK_COMMON_SRC)
OPT_DEFS += $(TMK_COMMON_DEFS) OPT_DEFS += $(TMK_COMMON_DEFS)
EXTRALDFLAGS += $(TMK_COMMON_LDFLAGS) EXTRALDFLAGS += $(TMK_COMMON_LDFLAGS)

@ -40,13 +40,23 @@ VPATH +=\
all: elf all: elf
VPATH += $(COMMON_VPATH) VPATH += $(COMMON_VPATH)
PLATFORM:=TEST
ifneq ($(filter $(FULL_TESTS),$(TEST)),)
include tests/$(TEST)/rules.mk
endif
include common_features.mk
include $(TMK_PATH)/common.mk include $(TMK_PATH)/common.mk
include $(QUANTUM_PATH)/serial_link/tests/rules.mk include $(QUANTUM_PATH)/serial_link/tests/rules.mk
ifneq ($(filter $(FULL_TESTS),$(TEST)),)
include build_full_test.mk
endif
$(TEST_OBJ)/$(TEST)_SRC := $($(TEST)_SRC) $(TEST_OBJ)/$(TEST)_SRC := $($(TEST)_SRC)
$(TEST_OBJ)/$(TEST)_INC := $($(TEST)_INC) $(VPATH) $(GTEST_INC) $(TEST_OBJ)/$(TEST)_INC := $($(TEST)_INC) $(VPATH) $(GTEST_INC)
$(TEST_OBJ)/$(TEST)_DEFS := $($(TEST)_DEFS) $(TEST_OBJ)/$(TEST)_DEFS := $($(TEST)_DEFS)
$(TEST_OBJ)/$(TEST)_CONFIG := $($(TEST)_CONFIG)
include $(TMK_PATH)/native.mk include $(TMK_PATH)/native.mk
include $(TMK_PATH)/rules.mk include $(TMK_PATH)/rules.mk

@ -11,12 +11,6 @@ QUANTUM_PATH = $(TOP_DIR)/$(QUANTUM_DIR)
BUILD_DIR := $(TOP_DIR)/.build BUILD_DIR := $(TOP_DIR)/.build
SERIAL_DIR := $(QUANTUM_DIR)/serial_link
SERIAL_PATH := $(QUANTUM_PATH)/serial_link
SERIAL_SRC := $(wildcard $(SERIAL_PATH)/protocol/*.c)
SERIAL_SRC += $(wildcard $(SERIAL_PATH)/system/*.c)
SERIAL_DEFS += -DSERIAL_LINK_ENABLE
COMMON_VPATH := $(TOP_DIR) COMMON_VPATH := $(TOP_DIR)
COMMON_VPATH += $(TMK_PATH) COMMON_VPATH += $(TMK_PATH)
COMMON_VPATH += $(QUANTUM_PATH) COMMON_VPATH += $(QUANTUM_PATH)
@ -24,4 +18,3 @@ COMMON_VPATH += $(QUANTUM_PATH)/keymap_extras
COMMON_VPATH += $(QUANTUM_PATH)/audio COMMON_VPATH += $(QUANTUM_PATH)/audio
COMMON_VPATH += $(QUANTUM_PATH)/process_keycode COMMON_VPATH += $(QUANTUM_PATH)/process_keycode
COMMON_VPATH += $(QUANTUM_PATH)/api COMMON_VPATH += $(QUANTUM_PATH)/api
COMMON_VPATH += $(SERIAL_PATH)

@ -0,0 +1,153 @@
# Copyright 2017 Fred Sundvik
#
# 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, either version 2 of the License, or
# (at your option) any later version.
#
# 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/>.
SERIAL_DIR := $(QUANTUM_DIR)/serial_link
SERIAL_PATH := $(QUANTUM_PATH)/serial_link
SERIAL_SRC := $(wildcard $(SERIAL_PATH)/protocol/*.c)
SERIAL_SRC += $(wildcard $(SERIAL_PATH)/system/*.c)
SERIAL_DEFS += -DSERIAL_LINK_ENABLE
COMMON_VPATH += $(SERIAL_PATH)
ifeq ($(strip $(API_SYSEX_ENABLE)), yes)
OPT_DEFS += -DAPI_SYSEX_ENABLE
SRC += $(QUANTUM_DIR)/api/api_sysex.c
OPT_DEFS += -DAPI_ENABLE
SRC += $(QUANTUM_DIR)/api.c
MIDI_ENABLE=yes
endif
MUSIC_ENABLE := 0
ifeq ($(strip $(AUDIO_ENABLE)), yes)
OPT_DEFS += -DAUDIO_ENABLE
MUSIC_ENABLE := 1
SRC += $(QUANTUM_DIR)/process_keycode/process_audio.c
SRC += $(QUANTUM_DIR)/audio/audio.c
SRC += $(QUANTUM_DIR)/audio/voices.c
SRC += $(QUANTUM_DIR)/audio/luts.c
endif
ifeq ($(strip $(MIDI_ENABLE)), yes)
OPT_DEFS += -DMIDI_ENABLE
MUSIC_ENABLE := 1
SRC += $(QUANTUM_DIR)/process_keycode/process_midi.c
endif
ifeq ($(MUSIC_ENABLE), 1)
SRC += $(QUANTUM_DIR)/process_keycode/process_music.c
endif
ifeq ($(strip $(COMBO_ENABLE)), yes)
OPT_DEFS += -DCOMBO_ENABLE
SRC += $(QUANTUM_DIR)/process_keycode/process_combo.c
endif
ifeq ($(strip $(VIRTSER_ENABLE)), yes)
OPT_DEFS += -DVIRTSER_ENABLE
endif
ifeq ($(strip $(FAUXCLICKY_ENABLE)), yes)
OPT_DEFS += -DFAUXCLICKY_ENABLE
SRC += $(QUANTUM_DIR)/fauxclicky.c
endif
ifeq ($(strip $(UCIS_ENABLE)), yes)
OPT_DEFS += -DUCIS_ENABLE
UNICODE_COMMON = yes
SRC += $(QUANTUM_DIR)/process_keycode/process_ucis.c
endif
ifeq ($(strip $(UNICODEMAP_ENABLE)), yes)
OPT_DEFS += -DUNICODEMAP_ENABLE
UNICODE_COMMON = yes
SRC += $(QUANTUM_DIR)/process_keycode/process_unicodemap.c
endif
ifeq ($(strip $(UNICODE_ENABLE)), yes)
OPT_DEFS += -DUNICODE_ENABLE
UNICODE_COMMON = yes
SRC += $(QUANTUM_DIR)/process_keycode/process_unicode.c
endif
ifeq ($(strip $(UNICODE_COMMON)), yes)
SRC += $(QUANTUM_DIR)/process_keycode/process_unicode_common.c
endif
ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
OPT_DEFS += -DRGBLIGHT_ENABLE
SRC += $(QUANTUM_DIR)/light_ws2812.c
SRC += $(QUANTUM_DIR)/rgblight.c
CIE1931_CURVE = yes
LED_BREATHING_TABLE = yes
endif
ifeq ($(strip $(TAP_DANCE_ENABLE)), yes)
OPT_DEFS += -DTAP_DANCE_ENABLE
SRC += $(QUANTUM_DIR)/process_keycode/process_tap_dance.c
endif
ifeq ($(strip $(PRINTING_ENABLE)), yes)
OPT_DEFS += -DPRINTING_ENABLE
SRC += $(QUANTUM_DIR)/process_keycode/process_printer.c
SRC += $(TMK_DIR)/protocol/serial_uart.c
endif
ifeq ($(strip $(SERIAL_LINK_ENABLE)), yes)
SRC += $(patsubst $(QUANTUM_PATH)/%,%,$(SERIAL_SRC))
OPT_DEFS += $(SERIAL_DEFS)
VAPTH += $(SERIAL_PATH)
endif
ifneq ($(strip $(VARIABLE_TRACE)),)
SRC += $(QUANTUM_DIR)/variable_trace.c
OPT_DEFS += -DNUM_TRACED_VARIABLES=$(strip $(VARIABLE_TRACE))
ifneq ($(strip $(MAX_VARIABLE_TRACE_SIZE)),)
OPT_DEFS += -DMAX_VARIABLE_TRACE_SIZE=$(strip $(MAX_VARIABLE_TRACE_SIZE))
endif
endif
ifeq ($(strip $(LCD_ENABLE)), yes)
CIE1931_CURVE = yes
endif
ifeq ($(strip $(BACKLIGHT_ENABLE)), yes)
ifeq ($(strip $(VISUALIZER_ENABLE)), yes)
CIE1931_CURVE = yes
endif
endif
ifeq ($(strip $(CIE1931_CURVE)), yes)
OPT_DEFS += -DUSE_CIE1931_CURVE
LED_TABLES = yes
endif
ifeq ($(strip $(LED_BREATHING_TABLE)), yes)
OPT_DEFS += -DUSE_LED_BREATHING_TABLE
LED_TABLES = yes
endif
ifeq ($(strip $(LED_TABLES)), yes)
SRC += $(QUANTUM_DIR)/led_tables.c
endif
QUANTUM_SRC:= \
$(QUANTUM_DIR)/quantum.c \
$(QUANTUM_DIR)/keymap_common.c \
$(QUANTUM_DIR)/keycode_config.c \
$(QUANTUM_DIR)/process_keycode/process_leader.c
ifndef CUSTOM_MATRIX
QUANTUM_SRC += $(QUANTUM_DIR)/matrix.c
endif

@ -1,215 +0,0 @@
# Macro shortcuts: Send a whole string when pressing just one key
Instead of using the `ACTION_MACRO` function, you can simply use `M(n)` to access macro *n* - *n* will get passed into the `action_get_macro` as the `id`, and you can use a switch statement to trigger it. This gets called on the keydown and keyup, so you'll need to use an if statement testing `record->event.pressed` (see keymap_default.c).
```c
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) // this is the function signature -- just copy/paste it into your keymap file as it is.
{
switch(id) {
case 0: // this would trigger when you hit a key mapped as M(0)
if (record->event.pressed) {
return MACRO( I(255), T(H), T(E), T(L), T(L), W(255), T(O), END ); // this sends the string 'hello' when the macro executes
}
break;
}
return MACRO_NONE;
};
```
A macro can include the following commands:
* I() change interval of stroke in milliseconds.
* D() press key.
* U() release key.
* T() type key(press and release).
* W() wait (milliseconds).
* END end mark.
So above you can see the stroke interval changed to 255ms between each keystroke, then a bunch of keys being typed, waits a while, then the macro ends.
Note: Using macros to have your keyboard send passwords for you is possible, but a bad idea.
## Advanced macro functions
To get more control over the keys/actions your keyboard takes, the following functions are available to you in the `action_get_macro` function block:
* `record->event.pressed`
This is a boolean value that can be tested to see if the switch is being pressed or released. An example of this is
```c
if (record->event.pressed) {
// on keydown
} else {
// on keyup
}
```
* `register_code(<kc>);`
This sends the `<kc>` keydown event to the computer. Some examples would be `KC_ESC`, `KC_C`, `KC_4`, and even modifiers such as `KC_LSFT` and `KC_LGUI`.
* `unregister_code(<kc>);`
Parallel to `register_code` function, this sends the `<kc>` keyup event to the computer. If you don't use this, the key will be held down until it's sent.
* `layer_on(<n>);`
This will turn on the layer `<n>` - the higher layer number will always take priority. Make sure you have `KC_TRNS` for the key you're pressing on the layer you're switching to, or you'll get stick there unless you have another plan.
* `layer_off(<n>);`
This will turn off the layer `<n>`.
* `clear_keyboard();`
This will clear all mods and keys currently pressed.
* `clear_mods();`
This will clear all mods currently pressed.
* `clear_keyboard_but_mods();`
This will clear all keys besides the mods currently pressed.
* `update_tri_layer(layer_1, layer_2, layer_3);`
If the user attempts to activate layer 1 AND layer 2 at the same time (for example, by hitting their respective layer keys), layer 3 will be activated. Layers 1 and 2 will _also_ be activated, for the purposes of fallbacks (so a given key will fall back from 3 to 2, to 1 -- and only then to 0).
### Naming your macros
If you have a bunch of macros you want to refer to from your keymap, while keeping the keymap easily readable, you can just name them like so:
```
#define AUD_OFF M(6)
#define AUD_ON M(7)
#define MUS_OFF M(8)
#define MUS_ON M(9)
#define VC_IN M(10)
#define VC_DE M(11)
#define PLOVER M(12)
#define EXT_PLV M(13)
```
As was done on the [Planck default keymap](https://github.com/qmk/qmk_firmware/blob/master/keyboards/planck/keymaps/default/keymap.c#L33-L40)
#### Timer functionality
It's possible to start timers and read values for time-specific events - here's an example:
```c
static uint16_t key_timer;
key_timer = timer_read();
if (timer_elapsed(key_timer) < 100) {
// do something if less than 100ms have passed
} else {
// do something if 100ms or more have passed
}
```
It's best to declare the `static uint16_t key_timer;` outside of the macro block (top of file, etc).
### Example: Single-key copy/paste (hold to copy, tap to paste)
With QMK, it's easy to make one key do two things, as long as one of those things is being a modifier. :) So if you want a key to act as Ctrl when held and send the letter R when tapped, that's easy: `CTL_T(KC_R)`. But what do you do when you want that key to send Ctrl-V (paste) when tapped, and Ctrl-C (copy) when held?
Here's what you do:
```
static uint16_t key_timer;
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
switch(id) {
case 0: {
if (record->event.pressed) {
key_timer = timer_read(); // if the key is being pressed, we start the timer.
}
else { // this means the key was just released, so we can figure out how long it was pressed for (tap or "held down").
if (timer_elapsed(key_timer) > 150) { // 150 being 150ms, the threshhold we pick for counting something as a tap.
return MACRO( D(LCTL), T(C), U(LCTL), END );
}
else {
return MACRO( D(LCTL), T(V), U(LCTL), END );
}
}
break;
}
}
return MACRO_NONE;
};
```
And then, to assign this macro to a key on your keyboard layout, you just use `M(0)` on the key you want to press for copy/paste.
# Dynamic macros: record and replay macros in runtime
In addition to the static macros described above, you may enable the dynamic macros which you may record while writing. They are forgotten as soon as the keyboard is unplugged. Only two such macros may be stored at the same time, with the total length of 64 keypresses (by default).
To enable them, first add a new element to the `planck_keycodes` enum — `DYNAMIC_MACRO_RANGE`:
enum planck_keycodes {
QWERTY = SAFE_RANGE,
COLEMAK,
DVORAK,
PLOVER,
LOWER,
RAISE,
BACKLIT,
EXT_PLV,
DYNAMIC_MACRO_RANGE,
};
It must be the last element because `dynamic_macros.h` will add some more keycodes after it.
Below it include the `dynamic_macro.h` header:
#include "dynamic_macro.h"`
Add the following keys to your keymap:
- `DYN_REC_START1` — start recording the macro 1,
- `DYN_REC_START2` — start recording the macro 2,
- `DYN_MACRO_PLAY1` — replay the macro 1,
- `DYN_MACRO_PLAY2` — replay the macro 2,
- `DYN_REC_STOP` — finish the macro that is currently being recorded.
Add the following code to the very beginning of your `process_record_user()` function:
if (!process_record_dynamic_macro(keycode, record)) {
return false;
}
That should be everything necessary. To start recording the macro, press either `DYN_REC_START1` or `DYN_REC_START2`. To finish the recording, press the `DYN_REC_STOP` layer button. To replay the macro, press either `DYN_MACRO_PLAY1` or `DYN_MACRO_PLAY2`.
Note that it's possible to replay a macro as part of a macro. It's ok to replay macro 2 while recording macro 1 and vice versa but never create recursive macros i.e. macro 1 that replays macro 1. If you do so and the keyboard will get unresponsive, unplug the keyboard and plug it again.
For users of the earlier versions of dynamic macros: It is still possible to finish the macro recording using just the layer modifier used to access the dynamic macro keys, without a dedicated `DYN_REC_STOP` key. If you want this behavior back, use the following snippet instead of the one above:
uint16_t macro_kc = (keycode == MO(_DYN) ? DYN_REC_STOP : keycode);
if (!process_record_dynamic_macro(macro_kc, record)) {
return false;
}
If the LED-s start blinking during the recording with each keypress, it means there is no more space for the macro in the macro buffer. To fit the macro in, either make the other macro shorter (they share the same buffer) or increase the buffer size by setting the `DYNAMIC_MACRO_SIZE` preprocessor macro (default value: 128; please read the comments for it in the header).
For the details about the internals of the dynamic macros, please read the comments in the `dynamic_macro.h` header.
# Sending strings
Some people want to have a password or some text on a key. This is possible without having to do every key individually using `SEND_STRING("<text>");`. Note the caps, because `send_string("<text>");` does something else. For example:
```c
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) // this is the function signature -- just copy/paste it into your keymap file as it is.
{
switch(id) {
case 0: // this would trigger when you hit a key mapped as M(0)
if (record->event.pressed) {
SEND_STRING("QMK is the best thing ever!"); // This would type "QMK is the best thing ever!" (without quotation marks).
return false; // This is false because it has to return something.
}
break;
}
return MACRO_NONE;
};
```
If you'd want it to press enter as well, just replace `return false;` with `return MACRO( T(ENT), END );`.

@ -1,62 +0,0 @@
Keyboard Firmware Projects other than TMK
================================
## PJRC USB Keyboard/Mouse Example[USB][PJRC][Teensy][AVR]
- <http://www.pjrc.com/teensy/usb_keyboard.html>
- <http://www.pjrc.com/teensy/usb_mouse.html>
## kbupgrade[USB][V-USB][AVR]
- <http://github.com/rhomann/kbupgrade>
- <http://geekhack.org/showwiki.php?title=Island:8406>
## c64key[USB][V-USB][AVR]
- <http://symlink.dk/projects/c64key/>
## rump[USB][V-USB][AVR]
- <http://mg8.org/rump/>
- <http://github.com/clee/rump>
## dulcimer[USB][V-USB][AVR]
- <http://www.schatenseite.de/dulcimer.html>
## humblehacker-keyboard[USB][LUFA][AVR][Ergo]
- <http://github.com/humblehacker>
- <http://www.humblehacker.com/keyboard/>
- <http://geekhack.org/showwiki.php?title=Island:6292>
## ps2avr[PS/2][AVR]
- <http://sourceforge.net/projects/ps2avr/>
## ErgoDox[Ergo][Split][USB][AVR]
- <http://geekhack.org/index.php?topic=22780.0>
- <https://github.com/benblazak/ergodox-firmware>
- <https://github.com/cub-uanic/tmk_keyboard>
## Suka's keyboard collection[Ergo][Split][3DPrinting][USB][AVR]
- <http://deskthority.net/workshop-f7/my-diy-keyboard-collection-or-how-i-became-a-kb-geek-t2534.html>
- <https://github.com/frobiac/adnw>
## bpiphany's AVR-Keyboard[PJRC][AVR][USB]
- <https://github.com/BathroomEpiphanies/AVR-Keyboard>
- <http://deskthority.net/wiki/HID_Liberation_Device_-_DIY_Instructions>
- <http://deskthority.net/wiki/Phantom>
## USB-USB keyboard remapper[converter][USB-USB][AVR][Arduino]
- <http://forum.colemak.com/viewtopic.php?pid=10837>
- <https://github.com/darkytoothpaste/keymapper>
## USB-USB converter threads[converter][USB-USB]
- <http://deskthority.net/workshop-f7/is-remapping-a-usb-keyboard-using-teensy-possible-t2841-30.html>
- <http://geekhack.org/index.php?topic=19458.0>
## kbdbabel.org[converter][vintage][protocol][8051]
Great resource of vintage keyboard protocol information and code
- <http://www.kbdbabel.org/>
## Haata's kiibohd Controller[converter][vintage][protocol][AVR][PJRC][Cortex]
A lots of vintage keyboard protocol supports
- <https://github.com/kiibohd/controller>
## Kinesis ergonomic keyboard firmware replacement[V-USB][LUFA][Ergo]
- <https://github.com/chrisandreae/kinesis-firmware>

@ -1,26 +0,0 @@
### Getting started
* [Introduction](/Home.md)
* [QMK Overview](/QMK-Overview.md)
* [Build Environment Setup](/Build-Environment-Setup.md)
### Making a keymap
* [Keymap overview](/Keymap.md)
* [Keycodes](/Keycodes.md)
* [Layer switching](/Key-Functions.md)
* [Leader Key](/Leader-Key.md)
* [Macros](/Macros.md)
* [Space Cadet](/Space-Cadet-Shift.md)
* [Tap Dance](/Tap-Dance.md)
* [Mouse keys](/Mouse-keys.md)
* [FAQ: Creating a Keymap](/FAQ-Keymap.md)
* [FAQ: Compiling QMK](/FAQ-Build.md)
### For hardware makers and modders
* [Modding your keyboard](/Modding-your-keyboard.md)
* [Porting your keyboard to QMK](/Porting-your-keyboard-to-QMK.md)
* [Adding features to QMK](/Adding-features-to-QMK.md)
### Other topics
* [General FAQ](/FAQ.md)
* [Differences from TMK](/Differences-from-TMK.md)

@ -1,21 +0,0 @@
* [Wiki Home](/qmk/qmk_firmware/wiki)
* Getting started
* [QMK Overview](QMK-Overview)
* [Build Environment Setup](Build-Environment-Setup)
* [Overview for keymap creators](Keymap)
* [Keycodes](Keycodes)
* [Layer switching](Key-Functions)
* [Leader Key](Leader-Key)
* [Macros](Macros)
* [Space Cadet](Space-Cadet-Shift)
* [Tap Dance](Tap-Dance)
* [Mouse keys](Mouse-keys)
* [FAQ: Creating a Keymap](FAQ-Keymap)
* [FAQ: Compiling QMK](FAQ-Build)
* For hardware makers and modders
* [Modding your keyboard](Modding-your-keyboard)
* [Porting your keyboard to QMK](Porting-your-keyboard-to-QMK)
* [Adding features to QMK](Adding-features-to-QMK)
* [General FAQ](FAQ)

@ -0,0 +1,29 @@
### Getting started
* [Introduction](home.md)
* [QMK Overview](qmk_overview.md)
* [Build Environment Setup](build_environment_setup.md)
### Making a keymap
* [Keymap overview](keymap.md)
* [Custom Quantum Functions](custom_quantum_functions.md)
* [Keycodes](keycodes.md)
* [Layer switching](key_functions.md)
* [Leader Key](leader_key.md)
* [Macros](macros.md)
* [Dynamic Macros](dynamic_macros.md)
* [Space Cadet](space_cadet_shift.md)
* [Tap Dance](tap_dance.md)
* [Mouse keys](mouse_keys.md)
* [FAQ: Creating a Keymap](faq_keymap.md)
* [FAQ: Compiling QMK](faq_build.md)
### For hardware makers and modders
* [Adding a keyboard to QMK](adding_a_keyboard_to_qmk.md)
* [Porting your keyboard to QMK](porting_your_keyboard_to_qmk.md)
* [Modding your keyboard](modding_your_keyboard.md)
* [Adding features to QMK](adding_features_to_qmk.md)
### Other topics
* [General FAQ](faq.md)
* [Differences from TMK](differences_from_tmk.md)

@ -0,0 +1,35 @@
# Adding your keyboard to QMK
We welcome all keyboard projects into QMK, but ask that you try to stick to a couple guidelines that help us keep things organised and consistent.
## Naming your directory/project
All names should be lowercase alphanumeric, and separated by an underscore (`_`), but not begin with one. Dashes (`-`) aren't allow by our build system, and will confuse it with keymaps/subprojects. Your directory and your `.h` and `.c` files should have exactly the same name. Subprojects/revision should follow the same format.
## `readme.md`
All projects need to have a `readme.md` file that explains what the keyboard is, who made it, where it is available, and links to move information (template coming).
## Image/Hardware files
In an effort to keep the repo size down, we're no longer accepting images of any format in the repo, with few exceptions. Hosting them elsewhere (imgur) and linking them in the readme.md is the preferred method.
Any sort of hardware file (plate, case, pcb) can't be stored in qmk_firmware, but we have the [qmk.fm repo](https://github.com/qmk/qmk.fm) where such files (as well as in-depth info) can be store, and viewed on [qmk.fm](http://qmk.fm). Downloadable files are stored in `/<keyboard>/` (name follows the same format as above) which are served at `http://qmk.fm/<keyboard>/`, and pages are generated from `/_pages/<keyboard>/` which are served at the same location (.md files are generated into .html files through Jekyll). Check out the `lets_split` directory for an example.
## Non-production/handwired projects
We're happy to accept any project that uses QMK, including prototypes and handwired ones, but we have a separate `/keyboards/handwired/` folder for them, so the main `/keyboards/` folder doesn't get overcrowded. If a prototype project becomes a production project at some point in the future, we'd be happy to move it to the main `/keyboards/` folder!
## Warnings as errors
When developing your keyboard, keep in mind that all warnings will be treated as errors - these small warnings can build-up and cause larger errors down the road (and keeping them is generally a bad practice).
## Licenses
If you're adapting your keyboard's setup from another project, but not using the same code, but sure to update the copyright header at the top of the files to show your name, it this format:
Copyright 2017 Your Name <your@email.com>
## Technical details
If you're looking for more information on making your keyboard work with QMK, [check out this guide](porting_your_keyboard_to_qmk.md)!

@ -110,7 +110,7 @@ docker run -e keymap=default -e subproject=ez -e keyboard=ergobox --rm -v D:/Use
This will compile the targeted keyboard/keymap and leave it in your QMK directory for you to flash. This will compile the targeted keyboard/keymap and leave it in your QMK directory for you to flash.
### Vagrant ### Vagrant
If you have any problems building the firmware, you can try using a tool called Vagrant. It will set up a virtual computer with a known configuration that's ready-to-go for firmware building. OLKB does NOT host the files for this virtual computer. Details on how to set up Vagrant are in the [VAGRANT_GUIDE file](https://github.com/qmk/qmk_firmware/blob/master/doc/VAGRANT_GUIDE.md). If you have any problems building the firmware, you can try using a tool called Vagrant. It will set up a virtual computer with a known configuration that's ready-to-go for firmware building. OLKB does NOT host the files for this virtual computer. Details on how to set up Vagrant are in the [vagrant guide](vagrant_guide.md).
## Verify Your Installation ## Verify Your Installation
1. If you haven't already, obtain this repository ([https://github.com/qmk/qmk_firmware](https://github.com/qmk/qmk_firmware)). You can either download it as a zip file and extract it, or clone it using the command line tool git or the Github Desktop application. 1. If you haven't already, obtain this repository ([https://github.com/qmk/qmk_firmware](https://github.com/qmk/qmk_firmware)). You can either download it as a zip file and extract it, or clone it using the command line tool git or the Github Desktop application.

@ -35,7 +35,7 @@ Debian/Ubuntu example:
sudo apt-get install gcc-avr avr-libc dfu-programmer sudo apt-get install gcc-avr avr-libc dfu-programmer
### Vagrant ### Vagrant
If you have any problems building the firmware, you can try using a tool called Vagrant. It will set up a virtual computer with a known configuration that's ready-to-go for firmware building. OLKB does NOT host the files for this virtual computer. Details on how to set up Vagrant are in the [VAGRANT_GUIDE file](VAGRANT_GUIDE.md). If you have any problems building the firmware, you can try using a tool called Vagrant. It will set up a virtual computer with a known configuration that's ready-to-go for firmware building. OLKB does NOT host the files for this virtual computer. Details on how to set up Vagrant are in the [vagrant guide](vagrant_guide.md).
## Verify Your Installation ## Verify Your Installation
1. If you haven't already, obtain this repository ([https://github.com/qmk/qmk_firmware](https://github.com/qmk/qmk_firmware)). You can either download it as a zip file and extract it, or clone it using the command line tool git or the Github Desktop application. 1. If you haven't already, obtain this repository ([https://github.com/qmk/qmk_firmware](https://github.com/qmk/qmk_firmware)). You can either download it as a zip file and extract it, or clone it using the command line tool git or the Github Desktop application.

@ -1,7 +1,7 @@
Build Firmware and Program Controller Build Firmware and Program Controller
===================================== =====================================
## This guide may be out-dated - use doc/BUILD_GUIDE.md instead ## This guide may be out-dated - use [build_guide.md](build_guide.md) instead
Download and Install Download and Install
-------------------- --------------------

@ -4,7 +4,7 @@ A custom keyboard is about more than sending button presses to your computer. QM
We have structured QMK as a hierarchy: We have structured QMK as a hierarchy:
* Core * Core (`_quantum`)
* Keyboard/Revision (`_kb`) * Keyboard/Revision (`_kb`)
* Keymap (`_user`) * Keymap (`_user`)
@ -64,14 +64,14 @@ The `record` variable contains infomation about the actual press:
``` ```
keyrecord_t record { keyrecord_t record {
keyevent_t event { +-keyevent_t event {
keypos_t key { | +-keypos_t key {
uint8_t col | | +-uint8_t col
uint8_t row | | +-uint8_t row
} | | }
bool pressed | +-bool pressed
uint16_t time | +-uint16_t time
} | }
} }
``` ```

@ -0,0 +1,63 @@
# Dynamic macros: record and replay macros in runtime
QMK supports temporarily macros created on the fly. We call these Dynamic Macros. They are defined by the user from the keyboard and are lost when the keyboard is unplugged or otherwise rebooted.
You can store one or two macros and they may have a combined total of 128 keypresses. You can increase this size at the cost of RAM.
To enable them, first add a new element to the `planck_keycodes` enum — `DYNAMIC_MACRO_RANGE`:
```c
enum planck_keycodes {
QWERTY = SAFE_RANGE,
COLEMAK,
DVORAK,
PLOVER,
LOWER,
RAISE,
BACKLIT,
EXT_PLV,
DYNAMIC_MACRO_RANGE,
};
```
It must be the last element because `dynamic_macros.h` will add some more keycodes after it.
Below it include the `dynamic_macro.h` header:
```c
#include "dynamic_macro.h"`
```
Add the following keys to your keymap:
* `DYN_REC_START1` — start recording the macro 1,
* `DYN_REC_START2` — start recording the macro 2,
* `DYN_MACRO_PLAY1` — replay the macro 1,
* `DYN_MACRO_PLAY2` — replay the macro 2,
* `DYN_REC_STOP` — finish the macro that is currently being recorded.
Add the following code to the very beginning of your `process_record_user()` function:
```c
if (!process_record_dynamic_macro(keycode, record)) {
return false;
}
```
That should be everything necessary. To start recording the macro, press either `DYN_REC_START1` or `DYN_REC_START2`. To finish the recording, press the `DYN_REC_STOP` layer button. To replay the macro, press either `DYN_MACRO_PLAY1` or `DYN_MACRO_PLAY2`.
Note that it's possible to replay a macro as part of a macro. It's ok to replay macro 2 while recording macro 1 and vice versa but never create recursive macros i.e. macro 1 that replays macro 1. If you do so and the keyboard will get unresponsive, unplug the keyboard and plug it again.
For users of the earlier versions of dynamic macros: It is still possible to finish the macro recording using just the layer modifier used to access the dynamic macro keys, without a dedicated `DYN_REC_STOP` key. If you want this behavior back, use the following snippet instead of the one above:
```c
uint16_t macro_kc = (keycode == MO(_DYN) ? DYN_REC_STOP : keycode);
if (!process_record_dynamic_macro(macro_kc, record)) {
return false;
}
```
If the LED's start blinking during the recording with each keypress, it means there is no more space for the macro in the macro buffer. To fit the macro in, either make the other macro shorter (they share the same buffer) or increase the buffer size by setting the `DYNAMIC_MACRO_SIZE` preprocessor macro (default value: 128; please read the comments for it in the header).
For the details about the internals of the dynamic macros, please read the comments in the `dynamic_macro.h` header.

@ -15,7 +15,7 @@ Note that this set-up has been tested on Ubuntu 16.04 only for the moment.
# Prerequisites # Prerequisites
## Build environment ## Build environment
Before starting, you must have followed the [Getting Started](/Home.md#getting-started) section corresponding to your system. In particular, you must have been able to build the firmware with [the `make` command](../#the-make-command). Before starting, you must have followed the [Getting Started](home.md#getting-started) section corresponding to your system. In particular, you must have been able to build the firmware with [the `make` command](../#the-make-command).
## Java ## Java
Eclipse is a Java application, so you will need to install Java 8 or more recent to be able to run it. You may choose between the JRE or the JDK, the latter being useful if you intend to do Java development. Eclipse is a Java application, so you will need to install Java 8 or more recent to be able to run it. You may choose between the JRE or the JDK, the latter being useful if you intend to do Java development.

@ -1,5 +1,5 @@
## READ FIRST ## READ FIRST
- https://github.com/jackhumbert/qmk_firmware/blob/master/doc/BUILD_GUIDE.md - https://github.com/qmk/qmk_firmware/blob/master/docs/build_guide.md
In short, In short,

@ -111,7 +111,6 @@ https://github.com/tekezo/Karabiner/issues/403
## Esc and `~ on a key ## Esc and `~ on a key
You can define FC660 and Poker style ESC with `ACTION_LAYER_MODS`. You can define FC660 and Poker style ESC with `ACTION_LAYER_MODS`.
https://github.com/tmk/tmk_core/blob/master/doc/keymap.md#35-momentary-switching-with-modifiers https://github.com/tmk/tmk_core/blob/master/doc/keymap.md#35-momentary-switching-with-modifiers
@ -246,3 +245,21 @@ here real_mods lost state for 'physical left shift'.
weak_mods is ORed with real_mods when keyboard report is sent. weak_mods is ORed with real_mods when keyboard report is sent.
https://github.com/tmk/tmk_core/blob/master/common/action_util.c#L57 https://github.com/tmk/tmk_core/blob/master/common/action_util.c#L57
## Timer functionality
It's possible to start timers and read values for time-specific events - here's an example:
```c
static uint16_t key_timer;
key_timer = timer_read();
if (timer_elapsed(key_timer) < 100) {
// do something if less than 100ms have passed
} else {
// do something if 100ms or more have passed
}
```
It's best to declare the `static uint16_t key_timer;` at the top of the file, outside of any code blocks you're using it in.

@ -282,7 +282,7 @@ It's also important to use the `KEYMAP` function we defined earlier - this is wh
#### Compiling your firmware #### Compiling your firmware
After you've written out your entire keymap, you're ready to get the firmware compiled and onto your Teensy. Before compiling, you'll need to get your [development environment set-up](/doc/BUILD_GUIDE.md) - you can skip the dfu-programmer instructions, but you'll need to download and install the [Teensy Loader](https://www.pjrc.com/teensy/loader.html) to get the firmware on your Teensy. After you've written out your entire keymap, you're ready to get the firmware compiled and onto your Teensy. Before compiling, you'll need to get your [development environment set-up](build_guide.md) - you can skip the dfu-programmer instructions, but you'll need to download and install the [Teensy Loader](https://www.pjrc.com/teensy/loader.html) to get the firmware on your Teensy.
Once everything is installed, running `make` in the terminal should get you some output, and eventually a `<project_name>.hex` file in that folder. If you're having trouble with this step, see the end of the guide for the trouble-shooting section. Once everything is installed, running `make` in the terminal should get you some output, and eventually a `<project_name>.hex` file in that folder. If you're having trouble with this step, see the end of the guide for the trouble-shooting section.

@ -1,31 +1,31 @@
# Quantum Mechanical Keyboard Firmware # Quantum Mechanical Keyboard Firmware
You have found the QMK Firmware documentation site. This is a keyboard firmware based on the [tmk\_keyboard firmware](http://github.com/tmk/tmk_keyboard) \([view differences](/Differences-from-TMK.md)\) with some useful features for Atmel AVR controllers, and more specifically, the [OLKB product line](http://olkb.com), the [ErgoDox EZ](http://www.ergodox-ez.com) keyboard, and the [Clueboard product line](http://clueboard.co/). It has also been ported to ARM chips using ChibiOS. You can use it to power your own hand-wired or custom keyboard PCB. You have found the QMK Firmware documentation site. This is a keyboard firmware based on the [tmk\_keyboard firmware](http://github.com/tmk/tmk_keyboard) \([view differences](differences_from_tmk.md)\) with some useful features for Atmel AVR controllers, and more specifically, the [OLKB product line](http://olkb.com), the [ErgoDox EZ](http://www.ergodox-ez.com) keyboard, and the [Clueboard product line](http://clueboard.co/). It has also been ported to ARM chips using ChibiOS. You can use it to power your own hand-wired or custom keyboard PCB.
# Getting started # Getting started
Before you are able to compile, you'll need to install an environment for AVR or ARM development. You'll find the instructions for any OS below. If you find another/better way to set things up from scratch, please consider [making a pull request](https://github.com/qmk/qmk_firmware/pulls) with your changes! Before you are able to compile, you'll need to install an environment for AVR or ARM development. You'll find the instructions for any OS below. If you find another/better way to set things up from scratch, please consider [making a pull request](https://github.com/qmk/qmk_firmware/pulls) with your changes!
* [Build Environment Setup](/Build-Environment-Setup.md) * [Build Environment Setup](build_environment_setup.md)
* [QMK Overview](/QMK-Overview.md) * [QMK Overview](qmk_overview.md)
# Configuring QMK Firmware # Configuring QMK Firmware
The QMK Firmware can be configured via the `keymaps` array data. For simply generating a [basic keycode](/Keycodes.md), you add it as an element of your `keymaps` array data. For more complicated actions, there are more advanced keycodes that are organized carefully to represent common operations, some of which can be found on the [Key Functions](/Key-Functions.md) page. The QMK Firmware can be configured via the `keymaps` array data. For simply generating a [basic keycode](keycodes.md), you add it as an element of your `keymaps` array data. For more complicated actions, there are more advanced keycodes that are organized carefully to represent common operations, some of which can be found on the [Key Functions](key_functions.md) page.
For more details of the `keymaps` array, see [Keymap Overview](/Keymap.md) page. For more details of the `keymaps` array, see [Keymap Overview](keymap.md) page.
## Space Cadet Shift: The future, built in ## Space Cadet Shift: The future, built in
Steve Losh [described](http://stevelosh.com/blog/2012/10/a-modern-space-cadet/) the Space Cadet Shift quite well. Essentially, you hit the left Shift on its own, and you get an opening parenthesis; hit the right Shift on its own, and you get the closing one. When hit with other keys, the Shift key keeps working as it always does. Yes, it's as cool as it sounds. Head on over to the [Space Cadet Shift](/Space-Cadet-Shift.md) page to read about it. Steve Losh [described](http://stevelosh.com/blog/2012/10/a-modern-space-cadet/) the Space Cadet Shift quite well. Essentially, you hit the left Shift on its own, and you get an opening parenthesis; hit the right Shift on its own, and you get the closing one. When hit with other keys, the Shift key keeps working as it always does. Yes, it's as cool as it sounds. Head on over to the [Space Cadet Shift](space_cadet_shift.md) page to read about it.
## The Leader key: A new kind of modifier ## The Leader key: A new kind of modifier
Most modifiers have to be held or toggled. But what if you had a key that indicated the start of a sequence? You could press that key and then rapidly press 1-3 more keys to trigger a macro, or enter a special layer, or anything else you might want to do. To learn more about it check out the [Leader Key](/Leader-Key.md) page. Most modifiers have to be held or toggled. But what if you had a key that indicated the start of a sequence? You could press that key and then rapidly press 1-3 more keys to trigger a macro, or enter a special layer, or anything else you might want to do. To learn more about it check out the [Leader Key](leader_key.md) page.
## Tap Dance: A single key can do 3, 5, or 100 different things ## Tap Dance: A single key can do 3, 5, or 100 different things
Hit the semicolon key once, send a semicolon. Hit it twice, rapidly -- send a colon. Hit it three times, and your keyboard's LEDs do a wild dance. That's just one example of what Tap Dance can do. Read more about it on the [Tap Dance](/Tap-Dance.md) page. Hit the semicolon key once, send a semicolon. Hit it twice, rapidly -- send a colon. Hit it three times, and your keyboard's LEDs do a wild dance. That's just one example of what Tap Dance can do. Read more about it on the [Tap Dance](tap_dance.md) page.
## Temporarily setting the default layer ## Temporarily setting the default layer
@ -33,7 +33,7 @@ Hit the semicolon key once, send a semicolon. Hit it twice, rapidly -- send a co
## Macro shortcuts: Send a whole string when pressing just one key ## Macro shortcuts: Send a whole string when pressing just one key
How would you like a single keypress to send a whole word, sentence, paragraph, or even document? Head on over to the [Macros](/Macros.md) page to read up on all aspects of Simple and Dynamic Macros. How would you like a single keypress to send a whole word, sentence, paragraph, or even document? Head on over to the [Macros](macros.md) page to read up on all aspects of Simple and Dynamic Macros.
## Additional keycode aliases for software-implemented layouts \(Colemak, Dvorak, etc\) ## Additional keycode aliases for software-implemented layouts \(Colemak, Dvorak, etc\)
@ -132,52 +132,3 @@ case MACRO_RAISED:
Enable the backlight from the Makefile. Enable the backlight from the Makefile.
# Custom Quantum functions
All of these functions are available in the `*_kb()` or `*_user()` variety. `kb` ones should only be used in the `<keyboard>/<keyboard>.c` file, and `user` ones should only be used in the `keymap.c`. The keyboard ones call the user ones - it's necessary to keep these calls to allow the keymap functions to work correctly.
## `void matrix_init_*(void)`
This function gets called when the matrix is initiated, and can contain start-up code for your keyboard/keymap.
## `void matrix_scan_*(void)`
This function gets called at every matrix scan, which is basically as often as the MCU can handle. Be careful what you put here, as it will get run a lot.
## `bool process_record_*(uint16_t keycode, keyrecord_t *record)`
This function gets called on every keypress/release, and is where you can define custom functionality. The return value is whether or not QMK should continue processing the keycode - returning `false` stops the execution.
The `keycode` variable is whatever is defined in your keymap, eg `MO(1)`, `KC_L`, etc. and can be switch-cased to execute code whenever a particular code is pressed.
The `record` variable contains infomation about the actual press:
```
keyrecord_t record {
keyevent_t event {
keypos_t key {
uint8_t col
uint8_t row
}
bool pressed
uint16_t time
}
}
```
The conditional `if (record->event.pressed)` can tell if the key is being pressed or released, and you can execute code based on that.
## `void led_set_*(uint8_t usb_led)`
This gets called whenever there is a state change on your host LEDs \(eg caps lock, scroll lock, etc\). The LEDs are defined as:
```
#define USB_LED_NUM_LOCK 0
#define USB_LED_CAPS_LOCK 1
#define USB_LED_SCROLL_LOCK 2
#define USB_LED_COMPOSE 3
#define USB_LED_KANA 4
```
and can be tested against the `usb_led` with a conditional like `if (usb_led & (1<<USB_LED_CAPS_LOCK))` - if this is true, you can turn your LED on, otherwise turn it off.

@ -2,10 +2,14 @@
Your keymap can include shortcuts to common operations (called "function actions" in tmk). Your keymap can include shortcuts to common operations (called "function actions" in tmk).
These functions work the same way that their `ACTION_*` functions do - they're just quick aliases. To dig into all of the tmk `ACTION_*` functions, please see the [TMK documentation](https://github.com/qmk/qmk_firmware/blob/master/doc/keymap.md#2-action). These functions work the same way that their `ACTION_*` functions do - they're just quick aliases. To dig into all of the tmk `ACTION_*` functions, please see the [TMK documentation](keymap.md#2-action).
Instead of using `FNx` when defining `ACTION_*` functions, you can use `F(x)` - the benefit here is being able to use more than 32 function actions (up to 4096), if you happen to need them. Instead of using `FNx` when defining `ACTION_*` functions, you can use `F(x)` - the benefit here is being able to use more than 32 function actions (up to 4096), if you happen to need them.
### Limits of these aliases
Currently, the keycodes able to used with these functions are limited to the TMK ones, meaning you can't use keycodes like `KC_TILD`, or anything greater than 0xFF. For a full list of the keycodes able to be used, [see this list](keycode.txt).
### Switching and toggling layers ### Switching and toggling layers
`MO(layer)` - momentary switch to *layer*. As soon as you let go of the key, the layer is deactivated and you pop back out to the previous layer. When you apply this to a key, that same key must be set as `KC_TRNS` on the destination layer. Otherwise, you won't make it back to the original layer when you release the key (and you'll get a keycode sent). You can only switch to layers *above* your current layer. If you're on layer 0 and you use `MO(1)`, that will switch to layer 1 just fine. But if you include `MO(3)` on layer 5, that won't do anything for you -- because layer 3 is lower than layer 5 on the stack. `MO(layer)` - momentary switch to *layer*. As soon as you let go of the key, the layer is deactivated and you pop back out to the previous layer. When you apply this to a key, that same key must be set as `KC_TRNS` on the destination layer. Otherwise, you won't make it back to the original layer when you release the key (and you'll get a keycode sent). You can only switch to layers *above* your current layer. If you're on layer 0 and you use `MO(1)`, that will switch to layer 1 just fine. But if you include `MO(3)` on layer 5, that won't do anything for you -- because layer 3 is lower than layer 5 on the stack.
@ -92,3 +96,26 @@ We've added shortcuts to make common modifier/tap (mod-tap) mappings more compac
* `ALL_T(kc)` - is Hyper (all mods) when held and *kc* when tapped. To read more about what you can do with a Hyper key, see [this blog post by Brett Terpstra](http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/) * `ALL_T(kc)` - is Hyper (all mods) when held and *kc* when tapped. To read more about what you can do with a Hyper key, see [this blog post by Brett Terpstra](http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/)
* `LCAG_T(kc)` - is CtrlAltGui when held and *kc* when tapped * `LCAG_T(kc)` - is CtrlAltGui when held and *kc* when tapped
* `MEH_T(kc)` - is like Hyper, but not as cool -- does not include the Cmd/Win key, so just sends Alt+Ctrl+Shift. * `MEH_T(kc)` - is like Hyper, but not as cool -- does not include the Cmd/Win key, so just sends Alt+Ctrl+Shift.
##### Permissive Hold
As of [PR#1359](https://github.com/qmk/qmk_firmware/pull/1359/), there is a new `config.h` option:
```
#define PERMISSIVE_HOLD
```
This makes it easier for fast typists to use dual-function keys. As described in the PR:
Without this, if you let go of a held key inside the tapping term, it won't register.
Example: (Tapping Term = 200)
- SHFT_T(KC_A) Down
- KC_X Down
- KC_X Up
- SHFT_T(KC_A) Up
With permissive hold, if above is typed within tapping term, this will emit `X` (so, Shift+X).
With defaults, if above is typed within tapping term, this will emit `ax`, which I doubt is what anyone really wants

@ -78,25 +78,25 @@ KC_F9 42 Keyboard F9
KC_F10 43 Keyboard F10 KC_F10 43 Keyboard F10
KC_F11 44 Keyboard F11 KC_F11 44 Keyboard F11
KC_F12 45 Keyboard F12 KC_F12 45 Keyboard F12
KC_PSCREEN KC_PSCR 46 Keyboard PrintScreen1 KC_PSCREEN KC_PSCR 46 Keyboard PrintScreen
KC_SCKLOCK KC_SLCK 47 Keyboard Scroll Lock11 KC_SCROLLLOCK KC_SLCK 47 Keyboard Scroll Lock
KC_PAUSE KC_PAUS 48 Keyboard Pause1 KC_PAUSE KC_PAUS 48 Keyboard Pause
KC_INSERT KC_INS 49 Keyboard Insert1 KC_INSERT KC_INS 49 Keyboard Insert
KC_HOME 4A Keyboard Home1 KC_HOME 4A Keyboard Home
KC_PGUP 4B Keyboard PageUp1 KC_PGUP 4B Keyboard PageUp
KC_DELETE KC_DEL 4C Keyboard Delete Forward KC_DELETE KC_DEL 4C Keyboard Delete Forward
KC_END 4D Keyboard End1 KC_END 4D Keyboard End
KC_PGDOWN KC_PGDN 4E Keyboard PageDown1 KC_PGDOWN KC_PGDN 4E Keyboard PageDown
KC_RIGHT KC_RGHT 4F Keyboard RightArrow1 KC_RIGHT KC_RGHT 4F Keyboard RightArrow
KC_LEFT 50 Keyboard LeftArrow1 KC_LEFT 50 Keyboard LeftArrow
KC_DOWN 51 Keyboard DownArrow1 KC_DOWN 51 Keyboard DownArrow
KC_UP 52 Keyboard UpArrow1 KC_UP 52 Keyboard UpArrow
KC_NUMLOCK KC_NLCK 53 Keypad Num Lock and Clear11 KC_NUMLOCK KC_NLCK 53 Keypad Num Lock and Clear
KC_KP_SLASH KC_PSLS 54 Keypad / KC_KP_SLASH KC_PSLS 54 Keypad /
KC_KP_ASTERISK KC_PAST 55 Keypad * KC_KP_ASTERISK KC_PAST 55 Keypad *
KC_KP_MINUS KC_PMNS 56 Keypad - KC_KP_MINUS KC_PMNS 56 Keypad -
KC_KP_PLUS KC_PPLS 57 Keypad + KC_KP_PLUS KC_PPLS 57 Keypad +
KC_KP_ENTER KC_PENT 58 Keypad ENTER5 KC_KP_ENTER KC_PENT 58 Keypad ENTER
KC_KP_1 KC_P1 59 Keypad 1 and End KC_KP_1 KC_P1 59 Keypad 1 and End
KC_KP_2 KC_P2 5A Keypad 2 and Down Arrow KC_KP_2 KC_P2 5A Keypad 2 and Down Arrow
KC_KP_3 KC_P3 5B Keypad 3 and PageDn KC_KP_3 KC_P3 5B Keypad 3 and PageDn
@ -109,8 +109,8 @@ KC_KP_9 KC_P9 61 Keypad 9 and PageUp
KC_KP_0 KC_P0 62 Keypad 0 and Insert KC_KP_0 KC_P0 62 Keypad 0 and Insert
KC_KP_DOT KC_PDOT 63 Keypad . and Delete KC_KP_DOT KC_PDOT 63 Keypad . and Delete
KC_NONUS_BSLASH KC_NUBS 64 Keyboard Non-US \ and | KC_NONUS_BSLASH KC_NUBS 64 Keyboard Non-US \ and |
KC_APPLICATION KC_APP 65 Keyboard Application10 KC_APPLICATION KC_APP 65 Keyboard Application
KC_POWER 66 Keyboard Power9 KC_POWER 66 Keyboard Power
KC_KP_EQUAL KC_PEQL 67 Keypad = KC_KP_EQUAL KC_PEQL 67 Keypad =
KC_F13 68 Keyboard F13 KC_F13 68 Keyboard F13
KC_F14 69 Keyboard F14 KC_F14 69 Keyboard F14
@ -138,12 +138,12 @@ KC_FIND 7E Keyboard Find
KC__MUTE 7F Keyboard Mute KC__MUTE 7F Keyboard Mute
KC__VOLUP 80 Keyboard Volume Up KC__VOLUP 80 Keyboard Volume Up
KC__VOLDOWN 81 Keyboard Volume Down KC__VOLDOWN 81 Keyboard Volume Down
KC_LOCKING_CAPS 82 Keyboard Locking Caps Lock12 KC_LOCKING_CAPS 82 Keyboard Locking Caps Lock
KC_LOCKING_NUM 83 Keyboard Locking Num Lock12 KC_LOCKING_NUM 83 Keyboard Locking Num Lock
KC_LOCKING_SCROLL 84 Keyboard Locking Scroll Lock12 KC_LOCKING_SCROLL 84 Keyboard Locking Scroll Lock
KC_KP_COMMA KC_PCMM 85 Keypad Comma27 KC_KP_COMMA KC_PCMM 85 Keypad Comma
KC_KP_EQUAL_AS400 86 Keypad Equal Sign29 KC_KP_EQUAL_AS400 86 Keypad Equal Sign
KC_INT1 KC_RO 87 Keyboard International115,28 KC_INT1 KC_RO 87 Keyboard International115
KC_INT2 KC_KANA 88 Keyboard International216 KC_INT2 KC_KANA 88 Keyboard International216
KC_INT3 KC_JYEN 89 Keyboard International317 KC_INT3 KC_JYEN 89 Keyboard International317
KC_INT4 KC_HENK 8A Keyboard International418 KC_INT4 KC_HENK 8A Keyboard International418
@ -161,8 +161,8 @@ KC_LANG6 95 Keyboard LANG68
KC_LANG7 96 Keyboard LANG78 KC_LANG7 96 Keyboard LANG78
KC_LANG8 97 Keyboard LANG88 KC_LANG8 97 Keyboard LANG88
KC_LANG9 98 Keyboard LANG98 KC_LANG9 98 Keyboard LANG98
KC_ALT_ERASE 99 Keyboard Alternate Erase7 KC_ALT_ERASE 99 Keyboard Alternate Erase
KC_SYSREQ 9A Keyboard SysReq/Attention1 KC_SYSREQ 9A Keyboard SysReq/Attention
KC_CANCEL 9B Keyboard Cancel KC_CANCEL 9B Keyboard Cancel
KC_CLEAR 9C Keyboard Clear KC_CLEAR 9C Keyboard Clear
KC_PRIOR 9D Keyboard Prior KC_PRIOR 9D Keyboard Prior

@ -1,6 +1,6 @@
# Overview # Overview
When defining a [keymap](Keymap.md) each key needs a valid key definition. When defining a [keymap](keymap.md) each key needs a valid key definition.
This page documents the symbols that correspond to keycodes that are available to you in QMK. This page documents the symbols that correspond to keycodes that are available to you in QMK.
@ -67,9 +67,9 @@ Keycodes in QMK are based on [HID Usage Keyboard/Keypad Page(0x07)](http://www.u
|KC_RSHIFT|KC_RSFT|RightShift| |KC_RSHIFT|KC_RSFT|RightShift|
|KC_RALT||RightAlt| |KC_RALT||RightAlt|
|KC_RGUI||Right GUI(Windows/Apple/Meta key)| |KC_RGUI||Right GUI(Windows/Apple/Meta key)|
|KC_LOCKING_CAPS||Locking Caps Lock12| |KC_LOCKING_CAPS||Locking Caps Lock|
|KC_LOCKING_NUM||Locking Num Lock12| |KC_LOCKING_NUM||Locking Num Lock|
|KC_LOCKING_SCROLL||Locking Scroll Lock12| |KC_LOCKING_SCROLL||Locking Scroll Lock|
|KC_INT4|KC_HENK|JIS Henken| |KC_INT4|KC_HENK|JIS Henken|
|KC_INT5|KC_MHEN|JIS Muhenken| |KC_INT5|KC_MHEN|JIS Muhenken|
@ -77,21 +77,21 @@ Keycodes in QMK are based on [HID Usage Keyboard/Keypad Page(0x07)](http://www.u
|Long Name|Short Name|Description| |Long Name|Short Name|Description|
|---------|----------|-----------| |---------|----------|-----------|
|KC_PSCREEN|KC_PSCR|PrintScreen1| |KC_PSCREEN|KC_PSCR|PrintScreen|
|KC_SCKLOCK|KC_SLCK|Scroll Lock11| |KC_SCROLLLOCK|KC_SLCK|Scroll Lock|
|KC_PAUSE|KC_PAUS|Pause1| |KC_PAUSE|KC_PAUS|Pause|
|KC_INSERT|KC_INS|Insert1| |KC_INSERT|KC_INS|Insert|
|KC_HOME||Home1| |KC_HOME||Home|
|KC_PGUP||PageUp1| |KC_PGUP||PageUp|
|KC_DELETE|KC_DEL|Delete Forward| |KC_DELETE|KC_DEL|Delete Forward|
|KC_END||End1| |KC_END||End|
|KC_PGDOWN|KC_PGDN|PageDown1| |KC_PGDOWN|KC_PGDN|PageDown|
|KC_RIGHT|KC_RGHT|RightArrow1| |KC_RIGHT|KC_RGHT|RightArrow|
|KC_LEFT||LeftArrow1| |KC_LEFT||LeftArrow|
|KC_DOWN||DownArrow1| |KC_DOWN||DownArrow|
|KC_UP||UpArrow1| |KC_UP||UpArrow|
|KC_APPLICATION|KC_APP|Application10| |KC_APPLICATION|KC_APP|Application|
|KC_POWER||Power9| |KC_POWER||Power|
|KC_EXECUTE||Execute| |KC_EXECUTE||Execute|
|KC_HELP||Help| |KC_HELP||Help|
|KC_MENU||Menu| |KC_MENU||Menu|
@ -102,8 +102,8 @@ Keycodes in QMK are based on [HID Usage Keyboard/Keypad Page(0x07)](http://www.u
|KC_COPY||Copy| |KC_COPY||Copy|
|KC_PASTE||Paste| |KC_PASTE||Paste|
|KC_FIND||Find| |KC_FIND||Find|
|KC_ALT_ERASE||Alternate Erase7| |KC_ALT_ERASE||Alternate Erase|
|KC_SYSREQ||SysReq/Attention1| |KC_SYSREQ||SysReq/Attention|
|KC_CANCEL||Cancel| |KC_CANCEL||Cancel|
|KC_CLEAR||Clear| |KC_CLEAR||Clear|
|KC_PRIOR||Prior| |KC_PRIOR||Prior|
@ -153,12 +153,12 @@ Windows and Mac use different key codes for next track and previous track. Make
|Long Name|Short Name|Description| |Long Name|Short Name|Description|
|---------|----------|-----------| |---------|----------|-----------|
|KC_NUMLOCK|KC_NLCK|Keypad Num Lock and Clear11| |KC_NUMLOCK|KC_NLCK|Keypad Num Lock and Clear|
|KC_KP_SLASH|KC_PSLS|Keypad /| |KC_KP_SLASH|KC_PSLS|Keypad /|
|KC_KP_ASTERISK|KC_PAST|Keypad *| |KC_KP_ASTERISK|KC_PAST|Keypad *|
|KC_KP_MINUS|KC_PMNS|Keypad -| |KC_KP_MINUS|KC_PMNS|Keypad -|
|KC_KP_PLUS|KC_PPLS|Keypad +| |KC_KP_PLUS|KC_PPLS|Keypad +|
|KC_KP_ENTER|KC_PENT|Keypad ENTER5| |KC_KP_ENTER|KC_PENT|Keypad ENTER|
|KC_KP_1|KC_P1|Keypad 1 and End| |KC_KP_1|KC_P1|Keypad 1 and End|
|KC_KP_2|KC_P2|Keypad 2 and Down Arrow| |KC_KP_2|KC_P2|Keypad 2 and Down Arrow|
|KC_KP_3|KC_P3|Keypad 3 and PageDn| |KC_KP_3|KC_P3|Keypad 3 and PageDn|
@ -171,8 +171,8 @@ Windows and Mac use different key codes for next track and previous track. Make
|KC_KP_0|KC_P0|Keypad 0 and Insert| |KC_KP_0|KC_P0|Keypad 0 and Insert|
|KC_KP_DOT|KC_PDOT|Keypad . and Delete| |KC_KP_DOT|KC_PDOT|Keypad . and Delete|
|KC_KP_EQUAL|KC_PEQL|Keypad =| |KC_KP_EQUAL|KC_PEQL|Keypad =|
|KC_KP_COMMA|KC_PCMM|Keypad Comma27| |KC_KP_COMMA|KC_PCMM|Keypad Comma|
|KC_KP_EQUAL_AS400||Keypad Equal Sign29| |KC_KP_EQUAL_AS400||Keypad Equal Sign|
## Special Keys ## Special Keys

@ -0,0 +1,158 @@
# Macros - Send multiple keystrokes when pressing just one key
QMK has a number of ways to define and use macros. These can do anything you want- type common phrases for you, copypasta, repetitive game movements, or even help you code.
**Security Note**: While it is possible to use macros to send passwords, credit card numbers, and other sensitive information it is a supremely bad idea to do so. Anyone who gets ahold of your keyboard will be able to access that information by opening a text editor.
# Macro Definitions
By default QMK assumes you don't have any macros. To define your macros you create an `action_get_macro()` function. For example:
```c
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
if (record->event.pressed) {
switch(id) {
case 0:
return MACRO(D(LSFT), T(H), U(LSFT), T(I), D(LSFT), T(1), U(LSFT), END);
case 1:
return MACRO(D(LSFT), T(B), U(LSFT), T(Y), T(E), D(LSFT), T(1), U(LSFT), END);
}
}
return MACRO_NONE;
};
```
This defines two macros which will be run when the key they are assigned to is pressed. If you'd like them to run when the release is released instead you can change the if statement:
```c
if (!record->event.pressed) {
```
## Macro Commands
A macro can include the following commands:
* I() change interval of stroke in milliseconds.
* D() press key.
* U() release key.
* T() type key(press and release).
* W() wait (milliseconds).
* END end mark.
## Sending strings
Sometimes you just want a key to type out words or phrases. For the most common situations we've provided `SEND_STRING()`, which will type out your string for you instead of having to build a `MACRO()`. Right now it assumes a US keymap with a QWERTY layout, so if you are using something else it may not behave as you expect.
For example:
```c
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
if (record->event.pressed) {
switch(id) {
case 0:
SEND_STRING("QMK is the best thing ever!");
return false;
}
}
return MACRO_NONE;
};
```
## Mapping a Macro to a key
Use the `M()` function within your `KEYMAP()` to call a macro. For example, here is the keymap for a 2-key keyboard:
```c
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = KEYMAP(
M(0), M(1)
),
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
if (record->event.pressed) {
switch(id) {
case 0:
return MACRO(D(LSFT), T(H), U(LSFT), T(I), D(LSFT), T(1), U(LSFT), END);
case 1:
return MACRO(D(LSFT), T(B), U(LSFT), T(Y), T(E), D(LSFT), T(1), U(LSFT), END);
}
}
return MACRO_NONE;
};
```
When you press the key on the left it will type "Hi!" and when you press the key on the right it will type "Bye!".
## Naming your macros
If you have a bunch of macros you want to refer to from your keymap while keeping the keymap easily readable you can name them using `#define` at the top of your file.
```c
#define M_HI M(0)
#define M_BYE M(1)
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = KEYMAP(
M_HI, M_BYE
),
};
```
# Advanced macro functions
While working within the `action_get_macro()` function block there are some functions you may find useful. Keep in mind that while you can write some fairly advanced code within a macro if your functionality gets too complex you may want to define a custom keycode instead. Macros are meant to be simple.
#### `record->event.pressed`
This is a boolean value that can be tested to see if the switch is being pressed or released. An example of this is
```c
if (record->event.pressed) {
// on keydown
} else {
// on keyup
}
```
#### `register_code(<kc>);`
This sends the `<kc>` keydown event to the computer. Some examples would be `KC_ESC`, `KC_C`, `KC_4`, and even modifiers such as `KC_LSFT` and `KC_LGUI`.
#### `unregister_code(<kc>);`
Parallel to `register_code` function, this sends the `<kc>` keyup event to the computer. If you don't use this, the key will be held down until it's sent.
#### `clear_keyboard();`
This will clear all mods and keys currently pressed.
#### `clear_mods();`
This will clear all mods currently pressed.
#### `clear_keyboard_but_mods();`
This will clear all keys besides the mods currently pressed.
# Advanced Example: Single-key copy/paste (hold to copy, tap to paste)
This example defines a macro which sends `Ctrl-C` when pressed down, and `Ctrl-V` when released.
```c
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
switch(id) {
case 0: {
if (record->event.pressed) {
return MACRO( D(LCTL), T(C), U(LCTL), END );
} else {
return MACRO( D(LCTL), T(V), U(LCTL), END );
}
break;
}
}
return MACRO_NONE;
};
```

@ -164,4 +164,4 @@ If your keymap directory has a file called `Makefile` (note the filename), any M
So let's say your keyboard's makefile has `BACKLIGHT_ENABLE = yes` (or maybe doesn't even list the `BACKLIGHT_ENABLE` option, which would cause it to be off). You want your particular keymap to not have the debug console, so you make a file called `Makefile` and specify `BACKLIGHT_ENABLE = no`. So let's say your keyboard's makefile has `BACKLIGHT_ENABLE = yes` (or maybe doesn't even list the `BACKLIGHT_ENABLE` option, which would cause it to be off). You want your particular keymap to not have the debug console, so you make a file called `Makefile` and specify `BACKLIGHT_ENABLE = no`.
You can use the `doc/keymap_makefile_example.md` as a template/starting point. You can use the `docs/keymap_makefile_example.md` as a template/starting point.

@ -48,16 +48,25 @@ This is inside one of the macros. So when that macro executes, your keyboard pla
"Rest style" in the method signature above (the last parameter) specifies if there's a rest (a moment of silence) between the notes. "Rest style" in the method signature above (the last parameter) specifies if there's a rest (a moment of silence) between the notes.
## Music mode
## Recording And Playing back Music The music mode maps your columns to a chromatic scale, and your rows to octaves. This works best with ortholinear keyboards, but can be made to work with others. All keycodes less than `0xFF` get blocked, so you won't type while playing notes - if you have special keys/mods, those will still work. A work-around for this is to jump to a different layer with KC_NOs before (or after) enabling music mode.
* ```Music On``` - Turn music mode on. The default mapping is ```Lower+Upper+C```
* ```LCTL``` - start a recording
* play some tones
* ```LALT``` - stop recording, stop playing
* ```LGUI``` - play recording
* ```LALT``` - stop playing
* ```Music Off``` - Turn music mode off. The default mapping is ```Lower+Upper+V```
Recording is experimental due to some memory issues - if you experience some weird behavior, unplugging/replugging your keyboard will fix things.
Keycodes available:
* `MU_ON` - Turn music mode on
* `MU_OFF` - Turn music mode off
* `MU_TOG` - Toggle music mode
In music mode, the following keycodes work differently, and don't pass through:
* `LCTL` - start a recording
* `LALT` - stop recording/stop playing
* `LGUI` - play recording
* `KC_UP` - speed-up playback
* `KC_DOWN` - slow-down playback
## MIDI functionalty ## MIDI functionalty

@ -119,7 +119,7 @@ A number of other keycodes have been added that you may find useful:
The extended keymap extends the number of function layers from 32 to the near-infinite value of 256. Rather than using `FN<num>` notation (still available, but limited to `FN0`-`FN31`), you can use the `FUNC(<num>)` notation. `F(<num>)` is a shortcut for this. The extended keymap extends the number of function layers from 32 to the near-infinite value of 256. Rather than using `FN<num>` notation (still available, but limited to `FN0`-`FN31`), you can use the `FUNC(<num>)` notation. `F(<num>)` is a shortcut for this.
The function actions are unchanged, and you can see the full list of them [here](https://github.com/jackhumbert/tmk_keyboard/blob/master/common/action_code.h). They are explained in detail [here](https://github.com/jackhumbert/tmk_keyboard/blob/master/doc/keymap.md#2-action). The function actions are unchanged, and you can see the full list of them [here](https://github.com/qmk/qmk_firmware/blob/master/tmk_core/common/action_code.h). They are explained in detail [here](keymap.md#2-action).
### Macros ### Macros

@ -1,3 +1,7 @@
# Porting your keyboard to QMK
This page describes the technical details of porting an existing keyboard to QMK. If you're looking to add your keyboard to QMK, please [look through these guidelines](adding_a_keyboard_to_qmk.md)!
If your keyboard is running an Atmega chip (atmega32u4 and others), it's pretty easy to get things setup for compiling your own firmware to flash onto your board. There is a `/util/new_project.sh <keyboard>` script to help get you started - you can simply pass your keyboard's name into the script, and all of the necessary files will be created. The components of each are described below. If your keyboard is running an Atmega chip (atmega32u4 and others), it's pretty easy to get things setup for compiling your own firmware to flash onto your board. There is a `/util/new_project.sh <keyboard>` script to help get you started - you can simply pass your keyboard's name into the script, and all of the necessary files will be created. The components of each are described below.
## `/keyboards/<keyboard>/config.h` ## `/keyboards/<keyboard>/config.h`
@ -34,7 +38,7 @@ At the bottom of the file, you'll find lots of features to turn on and off - all
## `/keyboards/<keyboard>/readme.md` ## `/keyboards/<keyboard>/readme.md`
This is where you'll describe your keyboard - please write as much as you can about it! Talking about default functionality/features is useful here. Feel free to link to external pages/sites if necessary. Images can be included here as well. This file will be rendered into a webpage at qmk.fm/keyboards/<keyboard>/. This is where you'll describe your keyboard - please write as much as you can about it! Talking about default functionality/features is useful here. Feel free to link to external pages/sites if necessary. Images can be included here as well, as long as they're hosted elsewhere (imgur).
## `/keyboards/<keyboard>/<keyboard>.c` ## `/keyboards/<keyboard>/<keyboard>.c`

@ -30,7 +30,7 @@ The `make` command is how you compile the firmware into a .hex file, which can b
**NOTE:** To abort a make command press `Ctrl-c` **NOTE:** To abort a make command press `Ctrl-c`
For more details on the QMK build process see [Make Instructions](/Make-Instructions.md). For more details on the QMK build process see [Make Instructions](make_instructions.md).
### Simple instructions for building and uploading a keyboard ### Simple instructions for building and uploading a keyboard

@ -113,13 +113,13 @@ Third party libraries like LUFA, PJRC and V-USB have their own license respectiv
Build Firmware and Program Controller Build Firmware and Program Controller
------------------------------------- -------------------------------------
See [build environment setup](/readme.md#build-environment-setup), or the readme in the particular keyboards/* folder. See [build environment setup](build_environment_setup.md), or the readme in the particular keyboards/* folder.
Change your keymap Change your keymap
------------------ ------------------
See [doc/keymap.md](tmk_core/doc/keymap.md). See [keymap.md](keymap.md).
@ -159,7 +159,7 @@ Boot Magic Configuration - Virtual DIP Switch
Boot Magic are executed during boot up time. Press Magic key below then plug in keyboard cable. Boot Magic are executed during boot up time. Press Magic key below then plug in keyboard cable.
Note that you must use keys of **Layer 0** as Magic keys. These settings are stored in EEPROM so that retain your configure over power cycles. Note that you must use keys of **Layer 0** as Magic keys. These settings are stored in EEPROM so that retain your configure over power cycles.
To avoid configuring accidentally additive salt key `KC_SPACE` also needs to be pressed along with the following configuration keys. The salt key is configurable in `config.h`. See [tmk_core/common/bootmagic.h](tmk_core/common/bootmagic.h). To avoid configuring accidentally additive salt key `KC_SPACE` also needs to be pressed along with the following configuration keys. The salt key is configurable in `config.h`. See [tmk_core/common/bootmagic.h](/tmk_core/common/bootmagic.h).
#### General #### General
- Skip reading EEPROM to start with default configuration(`ESC`) - Skip reading EEPROM to start with default configuration(`ESC`)
@ -240,4 +240,4 @@ Coding Style
Other Keyboard Firmware Projects Other Keyboard Firmware Projects
------------------ ------------------
You can learn a lot about keyboard firmware from these. See [doc/other_projects.md](tmk_core/doc/other_projects.md). You can learn a lot about keyboard firmware from these. See [docs/other_projects.md](other_projects.md).

@ -13,11 +13,11 @@ Other than having Vagrant and Virtualbox installed and possibly a restart of you
Build Firmware and Program Controller Build Firmware and Program Controller
------------------------------------- -------------------------------------
See [/doc/BUIDE_GUIDE.md](/doc/BUILD_GUIDE.md), or the readme in the particular keyboards/* folder. See [build_guide.md](build_guide.md), or the readme in the particular keyboards/* folder.
Change your keymap Change your keymap
------------------ ------------------
See [/doc/keymap.md](/doc/keymap.md). See [keymap.md](keymap.md).
## Flashing the firmware ## Flashing the firmware

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

@ -10,7 +10,7 @@ I won't claim that this layout is perfect for everyone. It does make several sig
## Base Layer ## ## Base Layer ##
![Atreus base layout](atreus-replica-base.png) ![Atreus base layout](http://imgur.com/YbOjS7O)
The letters on this layout are arranged in the [Colemak Mod-DH layout](https://colemakmods.github.io/mod-dh/). The letters on this layout are arranged in the [Colemak Mod-DH layout](https://colemakmods.github.io/mod-dh/).
@ -22,7 +22,7 @@ In addition to the Shift keys, there are three dual-purpose keys: Ctrl (Delete),
## Extend Layer ## ## Extend Layer ##
![Atreus extend layer](atreus-replica-extend.png) ![Atreus extend layer](http://imgur.com/WiKkMQw)
This layout is designed primarily for keyboard navigation. Arrow keys are easily accessible under the right hand (a welcome change from the original Atreus layout, which places them under the left hand), along with Home/End and PgUp/PgDn. This layout is designed primarily for keyboard navigation. Arrow keys are easily accessible under the right hand (a welcome change from the original Atreus layout, which places them under the left hand), along with Home/End and PgUp/PgDn.
@ -34,7 +34,7 @@ The Space key exists to prevent going from this layer directly into the Number l
## Number and Symbol Layer ## ## Number and Symbol Layer ##
![Atreus number and symbol layer](atreus-replica-num.png) ![Atreus number and symbol layer](http://imgur.com/gfTXcjC)
This layer provides the only way of accessing number keys on this keyboard, since it's too small for its own number row. Note that even though they are laid out in the number pad fashion, they send the "regular" number keystrokes. Games and programs that specifically use NumPad keys are not supported in this layout at the moment. This layer provides the only way of accessing number keys on this keyboard, since it's too small for its own number row. Note that even though they are laid out in the number pad fashion, they send the "regular" number keystrokes. Games and programs that specifically use NumPad keys are not supported in this layout at the moment.
@ -42,7 +42,7 @@ This layer also provides plenty of symbol shortcuts. Most of these can be access
## Function Layer ## ## Function Layer ##
![Atreus function layer](atreus-replica-function.png) ![Atreus function layer](http://imgur.com/m5x0MxZ)
Function keys (F1-F12) are on this layer. Their layout in groups of four comes from Jeremy's Atreus layout in this repository. I'd been using 1-9 in a numpad layout, then adding 10-12 on the side...I suppose it took seeing someone else do it this way for me to realize how much more sense it makes. Function keys (F1-F12) are on this layer. Their layout in groups of four comes from Jeremy's Atreus layout in this repository. I'd been using 1-9 in a numpad layout, then adding 10-12 on the side...I suppose it took seeing someone else do it this way for me to realize how much more sense it makes.
@ -52,7 +52,7 @@ Finally, the reset key is on this layer, as well as toggles from Colemak to QWER
## Gaming Layer ## ## Gaming Layer ##
![Atreus gaming layer](atreus-replica-game.png) ![Atreus gaming layer](http://imgur.com/4S5AO4E)
This is a small layer developed to allow some simple gameplay without a mouse. This layer is a toggle (from the Number layer), so it is designed to stay on while in use. This is a small layer developed to allow some simple gameplay without a mouse. This layer is a toggle (from the Number layer), so it is designed to stay on while in use.

@ -35,8 +35,8 @@ void promicro_bootloader_jmp(bool program);
{ KC_##k00, KC_##k01, KC_##k02, KC_##k03, KC_##k04, KC_##k05, KC_NO, KC_##k06, KC_##k07, KC_##k08, KC_##k09, KC_##k0a, KC_##k0b }, \ { KC_##k00, KC_##k01, KC_##k02, KC_##k03, KC_##k04, KC_##k05, KC_NO, KC_##k06, KC_##k07, KC_##k08, KC_##k09, KC_##k0a, KC_##k0b }, \
{ KC_##k10, KC_##k11, KC_##k12, KC_##k13, KC_##k14, KC_##k15, KC_NO, KC_##k16, KC_##k17, KC_##k18, KC_##k19, KC_##k1a, KC_##k1b }, \ { KC_##k10, KC_##k11, KC_##k12, KC_##k13, KC_##k14, KC_##k15, KC_NO, KC_##k16, KC_##k17, KC_##k18, KC_##k19, KC_##k1a, KC_##k1b }, \
{ KC_##k20, KC_##k21, KC_##k22, KC_##k23, KC_##k24, KC_##k25, KC_NO, KC_##k26, KC_##k27, KC_##k28, KC_##k29, KC_##k2a, KC_##k2b }, \ { KC_##k20, KC_##k21, KC_##k22, KC_##k23, KC_##k24, KC_##k25, KC_NO, KC_##k26, KC_##k27, KC_##k28, KC_##k29, KC_##k2a, KC_##k2b }, \
{ KC_##k30, KC_##k31, KC_##k32, KC_##k33, KC_##k34, KC_##k35, KC_##k46, KC_##k36, KC_##k37, KC_##k38, KC_##k39, KC_##k3a, KC_##k3b }, \ { KC_##k30, KC_##k31, KC_##k32, KC_##k33, KC_##k34, KC_##k35, KC_##k47, KC_##k36, KC_##k37, KC_##k38, KC_##k39, KC_##k3a, KC_##k3b }, \
{ KC_##k40, KC_##k41, KC_##k42, KC_##k43, KC_##k44, KC_##k45, KC_##k47, KC_##k48, KC_##k49, KC_##k4a, KC_##k4b, KC_##k4c, KC_##k4d } \ { KC_##k40, KC_##k41, KC_##k42, KC_##k43, KC_##k44, KC_##k45, KC_##k46, KC_##k48, KC_##k49, KC_##k4a, KC_##k4b, KC_##k4c, KC_##k4d } \
} }
#endif #endif

@ -0,0 +1,4 @@
NKRO_ENABLE = true
MOUSEKEY_ENABLE = no
EXTRAKEY_ENABLE = yes
CONSOLE_ENABLE = no

@ -0,0 +1,10 @@
<!-- -*- mode: markdown; fill-column: 8192 -*- -->
Atreus52 Modification
=======================
Firmware for my custom keyboard based on the Atreus layout, but with 5 rows and only 5 columns per hand.
More documentation coming soon.
# License
GPL-3+

@ -0,0 +1,18 @@
#include "../../config.h"
#undef MANUFACTURER
#undef PRODUCT
#undef DESCRIPTION
#undef MATRIX_ROW_PINS
#undef MATRIX_COL_PINS
#undef DIODE_DIRECTION
/* USB Device descriptor parameter */
#define MANUFACTURER Mesh Industries
#define PRODUCT Atreus52 Treeboard
#define DESCRIPTION q.m.k. keyboard firmware for Atreus52
#define MATRIX_ROW_PINS { C6, D7, E6, B4, B5 }
#define MATRIX_COL_PINS { B2, B1, F7, F6, F5, F4, B6, D3, D2, D1, D0, D4, B3 }
#define DIODE_DIRECTION COL2ROW

@ -0,0 +1,99 @@
#include "atreus62.h"
// Layers
#define DVORAK 0
#define QWERTY 1
#define RAISE 2
#define LOWER 3
#define BDO 4
#define RESETL 5
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[DVORAK] = KC_KEYMAP(
NO, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, NO, \
NO, QUOT, COMM, DOT, P, Y, F, G, C, R, L, NO, \
NO, A, O, E, U, I, D, H, T, N, S, NO, \
NO, SCLN, Q, J, K, X, B, M, W, V, Z, NO, \
NO, FN2, LALT, LCTL, FN1, LSFT, BSPC, ENT, SPC, FN0, LGUI, LEFT, RGHT, NO ),
[QWERTY] = KC_KEYMAP(
NO, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, NO, \
NO, Q, W, E, R, T, Y, U, I, O, P, NO, \
NO, A, S, D, F, G, H, J, K, L, SCLN, NO, \
NO, Z, X, C, V, B, N, M, COMM, DOT, SLSH, NO, \
NO, FN2, LALT, LCTL, FN1, LSFT, BSPC, ENT, SPC, FN0, LGUI, LEFT, RGHT, NO ),
[RAISE] = KC_KEYMAP(
NO, MRWD, MPRV, MPLY, MNXT, MFFD, TRNS, MUTE, VOLD, VOLU, DEL, NO, \
NO, TILD, GRV, LCBR, RCBR, DQUO, QUOT, EQL, PLUS, MINS, QUES, NO, \
NO, ESC, TAB, LPRN, RPRN, BSLS, SLSH, LEFT, DOWN, UP, RGHT, NO, \
NO, TRNS, TRNS, LBRC, RBRC, TRNS, INS, PIPE, UNDS, TRNS, TRNS, NO, \
NO, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, FN3, NO ),
[LOWER] = KC_KEYMAP(
NO, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, NO, \
NO, EXLM, AT, HASH, DLR, PERC, CIRC, AMPR, ASTR, LPRN, RPRN, NO, \
NO, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, NO, \
NO, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, DOT, TRNS, TRNS, TRNS, NO, \
NO, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, NO ),
[BDO] = KC_KEYMAP(
NO, ESC, 1, 2, 3, 4, 5, 0, SLSH, U, C, NO, \
NO, TAB, Q, W, E, R, 6, Y, I, O, P, NO, \
NO, LSFT, A, S, D, F, 7, G, H, J, K, NO, \
NO, T, Z, X, C, V, 8, B, N, M, L, NO, \
NO, LCTL, SPC, SPC, SPC, SPC, COMM, ENT, 9, NO, NO, NO, FN2, NO ),
[RESETL] = KEYMAP(
KC_NO, RESET, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, \
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, \
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, \
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, \
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_FN3,KC_NO )
};
const uint16_t PROGMEM fn_actions[] = {
[0] = ACTION_LAYER_MOMENTARY(RAISE), // Raise layer
[1] = ACTION_LAYER_MOMENTARY(LOWER), // Lower layer
[2] = ACTION_LAYER_TOGGLE(BDO), // BDO layer
[3] = ACTION_LAYER_TOGGLE(RESETL) // RESET layer
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRODOWN only works in this function
switch (id) {
case 0:
if (record->event.pressed) {
register_code(KC_RSFT);
}
else {
unregister_code(KC_RSFT);
}
break;
}
return MACRO_NONE;
};
static uint8_t qw_dv_swap_state = 0;
bool process_record_user (uint16_t keycode, keyrecord_t *record) {
if (keycode == KC_LGUI) {
if (record->event.pressed)
qw_dv_swap_state |= 0b00000001;
else
qw_dv_swap_state &= ~(0b00000001);
}
if (keycode == KC_LCTL) {
if (record->event.pressed)
qw_dv_swap_state |= 0b00000010;
else
qw_dv_swap_state &= ~(0b00000010);
}
if (qw_dv_swap_state == 0b00000011) {
layer_invert(DVORAK);
}
return true;
}

@ -21,7 +21,7 @@ It's for Windows (current work forces me to) and Swedish (matter of birth) so ym
## Base layer ## Base layer
![Base layer](img/base.png) ![Base layer](http://imgur.com/zTYxnE0)
* The number row doubles as a function row. Short presses produces numbers, long presses produces Fxx * The number row doubles as a function row. Short presses produces numbers, long presses produces Fxx
@ -40,14 +40,14 @@ It's for Windows (current work forces me to) and Swedish (matter of birth) so ym
## Nav layer ## Nav layer
![Nav layer](img/fun.png) ![Nav layer](http://imgur.com/cbMWVDC)
Basic navigation on the right hand and modifiers close Basic navigation on the right hand and modifiers close
by for the left. The latter because I tend to use `ctrl+arrows` quite a lot. by for the left. The latter because I tend to use `ctrl+arrows` quite a lot.
## Sym layer ## Sym layer
![Sym layer](img/sym.png) ![Sym layer](http://imgur.com/n2jmqFU)
* Easy access to most symbols I use on a daily basis. Most common are on the home row, the rest are grouped as best as I could. * Easy access to most symbols I use on a daily basis. Most common are on the home row, the rest are grouped as best as I could.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 446 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 415 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 423 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

@ -1,13 +1,4 @@
``` ![Clueboard Layout Image](http://i.imgur.com/kGADucy.png)
___ _____ _ _ _ __ __ _ __
|__ \ / ____| | | | | | / / / /(_) / /
||) | | | | |_ _ ___| |__ ___ __ _ _ __ __| | / /_ / /_ / /
|/ / | | | | | | |/ _ \ '_ \ / _ \ / _` | '__/ _` | | '_ \| '_ \ / /
|_| | |____| | |_| | __/ |_) | (_) | (_| | | | (_| | | (_) | (_) / / _
(_) \_____|_|\__,_|\___|_.__/ \___/ \__,_|_| \__,_| \___/ \___/_/ (_)
```
![Clueboard Layout Image](layout.png)
# Caps Fn Layout # Caps Fn Layout

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

@ -1,13 +1,4 @@
``` ![Clueboard Layout Image](http://i.imgur.com/7Capi8W.png)
___ _____ _ _ _ __ __ _ __
|__ \ / ____| | | | | | / / / /(_) / /
||) | | | | |_ _ ___| |__ ___ __ _ _ __ __| | / /_ / /_ / /
|/ / | | | | | | |/ _ \ '_ \ / _ \ / _` | '__/ _` | | '_ \| '_ \ / /
|_| | |____| | |_| | __/ |_) | (_) | (_| | | | (_| | | (_) | (_) / / _
(_) \_____|_|\__,_|\___|_.__/ \___/ \__,_|_| \__,_| \___/ \___/_/ (_)
```
![Clueboard Layout Image](layout.png)
# Default Clueboard Layout # Default Clueboard Layout

@ -1,11 +1,2 @@
```
___ _____ _ _ _ __ __ _ __
|__ \ / ____| | | | | | / / / /(_) / /
||) | | | | |_ _ ___| |__ ___ __ _ _ __ __| | / /_ / /_ / /
|/ / | | | | | | |/ _ \ '_ \ / _ \ / _` | '__/ _` | | '_ \| '_ \ / /
|_| | |____| | |_| | __/ |_) | (_) | (_| | | | (_| | | (_) | (_) / / _
(_) \_____|_|\__,_|\___|_.__/ \___/ \__,_|_| \__,_| \___/ \___/_/ (_)
```
# Jokrik's Clueboard Layout # Jokrik's Clueboard Layout

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

@ -1,13 +1,4 @@
``` ![Clueboard Layout Image](http://i.imgur.com/7oZCsHF.png)
___ _____ _ _ _ __ __ _ __
|__ \ / ____| | | | | | / / / /(_) / /
||) | | | | |_ _ ___| |__ ___ __ _ _ __ __| | / /_ / /_ / /
|/ / | | | | | | |/ _ \ '_ \ / _ \ / _` | '__/ _` | | '_ \| '_ \ / /
|_| | |____| | |_| | __/ |_) | (_) | (_| | | | (_| | | (_) | (_) / / _
(_) \_____|_|\__,_|\___|_.__/ \___/ \__,_|_| \__,_| \___/ \___/_/ (_)
```
![Clueboard Layout Image](layout.png)
# Default Clueboard Layout for Mac # Default Clueboard Layout for Mac

@ -1,2 +1,9 @@
MOUSEKEY_ENABLE = yes MOUSEKEY_ENABLE = yes
EXTRAKEY_ENABLE = yes EXTRAKEY_ENABLE = yes
MIDI_ENABLE = yes
# if MIDI_ENABLE is set to yes, then CONSOLE_ENABLE has to be disabled, because of the firmware size
CONSOLE_ENABLE = false
COMMAND_ENABLE = no

@ -0,0 +1,44 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
/*
* MIDI options
*/
/* Prevent use of disabled MIDI features in the keymap */
#define MIDI_ENABLE_STRICT 1
/* enable basic MIDI features:
- MIDI notes can be sent when in Music mode is on
#define MIDI_BASIC
*/
/* enable advanced MIDI features:
- MIDI notes can be added to the keymap
- Octave shift and transpose
- Virtual sustain, portamento, and modulation wheel
- etc.
*/
#define MIDI_ADVANCED
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
#define MIDI_TONE_KEYCODE_OCTAVES 2
/* Disabling rollover allows you to use the opposite shift key to cancel the space cadet state in the event
of an erroneous press instead of emitting a pair of parentheses when the keys are released.
*/
#define DISABLE_SPACE_CADET_ROLLOVER
/*
Setting the Space Cadet Parens for German layout
Default is
#define LSPO_KEY KC_9
#define RSPC_KEY KC_0
*/
#define LSPO_KEY KC_8
#define RSPC_KEY KC_9
#endif

@ -3,62 +3,94 @@
// Helpful defines // Helpful defines
#define GRAVE_MODS (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)|MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)|MOD_BIT(KC_LALT)|MOD_BIT(KC_RALT)) #define GRAVE_MODS (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)|MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)|MOD_BIT(KC_LALT)|MOD_BIT(KC_RALT))
#define _______ KC_TRNS #define _______ KC_TRNS
#define xxxxxxx KC_NO
#define HPR_TAB ALL_T(KC_TAB)
#define CTL_ESC CTL_T(KC_ESC)
// Each layer gets a name for readability, which is then used in the keymap matrix below. // Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name. // The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them // Layer names don't all need to be of the same length, obviously, and you can also skip them
// entirely and just use numbers. // entirely and just use numbers.
#define _BL 0 #define _BL 0 // BASE Layer
#define _FL 1 #define _FL 1 // Function Layer
#define _ME 2 #define _ME 2 // Media Layer
#define _CL 3 #define _CL 3 // Control Layer
#define _ML 4 #define _ML 4 // Mouse Layer
#if defined(MIDI_ENABLE)
#define _MI 5 // MIDI Layer
#define TO_MIDI TO(_MI)
#else
#define TO_MIDI _______
#endif
#define TO_BASE TO(_BL)
#define MO_FUNC MO(_FL)
#define MEDIA MO(_ME)
#define MO_CTL MO(_CL)
#define L_MOUSE LT(_ML, KC_SPC)
#define ESC_FUN LT(_FL, KC_ESC)
#define ESC_GRV F(0)
#define RGB_RST F(1)
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap _BL: Base Layer (Default Layer) /* Keymap _BL: Base Layer (Default Layer) */
*/
[_BL] = KEYMAP( [_BL] = KEYMAP(
F(0), KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, _______, KC_BSPC, KC_INS, \ ESC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, _______, KC_BSPC, KC_INS, \
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, \ HPR_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, \
MO(_FL), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NUHS, KC_ENT, \ ESC_FUN, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NUHS, KC_ENT, \
KC_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, _______, KC_RSFT, KC_UP, \ KC_LSPO, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, _______, KC_RSPC, KC_UP, \
KC_LCTL, KC_LGUI, KC_LALT, _______, LT(_ML, KC_SPC),LT(_ML, KC_SPC), _______, KC_RALT, MO(_ME), MO(_FL), KC_LEFT, KC_DOWN, KC_RGHT), KC_LCTL, KC_LGUI, KC_LALT,_______, L_MOUSE, L_MOUSE, _______, KC_RALT, KC_RCTL, MO_FUNC, KC_LEFT, KC_DOWN, KC_RGHT),
/* Keymap _FL: Function Layer /* Keymap _FL: Function Layer */
*/
[_FL] = KEYMAP( [_FL] = KEYMAP(
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, _______, BL_STEP, \ KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, _______, BL_STEP, \
_______, _______, _______,_______,_______,_______,_______,_______,KC_PSCR,_______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, KC_PSCR, _______, KC_PAUS, _______, _______, _______, _______, \
MO(_FL), _______, MO(_CL),_______,_______,_______,_______,_______,_______,_______, _______, _______, _______, _______, \ _______, _______, MO_CTL, _______, _______, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, _______, _______, _______, _______, \
_______, _______, _______,_______,_______,_______,_______,_______,MO(_ME),_______, _______, _______, _______, _______, KC_PGUP, \ _______, _______, _______, _______, _______, _______, _______, _______, MEDIA, _______, _______, TO_MIDI, _______, _______, KC_PGUP, \
_______, _______, _______,_______, _______,_______, _______, _______, _______, MO(_FL), KC_HOME, KC_PGDN, KC_END), _______, _______, _______, _______, _______, _______, _______, _______, _______, MO_FUNC, KC_HOME, KC_PGDN, KC_END),
/* Keymap _ME: Media layer /* Keymap _ME: Media layer */
*/
[_ME] = KEYMAP( [_ME] = KEYMAP(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MUTE, KC_VOLU, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MUTE, KC_VOLU, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_VOLD, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_VOLD, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
MO(_FL), _______, _______,_______,_______,_______,_______,_______,MO(_ME),_______, _______, _______, _______, MO(_FL), _______, \ _______, _______, _______, _______, _______, _______, _______, _______, MEDIA, _______, _______, _______, _______, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MPRV, KC_MPLY, KC_MNXT), _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MPRV, KC_MPLY, KC_MNXT),
/* Keymap _CL: Control layer /* Keymap _CL: Control layer */
*/
[_CL] = KEYMAP( [_CL] = KEYMAP(
_______, _______, _______,_______,_______,_______,_______,_______,_______,_______, _______, _______, _______, _______, RGB_TOG, RGB_VAI, \ _______, RGB_RST, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_TOG, RGB_VAI, \
_______, _______, _______, _______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_VAD, \ _______, _______, _______, _______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_VAD, \
_______, _______, MO(_CL),_______,_______,_______,_______,_______,_______,_______, _______, _______, _______, _______, \ _______, _______, MO_CTL, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
MO(_FL), _______, _______,_______,_______,_______,_______,_______,_______,_______, _______, _______, _______, MO(_FL), RGB_SAI, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_SAI, \
_______, _______, _______, _______, RGB_MOD, RGB_MOD, _______, _______, _______, _______, RGB_HUD, RGB_SAD, RGB_HUI), _______, _______, _______, _______, RGB_MOD, RGB_MOD, _______, _______, _______, _______, RGB_HUD, RGB_SAD, RGB_HUI),
/* Keymap _ML: Mouse layer /* Keymap _ML: Mouse layer */
*/
[_ML] = KEYMAP( [_ML] = KEYMAP(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
_______, _______, KC_BTN3, KC_BTN2, KC_BTN1, _______, KC_MS_L, KC_MS_D, KC_MS_U, KC_MS_R, _______, _______, _______, _______, \ _______, _______, KC_BTN3, KC_BTN2, KC_BTN1, _______, KC_MS_L, KC_MS_D, KC_MS_U, KC_MS_R, _______, _______, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MS_U, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MS_U, \
_______, _______, _______,_______, LT(_ML, KC_SPC),LT(_ML, KC_SPC), _______, KC_BTN1, KC_BTN2, KC_BTN3, KC_MS_L, KC_MS_D,KC_MS_R), _______, _______, _______, _______, L_MOUSE, L_MOUSE, _______, KC_BTN1, KC_BTN2, KC_BTN3, KC_MS_L, KC_MS_D, KC_MS_R),
#if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
/* Keymap _MI: MIDI layer (Advanced)*/
[_MI] = KEYMAP(
TO_BASE,MI_VEL_1,MI_VEL_2,MI_VEL_3,MI_VEL_4,MI_VEL_5,MI_VEL_6,MI_VEL_7,MI_VEL_8,MI_VEL_9,MI_VEL_10, MI_CHD, MI_CHU, xxxxxxx, xxxxxxx, xxxxxxx, \
xxxxxxx, xxxxxxx, MI_Cs, MI_Ds, xxxxxxx, MI_Fs, MI_Gs, MI_As, xxxxxxx, MI_Cs_1, MI_Ds_1, xxxxxxx, MI_Fs_1, xxxxxxx, xxxxxxx, \
MI_MOD, MI_C, MI_D, MI_E, MI_F, MI_G, MI_A, MI_B, MI_C_1, MI_D_1, MI_E_1, MI_F_1, MI_G_1, xxxxxxx, \
MI_SUS, xxxxxxx, MI_OCTD, MI_OCTU,MI_MODSD,MI_MODSU, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, MI_TRNSD,MI_TRNSU,MI_TRNS_0, MI_SUS, xxxxxxx, \
xxxxxxx, xxxxxxx, xxxxxxx,xxxxxxx, MI_ALLOFF, MI_ALLOFF, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx),
#elif defined(MIDI_ENABLE) && defined(MIDI_BASIC)
/* Keymap _MI: MIDI layer (Basic)*/
[_MI] = KEYMAP(
TO_BASE, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, \
xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, \
xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, \
xxxxxxx, xxxxxxx, MI_ON, MI_OFF, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, \
xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx),
#endif
}; };
/* This is a list of user defined functions. F(N) corresponds to item N /* This is a list of user defined functions. F(N) corresponds to item N
@ -66,6 +98,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
*/ */
const uint16_t PROGMEM fn_actions[] = { const uint16_t PROGMEM fn_actions[] = {
[0] = ACTION_FUNCTION(0), // Calls action_function() [0] = ACTION_FUNCTION(0), // Calls action_function()
[1] = ACTION_FUNCTION(1), // Calls action_function()
}; };
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
@ -102,6 +135,11 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
} }
} }
break; break;
case 1:
if (record->event.pressed) {
rgblight_mode(1);
rgblight_sethsv(206, 255, 255);
}
} }
} }
@ -110,43 +148,61 @@ enum layer_id {
LAYER_FUNCTION, LAYER_FUNCTION,
LAYER_MEDIA, LAYER_MEDIA,
LAYER_CONTROL, LAYER_CONTROL,
LAYER_MOUSE LAYER_MOUSE,
#if defined(MIDI_ENABLE)
LAYER_MIDI
#endif
}; };
void clueboard_set_led(uint8_t id) { void clueboard_set_led(uint8_t id, uint8_t val) {
switch (id) { switch (id) {
case LAYER_BASE: case LAYER_BASE:
rgblight_sethsv(346, 0, 255); rgblight_sethsv_noeeprom(0, 0, val);
break; break;
case LAYER_FUNCTION: case LAYER_FUNCTION:
rgblight_sethsv(46, 255, 255); rgblight_sethsv_noeeprom(46, 255, val);
break; break;
case LAYER_MEDIA: case LAYER_MEDIA:
rgblight_sethsv(86, 255, 255); rgblight_sethsv_noeeprom(86, 255, val);
break; break;
case LAYER_CONTROL: case LAYER_CONTROL:
rgblight_sethsv(346, 255, 255); rgblight_sethsv_noeeprom(346, 255, val);
break; break;
case LAYER_MOUSE: case LAYER_MOUSE:
rgblight_sethsv(206, 255, 255); rgblight_sethsv_noeeprom(206, 255, val);
break; break;
#if defined(MIDI_ENABLE)
case LAYER_MIDI:
rgblight_sethsv_noeeprom(316, 255, val);
break;
#endif
} }
}; };
void matrix_scan_user(void) { void matrix_scan_user(void) {
rgblight_config_t rgblight_config;
rgblight_config.raw = eeconfig_read_rgblight();
if (!rgblight_config.enable || rgblight_config.mode != 1) { return; }
uint32_t layer = layer_state; uint32_t layer = layer_state;
uint8_t val = rgblight_config.val;
if (layer & (1<<_FL)) { if (layer & (1<<_FL)) {
if (layer & (1<<_ME)) { if (layer & (1<<_ME)) {
clueboard_set_led(LAYER_MEDIA); clueboard_set_led(LAYER_MEDIA, val);
} else if (layer & (1<<_CL)) { } else if (layer & (1<<_CL)) {
clueboard_set_led(LAYER_CONTROL); clueboard_set_led(LAYER_CONTROL, val);
} else { } else {
clueboard_set_led(LAYER_FUNCTION); clueboard_set_led(LAYER_FUNCTION, val);
} }
} else if (layer & (1<<_ML)) { } else if (layer & (1<<_ML)) {
clueboard_set_led(LAYER_MOUSE); clueboard_set_led(LAYER_MOUSE, val);
#if defined(MIDI_ENABLE)
} else if (layer & (1<<_MI)) {
clueboard_set_led(LAYER_MIDI, val);
#endif
} else { } else {
clueboard_set_led(LAYER_BASE); clueboard_set_led(LAYER_BASE, val);
} }
}; };

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 KiB

@ -1,15 +1,8 @@
``` # Layout of @magicmonty
___ _____ _ _ _ __ __ _ __
|__ \ / ____| | | | | | / / / /(_) / /
||) | | | | |_ _ ___| |__ ___ __ _ _ __ __| | / /_ / /_ / /
|/ / | | | | | | |/ _ \ '_ \ / _ \ / _` | '__/ _` | | '_ \| '_ \ / /
|_| | |____| | |_| | __/ |_) | (_) | (_| | | | (_| | | (_) | (_) / / _
(_) \_____|_|\__,_|\___|_.__/ \___/ \__,_|_| \__,_| \___/ \___/_/ (_)
```
![Clueboard Layout Image](layout.png) [Keyboard Layout Editor File]
# MouseKeys Layout ![Clueboard Layout Image](http://i.imgur.com/WFfJ15k.png)
This layout is a combination of the `mouse_keys` and the `win_optimized` layouts. This layout is a combination of the `mouse_keys` and the `win_optimized` layouts.
This layout is optimized for an ISO layout. This layout is optimized for an ISO layout.
@ -19,7 +12,11 @@ will move your mouse cursor. You can click using the 3 mods to the left of the
arrow keys, or the 3 keys under your primary fingers on the home row. arrow keys, or the 3 keys under your primary fingers on the home row.
The Left, Down, Up and Right for the mouse movement are also VIM-Like on the HJKL keys The Left, Down, Up and Right for the mouse movement are also VIM-Like on the HJKL keys
The CapsLock is disabled and works as Function key. There is also a MIDI layer included.
The CapsLock is disabled and works as Escape when tapped and Fn when Hold.
The Tab key works as Tab when tapped, and [Hyper] (Ctrl + Alt + Shift + Cmd) when hold
The Shift-Keys are configured as [Space Cadet Shift Parentheses]
There is also a separate media layer with Volume/Play controls There is also a separate media layer with Volume/Play controls
@ -30,3 +27,8 @@ The different layers are signalled throug setting of the underlight:
- Media layer: Green - Media layer: Green
- Mouse layer: Blue - Mouse layer: Blue
- Control layer: Red - Control layer: Red
- Midi layer: Purple
[Hyper]: http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/
[Space Cadet Shift Parentheses]: http://stevelosh.com/blog/2012/10/a-modern-space-cadet/#shift-parentheses
[Keyboard Layout Editor File]: http://www.keyboard-layout-editor.com/#/gists/f869b8789242a712e0f46eabbd550056

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

@ -1,13 +1,4 @@
``` ![Clueboard Layout Image](http://i.imgur.com/7oZCsHF.png)
___ _____ _ _ _ __ __ _ __
|__ \ / ____| | | | | | / / / /(_) / /
||) | | | | |_ _ ___| |__ ___ __ _ _ __ __| | / /_ / /_ / /
|/ / | | | | | | |/ _ \ '_ \ / _ \ / _` | '__/ _` | | '_ \| '_ \ / /
|_| | |____| | |_| | __/ |_) | (_) | (_| | | | (_| | | (_) | (_) / / _
(_) \_____|_|\__,_|\___|_.__/ \___/ \__,_|_| \__,_| \___/ \___/_/ (_)
```
![Clueboard Layout Image](layout.png)
# Maximised Clueboard Layout # Maximised Clueboard Layout

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

@ -1,12 +1,3 @@
```
___ _____ _ _ _ __ __ _ __
|__ \ / ____| | | | | | / / / /(_) / /
||) | | | | |_ _ ___| |__ ___ __ _ _ __ __| | / /_ / /_ / /
|/ / | | | | | | |/ _ \ '_ \ / _ \ / _` | '__/ _` | | '_ \| '_ \ / /
|_| | |____| | |_| | __/ |_) | (_) | (_| | | | (_| | | (_) | (_) / / _
(_) \_____|_|\__,_|\___|_.__/ \___/ \__,_|_| \__,_| \___/ \___/_/ (_)
```
![Clueboard Layout Image](layout.png) ![Clueboard Layout Image](layout.png)
# MouseKeys Layout # MouseKeys Layout

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save