はじめに
これは、「C言語とか組み込みなんもわからん」男が QMK というジャングルを探検していく、ノンフィクションドキュメンタリーである……
なお、更新は亀の歩みである……
- はじめに
- 前回のおさらい
- 探検開始
- keymap.h
- keycode.h
- quantum_keycodes.h
- keycode_config.h
- keycode_config.c
- debug.h
- debug.c
- report.h
- report.c
- uint8_t has_anykey(report_keyboard_t* keyboard_report)
- uint8_t get_first_key(report_keyboard_t* keyboard_report)
- bool is_key_pressed(report_keyboard_t* keyboard_report, uint8_t key)
- void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code)
- void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code)
- void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code)
- void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code)
- void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key)
- void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key)
- void clear_keys_from_report(report_keyboard_t* keyboard_report)
- まとめ
- 次回予告
前回のおさらい
- wait.h
- matrix.h
を探検した
探検開始
続きから探検していこう
wait.hmatrix.h- keymap.h
- action_layer.h
- eeconfig.h
- bootloader.h
- timer.h
- sync_timer.h
- config_common.h
- gpio.h
- atomic_util.h
- led.h
- action_util.h
- action_tapping.h
- print.h
- send_string.h
- suspend.h
keymap.h
ソース全体
/* Copyright 2012-2016 Jun Wako <wakojun@gmail.com> 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/>. */ #pragma once #include <stdint.h> #include <stdbool.h> #include "action.h" #if defined(__AVR__) # include <avr/pgmspace.h> #elif defined PROTOCOL_CHIBIOS // We need to ensure that chibios is include before redefining reset # include <ch.h> #endif #include "keycode.h" #include "action_macro.h" #include "report.h" #include "host.h" // #include "print.h" #include "debug.h" #include "keycode_config.h" // ChibiOS uses RESET in its FlagStatus enumeration // Therefore define it as QK_RESET here, to avoid name collision #if defined(PROTOCOL_CHIBIOS) # define RESET QK_RESET #endif // Gross hack, remove me and change RESET keycode to QK_BOOT #if defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1287__) # undef RESET #endif #include "quantum_keycodes.h" // translates key to keycode uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key); // translates function id to action uint16_t keymap_function_id_to_action(uint16_t function_id); extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; extern const uint16_t fn_actions[];
ここでもたくさん include されている
- action.h
- keycode.h
- action_macro.h
- report.h
- host.h
- debug.h
- keycode_config.h
- quantum_keycodes.h
今回は、ざっと見て簡単そうなものから見ていこうと思う
順番はこんな感じだ
- keycode.h
- quantum_keycodes.h
- keycode_config.h
- debug.h
- report.h
- host.h
- action_macro.h
- action.h
keycode.h
ソース全体
/* Copyright 2011,2012 Jun Wako <wakojun@gmail.com> 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/>. */ /* * Keycodes based on HID Keyboard/Keypad Usage Page (0x07) plus media keys from Generic Desktop Page (0x01) and Consumer Page (0x0C) * * See https://web.archive.org/web/20060218214400/http://www.usb.org/developers/devclass_docs/Hut1_12.pdf * or http://www.usb.org/developers/hidpage/Hut1_12v2.pdf (older) */ #pragma once /* FIXME: Add doxygen comments here */ #define IS_ERROR(code) (KC_ROLL_OVER <= (code) && (code) <= KC_UNDEFINED) #define IS_ANY(code) (KC_A <= (code) && (code) <= 0xFF) #define IS_KEY(code) (KC_A <= (code) && (code) <= KC_EXSEL) #define IS_MOD(code) (KC_LCTRL <= (code) && (code) <= KC_RGUI) #define IS_SPECIAL(code) ((0xA5 <= (code) && (code) <= 0xDF) || (0xE8 <= (code) && (code) <= 0xFF)) #define IS_SYSTEM(code) (KC_PWR <= (code) && (code) <= KC_WAKE) #define IS_CONSUMER(code) (KC_MUTE <= (code) && (code) <= KC_BRID) #define IS_FN(code) (KC_FN0 <= (code) && (code) <= KC_FN31) #define IS_MOUSEKEY(code) (KC_MS_UP <= (code) && (code) <= KC_MS_ACCEL2) #define IS_MOUSEKEY_MOVE(code) (KC_MS_UP <= (code) && (code) <= KC_MS_RIGHT) #define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN8) #define IS_MOUSEKEY_WHEEL(code) (KC_MS_WH_UP <= (code) && (code) <= KC_MS_WH_RIGHT) #define IS_MOUSEKEY_ACCEL(code) (KC_MS_ACCEL0 <= (code) && (code) <= KC_MS_ACCEL2) #define MOD_BIT(code) (1 << MOD_INDEX(code)) #define MOD_INDEX(code) ((code)&0x07) #define MOD_MASK_CTRL (MOD_BIT(KC_LCTRL) | MOD_BIT(KC_RCTRL)) #define MOD_MASK_SHIFT (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) #define MOD_MASK_ALT (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT)) #define MOD_MASK_GUI (MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI)) #define MOD_MASK_CS (MOD_MASK_CTRL | MOD_MASK_SHIFT) #define MOD_MASK_CA (MOD_MASK_CTRL | MOD_MASK_ALT) #define MOD_MASK_CG (MOD_MASK_CTRL | MOD_MASK_GUI) #define MOD_MASK_SA (MOD_MASK_SHIFT | MOD_MASK_ALT) #define MOD_MASK_SG (MOD_MASK_SHIFT | MOD_MASK_GUI) #define MOD_MASK_AG (MOD_MASK_ALT | MOD_MASK_GUI) #define MOD_MASK_CSA (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_ALT) #define MOD_MASK_CSG (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_GUI) #define MOD_MASK_CAG (MOD_MASK_CTRL | MOD_MASK_ALT | MOD_MASK_GUI) #define MOD_MASK_SAG (MOD_MASK_SHIFT | MOD_MASK_ALT | MOD_MASK_GUI) #define MOD_MASK_CSAG (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_ALT | MOD_MASK_GUI) #define FN_BIT(code) (1 << FN_INDEX(code)) #define FN_INDEX(code) ((code)-KC_FN0) #define FN_MIN KC_FN0 #define FN_MAX KC_FN31 /* * Short names for ease of definition of keymap */ /* Transparent */ #define KC_TRANSPARENT 0x01 #define KC_TRNS KC_TRANSPARENT /* Punctuation */ #define KC_ENT KC_ENTER #define KC_ESC KC_ESCAPE #define KC_BSPC KC_BSPACE #define KC_SPC KC_SPACE #define KC_MINS KC_MINUS #define KC_EQL KC_EQUAL #define KC_LBRC KC_LBRACKET #define KC_RBRC KC_RBRACKET #define KC_BSLS KC_BSLASH #define KC_NUHS KC_NONUS_HASH #define KC_SCLN KC_SCOLON #define KC_QUOT KC_QUOTE #define KC_GRV KC_GRAVE #define KC_COMM KC_COMMA #define KC_SLSH KC_SLASH #define KC_NUBS KC_NONUS_BSLASH /* Lock Keys */ #define KC_CLCK KC_CAPSLOCK #define KC_CAPS KC_CAPSLOCK #define KC_SLCK KC_SCROLLLOCK #define KC_NLCK KC_NUMLOCK #define KC_LCAP KC_LOCKING_CAPS #define KC_LNUM KC_LOCKING_NUM #define KC_LSCR KC_LOCKING_SCROLL /* Commands */ #define KC_PSCR KC_PSCREEN #define KC_PAUS KC_PAUSE #define KC_BRK KC_PAUSE #define KC_INS KC_INSERT #define KC_DEL KC_DELETE #define KC_PGDN KC_PGDOWN #define KC_RGHT KC_RIGHT #define KC_APP KC_APPLICATION #define KC_EXEC KC_EXECUTE #define KC_SLCT KC_SELECT #define KC_AGIN KC_AGAIN #define KC_PSTE KC_PASTE #define KC_ERAS KC_ALT_ERASE #define KC_CLR KC_CLEAR /* Keypad */ #define KC_PSLS KC_KP_SLASH #define KC_PAST KC_KP_ASTERISK #define KC_PMNS KC_KP_MINUS #define KC_PPLS KC_KP_PLUS #define KC_PENT KC_KP_ENTER #define KC_P1 KC_KP_1 #define KC_P2 KC_KP_2 #define KC_P3 KC_KP_3 #define KC_P4 KC_KP_4 #define KC_P5 KC_KP_5 #define KC_P6 KC_KP_6 #define KC_P7 KC_KP_7 #define KC_P8 KC_KP_8 #define KC_P9 KC_KP_9 #define KC_P0 KC_KP_0 #define KC_PDOT KC_KP_DOT #define KC_PEQL KC_KP_EQUAL #define KC_PCMM KC_KP_COMMA /* Japanese specific */ #define KC_ZKHK KC_GRAVE #define KC_RO KC_INT1 #define KC_KANA KC_INT2 #define KC_JYEN KC_INT3 #define KC_HENK KC_INT4 #define KC_MHEN KC_INT5 /* Korean specific */ #define KC_HAEN KC_LANG1 #define KC_HANJ KC_LANG2 /* Modifiers */ #define KC_LCTL KC_LCTRL #define KC_LSFT KC_LSHIFT #define KC_LOPT KC_LALT #define KC_LCMD KC_LGUI #define KC_LWIN KC_LGUI #define KC_RCTL KC_RCTRL #define KC_RSFT KC_RSHIFT #define KC_ALGR KC_RALT #define KC_ROPT KC_RALT #define KC_RCMD KC_RGUI #define KC_RWIN KC_RGUI /* Generic Desktop Page (0x01) */ #define KC_PWR KC_SYSTEM_POWER #define KC_SLEP KC_SYSTEM_SLEEP #define KC_WAKE KC_SYSTEM_WAKE /* Consumer Page (0x0C) */ #define KC_MUTE KC_AUDIO_MUTE #define KC_VOLU KC_AUDIO_VOL_UP #define KC_VOLD KC_AUDIO_VOL_DOWN #define KC_MNXT KC_MEDIA_NEXT_TRACK #define KC_MPRV KC_MEDIA_PREV_TRACK #define KC_MSTP KC_MEDIA_STOP #define KC_MPLY KC_MEDIA_PLAY_PAUSE #define KC_MSEL KC_MEDIA_SELECT #define KC_EJCT KC_MEDIA_EJECT #define KC_CALC KC_CALCULATOR #define KC_MYCM KC_MY_COMPUTER #define KC_WSCH KC_WWW_SEARCH #define KC_WHOM KC_WWW_HOME #define KC_WBAK KC_WWW_BACK #define KC_WFWD KC_WWW_FORWARD #define KC_WSTP KC_WWW_STOP #define KC_WREF KC_WWW_REFRESH #define KC_WFAV KC_WWW_FAVORITES #define KC_MFFD KC_MEDIA_FAST_FORWARD #define KC_MRWD KC_MEDIA_REWIND #define KC_BRIU KC_BRIGHTNESS_UP #define KC_BRID KC_BRIGHTNESS_DOWN /* System Specific */ #define KC_BRMU KC_PAUSE #define KC_BRMD KC_SCROLLLOCK /* Mouse Keys */ #define KC_MS_U KC_MS_UP #define KC_MS_D KC_MS_DOWN #define KC_MS_L KC_MS_LEFT #define KC_MS_R KC_MS_RIGHT #define KC_BTN1 KC_MS_BTN1 #define KC_BTN2 KC_MS_BTN2 #define KC_BTN3 KC_MS_BTN3 #define KC_BTN4 KC_MS_BTN4 #define KC_BTN5 KC_MS_BTN5 #define KC_BTN6 KC_MS_BTN6 #define KC_BTN7 KC_MS_BTN7 #define KC_BTN8 KC_MS_BTN8 #define KC_WH_U KC_MS_WH_UP #define KC_WH_D KC_MS_WH_DOWN #define KC_WH_L KC_MS_WH_LEFT #define KC_WH_R KC_MS_WH_RIGHT #define KC_ACL0 KC_MS_ACCEL0 #define KC_ACL1 KC_MS_ACCEL1 #define KC_ACL2 KC_MS_ACCEL2 /* Keyboard/Keypad Page (0x07) */ enum hid_keyboard_keypad_usage { KC_NO = 0x00, KC_ROLL_OVER, KC_POST_FAIL, KC_UNDEFINED, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G, KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, // 0x10 KC_N, KC_O, KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W, KC_X, KC_Y, KC_Z, KC_1, KC_2, KC_3, // 0x20 KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_ENTER, KC_ESCAPE, KC_BSPACE, KC_TAB, KC_SPACE, KC_MINUS, KC_EQUAL, KC_LBRACKET, KC_RBRACKET, // 0x30 KC_BSLASH, KC_NONUS_HASH, KC_SCOLON, KC_QUOTE, KC_GRAVE, KC_COMMA, KC_DOT, KC_SLASH, KC_CAPSLOCK, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, // 0x40 KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCREEN, KC_SCROLLLOCK, KC_PAUSE, KC_INSERT, KC_HOME, KC_PGUP, KC_DELETE, KC_END, KC_PGDOWN, KC_RIGHT, KC_LEFT, // 0x50 KC_DOWN, KC_UP, KC_NUMLOCK, KC_KP_SLASH, KC_KP_ASTERISK, KC_KP_MINUS, KC_KP_PLUS, KC_KP_ENTER, KC_KP_1, KC_KP_2, KC_KP_3, KC_KP_4, KC_KP_5, KC_KP_6, KC_KP_7, KC_KP_8, // 0x60 KC_KP_9, KC_KP_0, KC_KP_DOT, KC_NONUS_BSLASH, KC_APPLICATION, KC_POWER, KC_KP_EQUAL, KC_F13, KC_F14, KC_F15, KC_F16, KC_F17, KC_F18, KC_F19, KC_F20, KC_F21, // 0x70 KC_F22, KC_F23, KC_F24, KC_EXECUTE, KC_HELP, KC_MENU, KC_SELECT, KC_STOP, KC_AGAIN, KC_UNDO, KC_CUT, KC_COPY, KC_PASTE, KC_FIND, KC__MUTE, KC__VOLUP, // 0x80 KC__VOLDOWN, KC_LOCKING_CAPS, KC_LOCKING_NUM, KC_LOCKING_SCROLL, KC_KP_COMMA, KC_KP_EQUAL_AS400, KC_INT1, KC_INT2, KC_INT3, KC_INT4, KC_INT5, KC_INT6, KC_INT7, KC_INT8, KC_INT9, KC_LANG1, // 0x90 KC_LANG2, KC_LANG3, KC_LANG4, KC_LANG5, KC_LANG6, KC_LANG7, KC_LANG8, KC_LANG9, KC_ALT_ERASE, KC_SYSREQ, KC_CANCEL, KC_CLEAR, KC_PRIOR, KC_RETURN, KC_SEPARATOR, KC_OUT, // 0xA0 KC_OPER, KC_CLEAR_AGAIN, KC_CRSEL, KC_EXSEL, #if 0 // *************************************************************** // These keycodes are present in the HID spec, but are * // nonfunctional on modern OSes. QMK uses this range (0xA5-0xDF) * // for the media and function keys instead - see below. * // *************************************************************** KC_KP_00 = 0xB0, KC_KP_000, KC_THOUSANDS_SEPARATOR, KC_DECIMAL_SEPARATOR, KC_CURRENCY_UNIT, KC_CURRENCY_SUB_UNIT, KC_KP_LPAREN, KC_KP_RPAREN, KC_KP_LCBRACKET, KC_KP_RCBRACKET, KC_KP_TAB, KC_KP_BSPACE, KC_KP_A, KC_KP_B, KC_KP_C, KC_KP_D, KC_KP_E, //0xC0 KC_KP_F, KC_KP_XOR, KC_KP_HAT, KC_KP_PERC, KC_KP_LT, KC_KP_GT, KC_KP_AND, KC_KP_LAZYAND, KC_KP_OR, KC_KP_LAZYOR, KC_KP_COLON, KC_KP_HASH, KC_KP_SPACE, KC_KP_ATMARK, KC_KP_EXCLAMATION, KC_KP_MEM_STORE, //0xD0 KC_KP_MEM_RECALL, KC_KP_MEM_CLEAR, KC_KP_MEM_ADD, KC_KP_MEM_SUB, KC_KP_MEM_MUL, KC_KP_MEM_DIV, KC_KP_PLUS_MINUS, KC_KP_CLEAR, KC_KP_CLEAR_ENTRY, KC_KP_BINARY, KC_KP_OCTAL, KC_KP_DECIMAL, KC_KP_HEXADECIMAL, #endif /* Modifiers */ KC_LCTRL = 0xE0, KC_LSHIFT, KC_LALT, KC_LGUI, KC_RCTRL, KC_RSHIFT, KC_RALT, KC_RGUI // ********************************************** // * 0xF0-0xFF are unallocated in the HID spec. * // * QMK uses these for Mouse Keys - see below. * // ********************************************** }; /* Media and Function keys */ enum internal_special_keycodes { /* Generic Desktop Page (0x01) */ KC_SYSTEM_POWER = 0xA5, KC_SYSTEM_SLEEP, KC_SYSTEM_WAKE, /* Consumer Page (0x0C) */ KC_AUDIO_MUTE, KC_AUDIO_VOL_UP, KC_AUDIO_VOL_DOWN, KC_MEDIA_NEXT_TRACK, KC_MEDIA_PREV_TRACK, KC_MEDIA_STOP, KC_MEDIA_PLAY_PAUSE, KC_MEDIA_SELECT, KC_MEDIA_EJECT, // 0xB0 KC_MAIL, KC_CALCULATOR, KC_MY_COMPUTER, KC_WWW_SEARCH, KC_WWW_HOME, KC_WWW_BACK, KC_WWW_FORWARD, KC_WWW_STOP, KC_WWW_REFRESH, KC_WWW_FAVORITES, KC_MEDIA_FAST_FORWARD, KC_MEDIA_REWIND, KC_BRIGHTNESS_UP, KC_BRIGHTNESS_DOWN, /* Fn keys */ KC_FN0 = 0xC0, KC_FN1, KC_FN2, KC_FN3, KC_FN4, KC_FN5, KC_FN6, KC_FN7, KC_FN8, KC_FN9, KC_FN10, KC_FN11, KC_FN12, KC_FN13, KC_FN14, KC_FN15, KC_FN16, // 0xD0 KC_FN17, KC_FN18, KC_FN19, KC_FN20, KC_FN21, KC_FN22, KC_FN23, KC_FN24, KC_FN25, KC_FN26, KC_FN27, KC_FN28, KC_FN29, KC_FN30, KC_FN31 }; enum mouse_keys { /* Mouse Buttons */ #ifdef VIA_ENABLE KC_MS_UP = 0xF0, #else KC_MS_UP = 0xED, #endif KC_MS_DOWN, KC_MS_LEFT, KC_MS_RIGHT, // 0xF0 KC_MS_BTN1, KC_MS_BTN2, KC_MS_BTN3, KC_MS_BTN4, KC_MS_BTN5, #ifdef VIA_ENABLE KC_MS_BTN6 = KC_MS_BTN5, KC_MS_BTN7 = KC_MS_BTN5, KC_MS_BTN8 = KC_MS_BTN5, #else KC_MS_BTN6, KC_MS_BTN7, KC_MS_BTN8, #endif /* Mouse Wheel */ KC_MS_WH_UP, KC_MS_WH_DOWN, KC_MS_WH_LEFT, KC_MS_WH_RIGHT, /* Acceleration */ KC_MS_ACCEL0, KC_MS_ACCEL1, KC_MS_ACCEL2 // 0xFF };
ここでは、キーコードの定義を行っている
いくつか、キーの処理に有用そうなマクロも定義されているようだ
quantum_keycodes.h
ソース全体
/* Copyright 2016-2017 Jack Humbert * * 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/>. */ #pragma once #if defined(SEQUENCER_ENABLE) # include "sequencer.h" #endif #ifndef MIDI_ENABLE_STRICT # define MIDI_ENABLE_STRICT 0 #endif #if !MIDI_ENABLE_STRICT || (defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)) # ifndef MIDI_TONE_KEYCODE_OCTAVES # define MIDI_TONE_KEYCODE_OCTAVES 3 # endif #endif // Fillers to make layering more clear #define _______ KC_TRNS #define XXXXXXX KC_NO enum quantum_keycodes { // Ranges used in shortcuts - not to be used directly QK_BASIC = 0x0000, QK_BASIC_MAX = 0x00FF, QK_MODS = 0x0100, QK_LCTL = 0x0100, QK_LSFT = 0x0200, QK_LALT = 0x0400, QK_LGUI = 0x0800, QK_RMODS_MIN = 0x1000, QK_RCTL = 0x1100, QK_RSFT = 0x1200, QK_RALT = 0x1400, QK_RGUI = 0x1800, QK_MODS_MAX = 0x1FFF, QK_FUNCTION = 0x2000, QK_FUNCTION_MAX = 0x2FFF, QK_MACRO = 0x3000, QK_MACRO_MAX = 0x3FFF, QK_LAYER_TAP = 0x4000, QK_LAYER_TAP_MAX = 0x4FFF, QK_TO = 0x5000, QK_TO_MAX = 0x50FF, QK_MOMENTARY = 0x5100, QK_MOMENTARY_MAX = 0x51FF, QK_DEF_LAYER = 0x5200, QK_DEF_LAYER_MAX = 0x52FF, QK_TOGGLE_LAYER = 0x5300, QK_TOGGLE_LAYER_MAX = 0x53FF, QK_ONE_SHOT_LAYER = 0x5400, QK_ONE_SHOT_LAYER_MAX = 0x54FF, QK_ONE_SHOT_MOD = 0x5500, QK_ONE_SHOT_MOD_MAX = 0x55FF, QK_TAP_DANCE = 0x5700, QK_TAP_DANCE_MAX = 0x57FF, QK_LAYER_TAP_TOGGLE = 0x5800, QK_LAYER_TAP_TOGGLE_MAX = 0x58FF, QK_LAYER_MOD = 0x5900, QK_LAYER_MOD_MAX = 0x59FF, QK_STENO = 0x5A00, QK_STENO_BOLT = 0x5A30, QK_STENO_GEMINI = 0x5A31, QK_STENO_MAX = 0x5A3F, QK_SWAP_HANDS = 0x5B00, QK_SWAP_HANDS_MAX = 0x5BFF, QK_MOD_TAP = 0x6000, QK_MOD_TAP_MAX = 0x7FFF, QK_UNICODE = 0x8000, QK_UNICODE_MAX = 0xFFFF, QK_UNICODEMAP = 0x8000, QK_UNICODEMAP_MAX = 0xBFFF, QK_UNICODEMAP_PAIR = 0xC000, QK_UNICODEMAP_PAIR_MAX = 0xFFFF, // Loose keycodes - to be used directly RESET = 0x5C00, DEBUG, MAGIC_SWAP_CONTROL_CAPSLOCK, MAGIC_CAPSLOCK_TO_CONTROL, MAGIC_SWAP_LALT_LGUI, MAGIC_SWAP_RALT_RGUI, MAGIC_NO_GUI, MAGIC_SWAP_GRAVE_ESC, MAGIC_SWAP_BACKSLASH_BACKSPACE, MAGIC_HOST_NKRO, MAGIC_SWAP_ALT_GUI, MAGIC_UNSWAP_CONTROL_CAPSLOCK, MAGIC_UNCAPSLOCK_TO_CONTROL, MAGIC_UNSWAP_LALT_LGUI, MAGIC_UNSWAP_RALT_RGUI, MAGIC_UNNO_GUI, MAGIC_UNSWAP_GRAVE_ESC, MAGIC_UNSWAP_BACKSLASH_BACKSPACE, MAGIC_UNHOST_NKRO, MAGIC_UNSWAP_ALT_GUI, MAGIC_TOGGLE_NKRO, MAGIC_TOGGLE_ALT_GUI, GRAVE_ESC, // Leader key #ifdef LEADER_ENABLE KC_LEAD, #endif // Auto Shift setup #ifndef AUTO_SHIFT_NO_SETUP KC_ASUP, KC_ASDN, KC_ASRP, #endif KC_ASTG, KC_ASON, KC_ASOFF, // Audio on/off/toggle AU_ON, AU_OFF, AU_TOG, // Faux clicky as part of main audio feature CLICKY_TOGGLE, CLICKY_ENABLE, CLICKY_DISABLE, CLICKY_UP, CLICKY_DOWN, CLICKY_RESET, // Music mode on/off/toggle MU_ON, MU_OFF, MU_TOG, // Music mode cycle MU_MOD, // Music voice iterate MUV_IN, MUV_DE, // Midi #if !MIDI_ENABLE_STRICT || (defined(MIDI_ENABLE) && defined(MIDI_BASIC)) MI_ON, MI_OFF, MI_TOG, #endif #if !MIDI_ENABLE_STRICT || (defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)) MIDI_TONE_MIN, # if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 0 MI_C = MIDI_TONE_MIN, MI_Cs, MI_Db = MI_Cs, MI_D, MI_Ds, MI_Eb = MI_Ds, MI_E, MI_F, MI_Fs, MI_Gb = MI_Fs, MI_G, MI_Gs, MI_Ab = MI_Gs, MI_A, MI_As, MI_Bb = MI_As, MI_B, # endif # if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 1 MI_C_1, MI_Cs_1, MI_Db_1 = MI_Cs_1, MI_D_1, MI_Ds_1, MI_Eb_1 = MI_Ds_1, MI_E_1, MI_F_1, MI_Fs_1, MI_Gb_1 = MI_Fs_1, MI_G_1, MI_Gs_1, MI_Ab_1 = MI_Gs_1, MI_A_1, MI_As_1, MI_Bb_1 = MI_As_1, MI_B_1, # endif # if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 2 MI_C_2, MI_Cs_2, MI_Db_2 = MI_Cs_2, MI_D_2, MI_Ds_2, MI_Eb_2 = MI_Ds_2, MI_E_2, MI_F_2, MI_Fs_2, MI_Gb_2 = MI_Fs_2, MI_G_2, MI_Gs_2, MI_Ab_2 = MI_Gs_2, MI_A_2, MI_As_2, MI_Bb_2 = MI_As_2, MI_B_2, # endif # if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 3 MI_C_3, MI_Cs_3, MI_Db_3 = MI_Cs_3, MI_D_3, MI_Ds_3, MI_Eb_3 = MI_Ds_3, MI_E_3, MI_F_3, MI_Fs_3, MI_Gb_3 = MI_Fs_3, MI_G_3, MI_Gs_3, MI_Ab_3 = MI_Gs_3, MI_A_3, MI_As_3, MI_Bb_3 = MI_As_3, MI_B_3, # endif # if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 4 MI_C_4, MI_Cs_4, MI_Db_4 = MI_Cs_4, MI_D_4, MI_Ds_4, MI_Eb_4 = MI_Ds_4, MI_E_4, MI_F_4, MI_Fs_4, MI_Gb_4 = MI_Fs_4, MI_G_4, MI_Gs_4, MI_Ab_4 = MI_Gs_4, MI_A_4, MI_As_4, MI_Bb_4 = MI_As_4, MI_B_4, # endif # if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 5 MI_C_5, MI_Cs_5, MI_Db_5 = MI_Cs_5, MI_D_5, MI_Ds_5, MI_Eb_5 = MI_Ds_5, MI_E_5, MI_F_5, MI_Fs_5, MI_Gb_5 = MI_Fs_5, MI_G_5, MI_Gs_5, MI_Ab_5 = MI_Gs_5, MI_A_5, MI_As_5, MI_Bb_5 = MI_As_5, MI_B_5, # endif # if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 5 MIDI_TONE_MAX = MI_B_5, # elif MIDI_TONE_KEYCODE_OCTAVES > 4 MIDI_TONE_MAX = MI_B_4, # elif MIDI_TONE_KEYCODE_OCTAVES > 3 MIDI_TONE_MAX = MI_B_3, # elif MIDI_TONE_KEYCODE_OCTAVES > 2 MIDI_TONE_MAX = MI_B_2, # elif MIDI_TONE_KEYCODE_OCTAVES > 1 MIDI_TONE_MAX = MI_B_1, # elif MIDI_TONE_KEYCODE_OCTAVES > 0 MIDI_TONE_MAX = MI_B, # endif MIDI_OCTAVE_MIN, MI_OCT_N2 = MIDI_OCTAVE_MIN, MI_OCT_N1, MI_OCT_0, MI_OCT_1, MI_OCT_2, MI_OCT_3, MI_OCT_4, MI_OCT_5, MI_OCT_6, MI_OCT_7, MIDI_OCTAVE_MAX = MI_OCT_7, MI_OCTD, // octave down MI_OCTU, // octave up MIDI_TRANSPOSE_MIN, MI_TRNS_N6 = MIDI_TRANSPOSE_MIN, MI_TRNS_N5, MI_TRNS_N4, MI_TRNS_N3, MI_TRNS_N2, MI_TRNS_N1, MI_TRNS_0, MI_TRNS_1, MI_TRNS_2, MI_TRNS_3, MI_TRNS_4, MI_TRNS_5, MI_TRNS_6, MIDI_TRANSPOSE_MAX = MI_TRNS_6, MI_TRNSD, // transpose down MI_TRNSU, // transpose up MIDI_VELOCITY_MIN, MI_VEL_0 = MIDI_VELOCITY_MIN, # ifdef VIA_ENABLE MI_VEL_1 = MIDI_VELOCITY_MIN, # else MI_VEL_1, # endif 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, MIDI_VELOCITY_MAX = MI_VEL_10, MI_VELD, // velocity down MI_VELU, // velocity up MIDI_CHANNEL_MIN, MI_CH1 = MIDI_CHANNEL_MIN, MI_CH2, MI_CH3, MI_CH4, MI_CH5, MI_CH6, MI_CH7, MI_CH8, MI_CH9, MI_CH10, MI_CH11, MI_CH12, MI_CH13, MI_CH14, MI_CH15, MI_CH16, MIDI_CHANNEL_MAX = MI_CH16, MI_CHD, // previous channel MI_CHU, // next channel MI_ALLOFF, // all notes off MI_SUS, // sustain MI_PORT, // portamento MI_SOST, // sostenuto MI_SOFT, // soft pedal MI_LEG, // legato MI_MOD, // modulation MI_MODSD, // decrease modulation speed MI_MODSU, // increase modulation speed MI_BENDD, // Bend down MI_BENDU, // Bend up #endif // MIDI_ADVANCED // Backlight functionality BL_ON, BL_OFF, BL_DEC, BL_INC, BL_TOGG, BL_STEP, BL_BRTG, // RGB functionality RGB_TOG, RGB_MODE_FORWARD, RGB_MODE_REVERSE, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, RGB_SPI, RGB_SPD, RGB_MODE_PLAIN, RGB_MODE_BREATHE, RGB_MODE_RAINBOW, RGB_MODE_SWIRL, RGB_MODE_SNAKE, RGB_MODE_KNIGHT, RGB_MODE_XMAS, RGB_MODE_GRADIENT, RGB_MODE_RGBTEST, // Momentum matching toggle VLK_TOG, // Left shift, open paren KC_LSPO, // Right shift, close paren KC_RSPC, // Shift, Enter KC_SFTENT, // Printing PRINT_ON, PRINT_OFF, // output selection OUT_AUTO, OUT_USB, #ifdef BLUETOOTH_ENABLE OUT_BT, #endif #ifdef KEY_LOCK_ENABLE KC_LOCK, #endif #ifdef TERMINAL_ENABLE TERM_ON, TERM_OFF, #endif EEPROM_RESET, UNICODE_MODE_FORWARD, UNICODE_MODE_REVERSE, UNICODE_MODE_MAC, UNICODE_MODE_LNX, UNICODE_MODE_WIN, UNICODE_MODE_BSD, UNICODE_MODE_WINC, HPT_ON, HPT_OFF, HPT_TOG, HPT_RST, HPT_FBK, HPT_BUZ, HPT_MODI, HPT_MODD, HPT_CONT, HPT_CONI, HPT_COND, HPT_DWLI, HPT_DWLD, // Left control, open paren KC_LCPO, // Right control, close paren KC_RCPC, // Left control, open paren KC_LAPO, // Right control, close paren KC_RAPC, CMB_ON, CMB_OFF, CMB_TOG, MAGIC_SWAP_LCTL_LGUI, MAGIC_SWAP_RCTL_RGUI, MAGIC_UNSWAP_LCTL_LGUI, MAGIC_UNSWAP_RCTL_RGUI, MAGIC_SWAP_CTL_GUI, MAGIC_UNSWAP_CTL_GUI, MAGIC_TOGGLE_CTL_GUI, MAGIC_EE_HANDS_LEFT, MAGIC_EE_HANDS_RIGHT, // Dynamic Macros DYN_REC_START1, DYN_REC_START2, DYN_REC_STOP, DYN_MACRO_PLAY1, DYN_MACRO_PLAY2, JS_BUTTON0, JS_BUTTON_MIN = JS_BUTTON0, JS_BUTTON1, JS_BUTTON2, JS_BUTTON3, JS_BUTTON4, JS_BUTTON5, JS_BUTTON6, JS_BUTTON7, JS_BUTTON8, JS_BUTTON9, JS_BUTTON10, JS_BUTTON11, JS_BUTTON12, JS_BUTTON13, JS_BUTTON14, JS_BUTTON15, JS_BUTTON16, JS_BUTTON17, JS_BUTTON18, JS_BUTTON19, JS_BUTTON20, JS_BUTTON21, JS_BUTTON22, JS_BUTTON23, JS_BUTTON24, JS_BUTTON25, JS_BUTTON26, JS_BUTTON27, JS_BUTTON28, JS_BUTTON29, JS_BUTTON30, JS_BUTTON31, JS_BUTTON_MAX = JS_BUTTON31, #if defined(SEQUENCER_ENABLE) SQ_ON, SQ_OFF, SQ_TOG, SQ_TMPD, // Decrease tempo SQ_TMPU, // Increase tempo SEQUENCER_RESOLUTION_MIN, SEQUENCER_RESOLUTION_MAX = SEQUENCER_RESOLUTION_MIN + SEQUENCER_RESOLUTIONS, SQ_RESD, // Decrease resolution SQ_RESU, // Increase resolution SQ_SALL, // All steps on SQ_SCLR, // All steps off SEQUENCER_STEP_MIN, SEQUENCER_STEP_MAX = SEQUENCER_STEP_MIN + SEQUENCER_STEPS, SEQUENCER_TRACK_MIN, SEQUENCER_TRACK_MAX = SEQUENCER_TRACK_MIN + SEQUENCER_TRACKS, /** * Helpers to assign a keycode to a step, a resolution, or a track. * Falls back to NOOP if n is out of range. */ # define SQ_S(n) (n < SEQUENCER_STEPS ? SEQUENCER_STEP_MIN + n : XXXXXXX) # define SQ_R(n) (n < SEQUENCER_RESOLUTIONS ? SEQUENCER_RESOLUTION_MIN + n : XXXXXXX) # define SQ_T(n) (n < SEQUENCER_TRACKS ? SEQUENCER_TRACK_MIN + n : XXXXXXX) #endif // always leave at the end SAFE_RANGE }; // Ability to use mods in layouts #define LCTL(kc) (QK_LCTL | (kc)) #define LSFT(kc) (QK_LSFT | (kc)) #define LALT(kc) (QK_LALT | (kc)) #define LGUI(kc) (QK_LGUI | (kc)) #define LOPT(kc) LALT(kc) #define LCMD(kc) LGUI(kc) #define LWIN(kc) LGUI(kc) #define RCTL(kc) (QK_RCTL | (kc)) #define RSFT(kc) (QK_RSFT | (kc)) #define RALT(kc) (QK_RALT | (kc)) #define RGUI(kc) (QK_RGUI | (kc)) #define ALGR(kc) RALT(kc) #define ROPT(kc) RALT(kc) #define RCMD(kc) RGUI(kc) #define RWIN(kc) RGUI(kc) #define HYPR(kc) (QK_LCTL | QK_LSFT | QK_LALT | QK_LGUI | (kc)) #define MEH(kc) (QK_LCTL | QK_LSFT | QK_LALT | (kc)) #define LCAG(kc) (QK_LCTL | QK_LALT | QK_LGUI | (kc)) #define SGUI(kc) (QK_LGUI | QK_LSFT | (kc)) #define SCMD(kc) SGUI(kc) #define SWIN(kc) SGUI(kc) #define LCA(kc) (QK_LCTL | QK_LALT | (kc)) #define LSA(kc) (QK_LSFT | QK_LALT | (kc)) #define RSA(kc) (QK_RSFT | QK_RALT | (kc)) #define RCS(kc) (QK_RCTL | QK_RSFT | (kc)) #define SAGR(kc) RSA(kc) #define MOD_HYPR 0xF #define MOD_MEH 0x7 // Aliases for shifted symbols // Each key has a 4-letter code, and some have longer aliases too. // While the long aliases are descriptive, the 4-letter codes // make for nicer grid layouts (everything lines up), and are // the preferred style for Quantum. #define KC_TILD LSFT(KC_GRV) // ~ #define KC_TILDE KC_TILD #define KC_EXLM LSFT(KC_1) // ! #define KC_EXCLAIM KC_EXLM #define KC_AT LSFT(KC_2) // @ #define KC_HASH LSFT(KC_3) // # #define KC_DLR LSFT(KC_4) // $ #define KC_DOLLAR KC_DLR #define KC_PERC LSFT(KC_5) // % #define KC_PERCENT KC_PERC #define KC_CIRC LSFT(KC_6) // ^ #define KC_CIRCUMFLEX KC_CIRC #define KC_AMPR LSFT(KC_7) // & #define KC_AMPERSAND KC_AMPR #define KC_ASTR LSFT(KC_8) // * #define KC_ASTERISK KC_ASTR #define KC_LPRN LSFT(KC_9) // ( #define KC_LEFT_PAREN KC_LPRN #define KC_RPRN LSFT(KC_0) // ) #define KC_RIGHT_PAREN KC_RPRN #define KC_UNDS LSFT(KC_MINS) // _ #define KC_UNDERSCORE KC_UNDS #define KC_PLUS LSFT(KC_EQL) // + #define KC_LCBR LSFT(KC_LBRC) // { #define KC_LEFT_CURLY_BRACE KC_LCBR #define KC_RCBR LSFT(KC_RBRC) // } #define KC_RIGHT_CURLY_BRACE KC_RCBR #define KC_LABK LSFT(KC_COMM) // < #define KC_LEFT_ANGLE_BRACKET KC_LABK #define KC_RABK LSFT(KC_DOT) // > #define KC_RIGHT_ANGLE_BRACKET KC_RABK #define KC_COLN LSFT(KC_SCLN) // : #define KC_COLON KC_COLN #define KC_PIPE LSFT(KC_BSLS) // | #define KC_LT LSFT(KC_COMM) // < #define KC_GT LSFT(KC_DOT) // > #define KC_QUES LSFT(KC_SLSH) // ? #define KC_QUESTION KC_QUES #define KC_DQT LSFT(KC_QUOT) // " #define KC_DOUBLE_QUOTE KC_DQT #define KC_DQUO KC_DQT #define KC_DELT KC_DELETE // Del key (four letter code) // Alias for function layers than expand past FN31 #define FUNC(kc) (QK_FUNCTION | (kc)) // Aliases #define C(kc) LCTL(kc) #define S(kc) LSFT(kc) #define A(kc) LALT(kc) #define G(kc) LGUI(kc) #define F(kc) FUNC(kc) #define M(kc) (QK_MACRO | (kc)) #define MACROTAP(kc) (QK_MACRO | (FUNC_TAP << 8) | (kc)) #define MACRODOWN(...) (record->event.pressed ? MACRO(__VA_ARGS__) : MACRO_NONE) #define KC_GESC GRAVE_ESC #define EEP_RST EEPROM_RESET #define CK_TOGG CLICKY_TOGGLE #define CK_RST CLICKY_RESET #define CK_UP CLICKY_UP #define CK_DOWN CLICKY_DOWN #define CK_ON CLICKY_ENABLE #define CK_OFF CLICKY_DISABLE #define FC_ON CLICKY_ENABLE #define FC_OFF CLICKY_DISABLE #define FC_TOGG CLICKY_TOGGLE #define RGB_MOD RGB_MODE_FORWARD #define RGB_RMOD RGB_MODE_REVERSE #define RGB_M_P RGB_MODE_PLAIN #define RGB_M_B RGB_MODE_BREATHE #define RGB_M_R RGB_MODE_RAINBOW #define RGB_M_SW RGB_MODE_SWIRL #define RGB_M_SN RGB_MODE_SNAKE #define RGB_M_K RGB_MODE_KNIGHT #define RGB_M_X RGB_MODE_XMAS #define RGB_M_G RGB_MODE_GRADIENT #define RGB_M_T RGB_MODE_RGBTEST // L-ayer, T-ap - 256 keycode max, 16 layer max #define LT(layer, kc) (QK_LAYER_TAP | (((layer)&0xF) << 8) | ((kc)&0xFF)) #define CL_SWAP MAGIC_SWAP_CONTROL_CAPSLOCK #define CL_NORM MAGIC_UNSWAP_CONTROL_CAPSLOCK #define CL_CTRL MAGIC_CAPSLOCK_TO_CONTROL #define CL_CAPS MAGIC_UNCAPSLOCK_TO_CONTROL #define LCG_SWP MAGIC_SWAP_LCTL_LGUI #define LCG_NRM MAGIC_UNSWAP_LCTL_LGUI #define RCG_SWP MAGIC_SWAP_RCTL_RGUI #define RCG_NRM MAGIC_UNSWAP_RCTL_RGUI #define CG_SWAP MAGIC_SWAP_CTL_GUI #define CG_NORM MAGIC_UNSWAP_CTL_GUI #define CG_TOGG MAGIC_TOGGLE_CTL_GUI #define LAG_SWP MAGIC_SWAP_LALT_LGUI #define LAG_NRM MAGIC_UNSWAP_LALT_LGUI #define RAG_SWP MAGIC_SWAP_RALT_RGUI #define RAG_NRM MAGIC_UNSWAP_RALT_RGUI #define AG_SWAP MAGIC_SWAP_ALT_GUI #define AG_NORM MAGIC_UNSWAP_ALT_GUI #define AG_TOGG MAGIC_TOGGLE_ALT_GUI #define GUI_OFF MAGIC_NO_GUI #define GUI_ON MAGIC_UNNO_GUI #define GE_SWAP MAGIC_SWAP_GRAVE_ESC #define GE_NORM MAGIC_UNSWAP_GRAVE_ESC #define BS_SWAP MAGIC_SWAP_BACKSLASH_BACKSPACE #define BS_NORM MAGIC_UNSWAP_BACKSLASH_BACKSPACE #define NK_ON MAGIC_HOST_NKRO #define NK_OFF MAGIC_UNHOST_NKRO #define NK_TOGG MAGIC_TOGGLE_NKRO #define EH_LEFT MAGIC_EE_HANDS_LEFT #define EH_RGHT MAGIC_EE_HANDS_RIGHT // GOTO layer - 16 layers max // when: // ON_PRESS = 1 // ON_RELEASE = 2 // Unless you have a good reason not to do so, prefer ON_PRESS (1) as your default. // In fact, we changed it to assume ON_PRESS for sanity/simplicity. If needed, you can add your own // keycode modeled after the old version, kept below for this. /* #define TO(layer, when) (QK_TO | (when << 0x4) | (layer & 0xFF)) */ #define TO(layer) (QK_TO | (ON_PRESS << 0x4) | ((layer)&0xFF)) // Momentary switch layer - 256 layer max #define MO(layer) (QK_MOMENTARY | ((layer)&0xFF)) // Set default layer - 256 layer max #define DF(layer) (QK_DEF_LAYER | ((layer)&0xFF)) // Toggle to layer - 256 layer max #define TG(layer) (QK_TOGGLE_LAYER | ((layer)&0xFF)) // One-shot layer - 256 layer max #define OSL(layer) (QK_ONE_SHOT_LAYER | ((layer)&0xFF)) // L-ayer M-od: Momentary switch layer with modifiers active - 16 layer max, left mods only #define LM(layer, mod) (QK_LAYER_MOD | (((layer)&0xF) << 4) | ((mod)&0xF)) // One-shot mod #define OSM(mod) (QK_ONE_SHOT_MOD | ((mod)&0xFF)) // Layer tap-toggle #define TT(layer) (QK_LAYER_TAP_TOGGLE | ((layer)&0xFF)) // M-od, T-ap - 256 keycode max #define MT(mod, kc) (QK_MOD_TAP | (((mod)&0x1F) << 8) | ((kc)&0xFF)) #define LCTL_T(kc) MT(MOD_LCTL, kc) #define RCTL_T(kc) MT(MOD_RCTL, kc) #define CTL_T(kc) LCTL_T(kc) #define LSFT_T(kc) MT(MOD_LSFT, kc) #define RSFT_T(kc) MT(MOD_RSFT, kc) #define SFT_T(kc) LSFT_T(kc) #define LALT_T(kc) MT(MOD_LALT, kc) #define RALT_T(kc) MT(MOD_RALT, kc) #define LOPT_T(kc) LALT_T(kc) #define ROPT_T(kc) RALT_T(kc) #define ALGR_T(kc) RALT_T(kc) #define ALT_T(kc) LALT_T(kc) #define OPT_T(kc) LOPT_T(kc) #define LGUI_T(kc) MT(MOD_LGUI, kc) #define RGUI_T(kc) MT(MOD_RGUI, kc) #define LCMD_T(kc) LGUI_T(kc) #define LWIN_T(kc) LGUI_T(kc) #define RCMD_T(kc) RGUI_T(kc) #define RWIN_T(kc) RGUI_T(kc) #define GUI_T(kc) LGUI_T(kc) #define CMD_T(kc) LCMD_T(kc) #define WIN_T(kc) LWIN_T(kc) #define C_S_T(kc) MT(MOD_LCTL | MOD_LSFT, kc) // Left Control + Shift e.g. for gnome-terminal #define MEH_T(kc) MT(MOD_LCTL | MOD_LSFT | MOD_LALT, kc) // Meh is a less hyper version of the Hyper key -- doesn't include GUI, so just Left Control + Shift + Alt #define LCAG_T(kc) MT(MOD_LCTL | MOD_LALT | MOD_LGUI, kc) // Left Control + Alt + GUI #define RCAG_T(kc) MT(MOD_RCTL | MOD_RALT | MOD_RGUI, kc) // Right Control + Alt + GUI #define HYPR_T(kc) MT(MOD_LCTL | MOD_LSFT | MOD_LALT | MOD_LGUI, kc) // see http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/ #define SGUI_T(kc) MT(MOD_LGUI | MOD_LSFT, kc) // Left Shift + GUI #define SCMD_T(kc) SGUI_T(kc) #define SWIN_T(kc) SGUI_T(kc) #define LCA_T(kc) MT(MOD_LCTL | MOD_LALT, kc) // Left Control + Alt #define LSA_T(kc) MT(MOD_LSFT | MOD_LALT, kc) // Left Shift + Alt #define RSA_T(kc) MT(MOD_RSFT | MOD_RALT, kc) // Right Shift + Alt #define RCS_T(kc) MT(MOD_RCTL | MOD_RSFT, kc) // Right Control + Shift #define SAGR_T(kc) RSA_T(kc) #define ALL_T(kc) HYPR_T(kc) // Dedicated keycode versions for Hyper and Meh, if you want to use them as standalone keys rather than mod-tap #define KC_HYPR HYPR(KC_NO) #define KC_MEH MEH(KC_NO) // UNICODE_ENABLE - Allows Unicode input up to 0x7FFF #define UC(c) (QK_UNICODE | (c)) // UNICODEMAP_ENABLE - Allows Unicode input up to 0x10FFFF, requires unicode_map #define X(i) (QK_UNICODEMAP | (i)) #define XP(i, j) (QK_UNICODEMAP_PAIR | ((i)&0x7F) | (((j)&0x7F) << 7)) // 127 max i and j #define UC_MOD UNICODE_MODE_FORWARD #define UC_RMOD UNICODE_MODE_REVERSE #define UC_M_MA UNICODE_MODE_MAC #define UNICODE_MODE_OSX UNICODE_MODE_MAC // Deprecated alias #define UC_M_OS UNICODE_MODE_MAC // Deprecated alias #define UC_M_LN UNICODE_MODE_LNX #define UC_M_WI UNICODE_MODE_WIN #define UC_M_BS UNICODE_MODE_BSD #define UC_M_WC UNICODE_MODE_WINC #define SH_T(kc) (QK_SWAP_HANDS | (kc)) #define SH_TG (QK_SWAP_HANDS | OP_SH_TOGGLE) #define SH_TT (QK_SWAP_HANDS | OP_SH_TAP_TOGGLE) #define SH_OS (QK_SWAP_HANDS | OP_SH_ONESHOT) #define SH_MON (QK_SWAP_HANDS | OP_SH_ON_OFF) #define SH_MOFF (QK_SWAP_HANDS | OP_SH_OFF_ON) #define SH_ON (QK_SWAP_HANDS | OP_SH_ON) #define SH_OFF (QK_SWAP_HANDS | OP_SH_OFF) // Dynamic Macros aliases #define DM_REC1 DYN_REC_START1 #define DM_REC2 DYN_REC_START2 #define DM_RSTP DYN_REC_STOP #define DM_PLY1 DYN_MACRO_PLAY1 #define DM_PLY2 DYN_MACRO_PLAY2
ここでは QMK 固有のキーコードやマクロが定義されている
keycode_config.h
ソース全体
/* Copyright 2016 Jack Humbert * * 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/>. */ #pragma once #include "eeconfig.h" #include "keycode.h" #include "action_code.h" uint16_t keycode_config(uint16_t keycode); uint8_t mod_config(uint8_t mod); /* NOTE: Not portable. Bit field order depends on implementation */ typedef union { uint16_t raw; struct { bool swap_control_capslock : 1; bool capslock_to_control : 1; bool swap_lalt_lgui : 1; bool swap_ralt_rgui : 1; bool no_gui : 1; bool swap_grave_esc : 1; bool swap_backslash_backspace : 1; bool nkro : 1; bool swap_lctl_lgui : 1; bool swap_rctl_rgui : 1; }; } keymap_config_t; extern keymap_config_t keymap_config;
ここでは、キーボードの動作にかかわる設定を定義しているようだ
keycode_config.c
ソース全体
/* Copyright 2016 Jack Humbert * * 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 "keycode_config.h" extern keymap_config_t keymap_config; /** \brief keycode_config * * This function is used to check a specific keycode against the bootmagic config, * and will return the corrected keycode, when appropriate. */ uint16_t keycode_config(uint16_t keycode) { switch (keycode) { case KC_CAPSLOCK: case KC_LOCKING_CAPS: if (keymap_config.swap_control_capslock || keymap_config.capslock_to_control) { return KC_LCTL; } return keycode; case KC_LCTL: if (keymap_config.swap_control_capslock) { return KC_CAPSLOCK; } if (keymap_config.swap_lctl_lgui) { if (keymap_config.no_gui) { return KC_NO; } return KC_LGUI; } return KC_LCTL; case KC_LALT: if (keymap_config.swap_lalt_lgui) { if (keymap_config.no_gui) { return KC_NO; } return KC_LGUI; } return KC_LALT; case KC_LGUI: if (keymap_config.swap_lalt_lgui) { return KC_LALT; } if (keymap_config.swap_lctl_lgui) { return KC_LCTRL; } if (keymap_config.no_gui) { return KC_NO; } return KC_LGUI; case KC_RCTL: if (keymap_config.swap_rctl_rgui) { if (keymap_config.no_gui) { return KC_NO; } return KC_RGUI; } return KC_RCTL; case KC_RALT: if (keymap_config.swap_ralt_rgui) { if (keymap_config.no_gui) { return KC_NO; } return KC_RGUI; } return KC_RALT; case KC_RGUI: if (keymap_config.swap_ralt_rgui) { return KC_RALT; } if (keymap_config.swap_rctl_rgui) { return KC_RCTL; } if (keymap_config.no_gui) { return KC_NO; } return KC_RGUI; case KC_GRAVE: if (keymap_config.swap_grave_esc) { return KC_ESC; } return KC_GRAVE; case KC_ESC: if (keymap_config.swap_grave_esc) { return KC_GRAVE; } return KC_ESC; case KC_BSLASH: if (keymap_config.swap_backslash_backspace) { return KC_BSPACE; } return KC_BSLASH; case KC_BSPACE: if (keymap_config.swap_backslash_backspace) { return KC_BSLASH; } return KC_BSPACE; default: return keycode; } } /** \brief mod_config * * This function checks the mods passed to it against the bootmagic config, * and will remove or replace mods, based on that. */ uint8_t mod_config(uint8_t mod) { if (keymap_config.swap_lalt_lgui) { if ((mod & MOD_RGUI) == MOD_LGUI) { mod &= ~MOD_LGUI; mod |= MOD_LALT; } else if ((mod & MOD_RALT) == MOD_LALT) { mod &= ~MOD_LALT; mod |= MOD_LGUI; } } if (keymap_config.swap_ralt_rgui) { if ((mod & MOD_RGUI) == MOD_RGUI) { mod &= ~MOD_RGUI; mod |= MOD_RALT; } else if ((mod & MOD_RALT) == MOD_RALT) { mod &= ~MOD_RALT; mod |= MOD_RGUI; } } if (keymap_config.swap_lctl_lgui) { if ((mod & MOD_RGUI) == MOD_LGUI) { mod &= ~MOD_LGUI; mod |= MOD_LCTL; } else if ((mod & MOD_RCTL) == MOD_LCTL) { mod &= ~MOD_LCTL; mod |= MOD_LGUI; } } if (keymap_config.swap_rctl_rgui) { if ((mod & MOD_RGUI) == MOD_RGUI) { mod &= ~MOD_RGUI; mod |= MOD_RCTL; } else if ((mod & MOD_RCTL) == MOD_RCTL) { mod &= ~MOD_RCTL; mod |= MOD_RGUI; } } if (keymap_config.no_gui) { mod &= ~MOD_LGUI; mod &= ~MOD_RGUI; } return mod; }
keycode_config.h
で定義されている設定用構造体 keymap_config_t
の設定値をもとに、キーコードの変換を行っている
debug.h
ソース全体
/* Copyright 2011 Jun Wako <wakojun@gmail.com> 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/>. */ #pragma once #include <stdbool.h> #include "print.h" #ifdef __cplusplus extern "C" { #endif /* * Debug output control */ typedef union { struct { bool enable : 1; bool matrix : 1; bool keyboard : 1; bool mouse : 1; uint8_t reserved : 4; }; uint8_t raw; } debug_config_t; extern debug_config_t debug_config; #ifdef __cplusplus } #endif /* for backward compatibility */ #define debug_enable (debug_config.enable) #define debug_matrix (debug_config.matrix) #define debug_keyboard (debug_config.keyboard) #define debug_mouse (debug_config.mouse) /* * Debug print utils */ #ifndef NO_DEBUG # define dprint(s) \ do { \ if (debug_enable) print(s); \ } while (0) # define dprintln(s) \ do { \ if (debug_enable) println(s); \ } while (0) # define dprintf(fmt, ...) \ do { \ if (debug_enable) xprintf(fmt, ##__VA_ARGS__); \ } while (0) # define dmsg(s) dprintf("%s at %s: %S\n", __FILE__, __LINE__, PSTR(s)) /* Deprecated. DO NOT USE these anymore, use dprintf instead. */ # define debug(s) \ do { \ if (debug_enable) print(s); \ } while (0) # define debugln(s) \ do { \ if (debug_enable) println(s); \ } while (0) # define debug_msg(s) \ do { \ if (debug_enable) { \ print(__FILE__); \ print(" at "); \ print_dec(__LINE__); \ print(" in "); \ print(": "); \ print(s); \ } \ } while (0) # define debug_dec(data) \ do { \ if (debug_enable) print_dec(data); \ } while (0) # define debug_decs(data) \ do { \ if (debug_enable) print_decs(data); \ } while (0) # define debug_hex4(data) \ do { \ if (debug_enable) print_hex4(data); \ } while (0) # define debug_hex8(data) \ do { \ if (debug_enable) print_hex8(data); \ } while (0) # define debug_hex16(data) \ do { \ if (debug_enable) print_hex16(data); \ } while (0) # define debug_hex32(data) \ do { \ if (debug_enable) print_hex32(data); \ } while (0) # define debug_bin8(data) \ do { \ if (debug_enable) print_bin8(data); \ } while (0) # define debug_bin16(data) \ do { \ if (debug_enable) print_bin16(data); \ } while (0) # define debug_bin32(data) \ do { \ if (debug_enable) print_bin32(data); \ } while (0) # define debug_bin_reverse8(data) \ do { \ if (debug_enable) print_bin_reverse8(data); \ } while (0) # define debug_bin_reverse16(data) \ do { \ if (debug_enable) print_bin_reverse16(data); \ } while (0) # define debug_bin_reverse32(data) \ do { \ if (debug_enable) print_bin_reverse32(data); \ } while (0) # define debug_hex(data) debug_hex8(data) # define debug_bin(data) debug_bin8(data) # define debug_bin_reverse(data) debug_bin8(data) #else /* NO_DEBUG */ # define dprint(s) # define dprintln(s) # define dprintf(fmt, ...) # define dmsg(s) # define debug(s) # define debugln(s) # define debug_msg(s) # define debug_dec(data) # define debug_decs(data) # define debug_hex4(data) # define debug_hex8(data) # define debug_hex16(data) # define debug_hex32(data) # define debug_bin8(data) # define debug_bin16(data) # define debug_bin32(data) # define debug_bin_reverse8(data) # define debug_bin_reverse16(data) # define debug_bin_reverse32(data) # define debug_hex(data) # define debug_bin(data) # define debug_bin_reverse(data) #endif /* NO_DEBUG */
ファイル名が示す通り、デバッグ用の関数の定義である
各関数により、コンソールに所望のフォーマットでデータが出力されると思われる
debug.c
ソース全体
/* Copyright 2011 Jun Wako <wakojun@gmail.com> 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 "debug.h" debug_config_t debug_config = { .enable = false, // .matrix = false, // .keyboard = false, // .mouse = false, // .reserved = 0 // };
デフォルトではデバッグ出力が行われないように設定しているようだ
report.h
ソース全体
/* Copyright 2011,2012 Jun Wako <wakojun@gmail.com> 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/>. */ #pragma once #include <stdint.h> #include <stdbool.h> #include "keycode.h" // clang-format off /* HID report IDs */ enum hid_report_ids { REPORT_ID_KEYBOARD = 1, REPORT_ID_MOUSE, REPORT_ID_SYSTEM, REPORT_ID_CONSUMER, REPORT_ID_NKRO, REPORT_ID_JOYSTICK }; /* Mouse buttons */ #define MOUSE_BTN_MASK(n) (1 << (n)) enum mouse_buttons { MOUSE_BTN1 = MOUSE_BTN_MASK(0), MOUSE_BTN2 = MOUSE_BTN_MASK(1), MOUSE_BTN3 = MOUSE_BTN_MASK(2), MOUSE_BTN4 = MOUSE_BTN_MASK(3), MOUSE_BTN5 = MOUSE_BTN_MASK(4), MOUSE_BTN6 = MOUSE_BTN_MASK(5), MOUSE_BTN7 = MOUSE_BTN_MASK(6), MOUSE_BTN8 = MOUSE_BTN_MASK(7) }; /* Consumer Page (0x0C) * * See https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf#page=75 */ enum consumer_usages { // 15.5 Display Controls SNAPSHOT = 0x065, BRIGHTNESS_UP = 0x06F, // https://www.usb.org/sites/default/files/hutrr41_0.pdf BRIGHTNESS_DOWN = 0x070, // 15.7 Transport Controls TRANSPORT_RECORD = 0x0B2, TRANSPORT_FAST_FORWARD = 0x0B3, TRANSPORT_REWIND = 0x0B4, TRANSPORT_NEXT_TRACK = 0x0B5, TRANSPORT_PREV_TRACK = 0x0B6, TRANSPORT_STOP = 0x0B7, TRANSPORT_EJECT = 0x0B8, TRANSPORT_RANDOM_PLAY = 0x0B9, TRANSPORT_STOP_EJECT = 0x0CC, TRANSPORT_PLAY_PAUSE = 0x0CD, // 15.9.1 Audio Controls - Volume AUDIO_MUTE = 0x0E2, AUDIO_VOL_UP = 0x0E9, AUDIO_VOL_DOWN = 0x0EA, // 15.15 Application Launch Buttons AL_CC_CONFIG = 0x183, AL_EMAIL = 0x18A, AL_CALCULATOR = 0x192, AL_LOCAL_BROWSER = 0x194, AL_LOCK = 0x19E, AL_CONTROL_PANEL = 0x19F, AL_ASSISTANT = 0x1CB, AL_KEYBOARD_LAYOUT = 0x1AE, // 15.16 Generic GUI Application Controls AC_MINIMIZE = 0x206, AC_SEARCH = 0x221, AC_HOME = 0x223, AC_BACK = 0x224, AC_FORWARD = 0x225, AC_STOP = 0x226, AC_REFRESH = 0x227, AC_BOOKMARKS = 0x22A }; /* Generic Desktop Page (0x01) * * See https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf#page=26 */ enum desktop_usages { // 4.5.1 System Controls - Power Controls SYSTEM_POWER_DOWN = 0x81, SYSTEM_SLEEP = 0x82, SYSTEM_WAKE_UP = 0x83 }; // clang-format on #define NKRO_SHARED_EP /* key report size(NKRO or boot mode) */ #if defined(NKRO_ENABLE) # if defined(PROTOCOL_LUFA) || defined(PROTOCOL_CHIBIOS) # include "protocol/usb_descriptor.h" # define KEYBOARD_REPORT_BITS (SHARED_EPSIZE - 2) # elif defined(PROTOCOL_ARM_ATSAM) # include "protocol/arm_atsam/usb/udi_device_epsize.h" # define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1) # undef NKRO_SHARED_EP # undef MOUSE_SHARED_EP # else # error "NKRO not supported with this protocol" # endif #endif #ifdef KEYBOARD_SHARED_EP # define KEYBOARD_REPORT_SIZE 9 #else # define KEYBOARD_REPORT_SIZE 8 #endif #define KEYBOARD_REPORT_KEYS 6 #ifdef __cplusplus extern "C" { #endif /* * keyboard report is 8-byte array retains state of 8 modifiers and 6 keys. * * byte |0 |1 |2 |3 |4 |5 |6 |7 * -----+--------+--------+--------+--------+--------+--------+--------+-------- * desc |mods |reserved|keys[0] |keys[1] |keys[2] |keys[3] |keys[4] |keys[5] * * It is exended to 16 bytes to retain 120keys+8mods when NKRO mode. * * byte |0 |1 |2 |3 |4 |5 |6 |7 ... |15 * -----+--------+--------+--------+--------+--------+--------+--------+-------- +-------- * desc |mods |bits[0] |bits[1] |bits[2] |bits[3] |bits[4] |bits[5] |bits[6] ... |bit[14] * * mods retains state of 8 modifiers. * * bit |0 |1 |2 |3 |4 |5 |6 |7 * -----+--------+--------+--------+--------+--------+--------+--------+-------- * desc |Lcontrol|Lshift |Lalt |Lgui |Rcontrol|Rshift |Ralt |Rgui * */ typedef union { uint8_t raw[KEYBOARD_REPORT_SIZE]; struct { #ifdef KEYBOARD_SHARED_EP uint8_t report_id; #endif uint8_t mods; uint8_t reserved; uint8_t keys[KEYBOARD_REPORT_KEYS]; }; #ifdef NKRO_ENABLE struct nkro_report { # ifdef NKRO_SHARED_EP uint8_t report_id; # endif uint8_t mods; uint8_t bits[KEYBOARD_REPORT_BITS]; } nkro; #endif } __attribute__((packed)) report_keyboard_t; typedef struct { uint8_t report_id; uint16_t usage; } __attribute__((packed)) report_extra_t; typedef struct { #ifdef MOUSE_SHARED_EP uint8_t report_id; #endif uint8_t buttons; int8_t x; int8_t y; int8_t v; int8_t h; } __attribute__((packed)) report_mouse_t; typedef struct { #if JOYSTICK_AXES_COUNT > 0 # if JOYSTICK_AXES_RESOLUTION > 8 int16_t axes[JOYSTICK_AXES_COUNT]; # else int8_t axes[JOYSTICK_AXES_COUNT]; # endif #endif #if JOYSTICK_BUTTON_COUNT > 0 uint8_t buttons[(JOYSTICK_BUTTON_COUNT - 1) / 8 + 1]; #endif } __attribute__((packed)) joystick_report_t; /* keycode to system usage */ static inline uint16_t KEYCODE2SYSTEM(uint8_t key) { switch (key) { case KC_SYSTEM_POWER: return SYSTEM_POWER_DOWN; case KC_SYSTEM_SLEEP: return SYSTEM_SLEEP; case KC_SYSTEM_WAKE: return SYSTEM_WAKE_UP; default: return 0; } } /* keycode to consumer usage */ static inline uint16_t KEYCODE2CONSUMER(uint8_t key) { switch (key) { case KC_AUDIO_MUTE: return AUDIO_MUTE; case KC_AUDIO_VOL_UP: return AUDIO_VOL_UP; case KC_AUDIO_VOL_DOWN: return AUDIO_VOL_DOWN; case KC_MEDIA_NEXT_TRACK: return TRANSPORT_NEXT_TRACK; case KC_MEDIA_PREV_TRACK: return TRANSPORT_PREV_TRACK; case KC_MEDIA_FAST_FORWARD: return TRANSPORT_FAST_FORWARD; case KC_MEDIA_REWIND: return TRANSPORT_REWIND; case KC_MEDIA_STOP: return TRANSPORT_STOP; case KC_MEDIA_EJECT: return TRANSPORT_STOP_EJECT; case KC_MEDIA_PLAY_PAUSE: return TRANSPORT_PLAY_PAUSE; case KC_MEDIA_SELECT: return AL_CC_CONFIG; case KC_MAIL: return AL_EMAIL; case KC_CALCULATOR: return AL_CALCULATOR; case KC_MY_COMPUTER: return AL_LOCAL_BROWSER; case KC_WWW_SEARCH: return AC_SEARCH; case KC_WWW_HOME: return AC_HOME; case KC_WWW_BACK: return AC_BACK; case KC_WWW_FORWARD: return AC_FORWARD; case KC_WWW_STOP: return AC_STOP; case KC_WWW_REFRESH: return AC_REFRESH; case KC_BRIGHTNESS_UP: return BRIGHTNESS_UP; case KC_BRIGHTNESS_DOWN: return BRIGHTNESS_DOWN; case KC_WWW_FAVORITES: return AC_BOOKMARKS; default: return 0; } } uint8_t has_anykey(report_keyboard_t* keyboard_report); uint8_t get_first_key(report_keyboard_t* keyboard_report); bool is_key_pressed(report_keyboard_t* keyboard_report, uint8_t key); void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code); void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code); #ifdef NKRO_ENABLE void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code); void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code); #endif void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key); void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key); void clear_keys_from_report(report_keyboard_t* keyboard_report); #ifdef __cplusplus } #endif
HID デバイスとしてレポートを送る(データを送る)ためにデータ(押されたキー、マウスのボタン、マウスの移動量など)をフォーマットするための関数や変数が定義されているようだ
プログラム内で取り回しをよくするため、キーボード用には共用体 report_keyboard_t
、その他のデータ用に構造体 report_extra_t
、マウス用に構造体 report_mouse_t
、ジョイスティック用に構造体 joystick_report_t
がデータストアとして用意されている
report.c
ソース全体
/* 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 "report.h" #include "host.h" #include "keycode_config.h" #include "debug.h" #include "util.h" #include <string.h> /** \brief has_anykey * * FIXME: Needs doc */ uint8_t has_anykey(report_keyboard_t* keyboard_report) { uint8_t cnt = 0; uint8_t* p = keyboard_report->keys; uint8_t lp = sizeof(keyboard_report->keys); #ifdef NKRO_ENABLE if (keyboard_protocol && keymap_config.nkro) { p = keyboard_report->nkro.bits; lp = sizeof(keyboard_report->nkro.bits); } #endif while (lp--) { if (*p++) cnt++; } return cnt; } /** \brief get_first_key * * FIXME: Needs doc */ uint8_t get_first_key(report_keyboard_t* keyboard_report) { #ifdef NKRO_ENABLE if (keyboard_protocol && keymap_config.nkro) { uint8_t i = 0; for (; i < KEYBOARD_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++) ; return i << 3 | biton(keyboard_report->nkro.bits[i]); } #endif #ifdef USB_6KRO_ENABLE uint8_t i = cb_head; do { if (keyboard_report->keys[i] != 0) { break; } i = RO_INC(i); } while (i != cb_tail); return keyboard_report->keys[i]; #else return keyboard_report->keys[0]; #endif } /** \brief Checks if a key is pressed in the report * * Returns true if the keyboard_report reports that the key is pressed, otherwise false * Note: The function doesn't support modifers currently, and it returns false for KC_NO */ bool is_key_pressed(report_keyboard_t* keyboard_report, uint8_t key) { if (key == KC_NO) { return false; } #ifdef NKRO_ENABLE if (keyboard_protocol && keymap_config.nkro) { if ((key >> 3) < KEYBOARD_REPORT_BITS) { return keyboard_report->nkro.bits[key >> 3] & 1 << (key & 7); } else { return false; } } #endif for (int i = 0; i < KEYBOARD_REPORT_KEYS; i++) { if (keyboard_report->keys[i] == key) { return true; } } return false; } /** \brief add key byte * * FIXME: Needs doc */ void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code) { #ifdef USB_6KRO_ENABLE int8_t i = cb_head; int8_t empty = -1; if (cb_count) { do { if (keyboard_report->keys[i] == code) { return; } if (empty == -1 && keyboard_report->keys[i] == 0) { empty = i; } i = RO_INC(i); } while (i != cb_tail); if (i == cb_tail) { if (cb_tail == cb_head) { // buffer is full if (empty == -1) { // pop head when has no empty space cb_head = RO_INC(cb_head); cb_count--; } else { // left shift when has empty space uint8_t offset = 1; i = RO_INC(empty); do { if (keyboard_report->keys[i] != 0) { keyboard_report->keys[empty] = keyboard_report->keys[i]; keyboard_report->keys[i] = 0; empty = RO_INC(empty); } else { offset++; } i = RO_INC(i); } while (i != cb_tail); cb_tail = RO_SUB(cb_tail, offset); } } } } // add to tail keyboard_report->keys[cb_tail] = code; cb_tail = RO_INC(cb_tail); cb_count++; #else int8_t i = 0; int8_t empty = -1; for (; i < KEYBOARD_REPORT_KEYS; i++) { if (keyboard_report->keys[i] == code) { break; } if (empty == -1 && keyboard_report->keys[i] == 0) { empty = i; } } if (i == KEYBOARD_REPORT_KEYS) { if (empty != -1) { keyboard_report->keys[empty] = code; } } #endif } /** \brief del key byte * * FIXME: Needs doc */ void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code) { #ifdef USB_6KRO_ENABLE uint8_t i = cb_head; if (cb_count) { do { if (keyboard_report->keys[i] == code) { keyboard_report->keys[i] = 0; cb_count--; if (cb_count == 0) { // reset head and tail cb_tail = cb_head = 0; } if (i == RO_DEC(cb_tail)) { // left shift when next to tail do { cb_tail = RO_DEC(cb_tail); if (keyboard_report->keys[RO_DEC(cb_tail)] != 0) { break; } } while (cb_tail != cb_head); } break; } i = RO_INC(i); } while (i != cb_tail); } #else for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) { if (keyboard_report->keys[i] == code) { keyboard_report->keys[i] = 0; } } #endif } #ifdef NKRO_ENABLE /** \brief add key bit * * FIXME: Needs doc */ void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code) { if ((code >> 3) < KEYBOARD_REPORT_BITS) { keyboard_report->nkro.bits[code >> 3] |= 1 << (code & 7); } else { dprintf("add_key_bit: can't add: %02X\n", code); } } /** \brief del key bit * * FIXME: Needs doc */ void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code) { if ((code >> 3) < KEYBOARD_REPORT_BITS) { keyboard_report->nkro.bits[code >> 3] &= ~(1 << (code & 7)); } else { dprintf("del_key_bit: can't del: %02X\n", code); } } #endif /** \brief add key to report * * FIXME: Needs doc */ void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key) { #ifdef NKRO_ENABLE if (keyboard_protocol && keymap_config.nkro) { add_key_bit(keyboard_report, key); return; } #endif add_key_byte(keyboard_report, key); } /** \brief del key from report * * FIXME: Needs doc */ void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key) { #ifdef NKRO_ENABLE if (keyboard_protocol && keymap_config.nkro) { del_key_bit(keyboard_report, key); return; } #endif del_key_byte(keyboard_report, key); } /** \brief clear key from report * * FIXME: Needs doc */ void clear_keys_from_report(report_keyboard_t* keyboard_report) { // not clear mods #ifdef NKRO_ENABLE if (keyboard_protocol && keymap_config.nkro) { memset(keyboard_report->nkro.bits, 0, sizeof(keyboard_report->nkro.bits)); return; } #endif memset(keyboard_report->keys, 0, sizeof(keyboard_report->keys)); }
では、関数を見ていこう
uint8_t has_anykey(report_keyboard_t* keyboard_report)
keyboard_report
にキーのデータがあるかを確認するための関数のようだ
キーのデータがあればその数を、なければ 0
を返すと思われる
uint8_t get_first_key(report_keyboard_t* keyboard_report)
keyboard_report
の最初のキーを取得する関数のようだ
bool is_key_pressed(report_keyboard_t* keyboard_report, uint8_t key)
keyboard_report
に key
が存在するかを確認する関数のようだ
存在すれば True
を、存在しなければ False
を返す
keyboard_report
に存在する == キーが押された ということで is_key_pressed()
という名前なのかもしれない
void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code)
keyboard_report
の末尾に code
を追加する関数のようだ
void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code)
keyboard_report
から code
を削除する関数のようだ
void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code)
Nキーロールオーバーが有効な場合、 report_keyboard_t
でのデータの持ち方が異なる
それに合わせて、 code
を追加する関数が用意されているようだ
void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code)
add_key_bit
と同じように、Nキーロールオーバーが有効な場合の code
を削除する関数のようだ
void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key)
Nキーロールオーバーが有効かどうかで add_key_byte()
と add_key_bit()
の呼び出しをルーティングしている
void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key)
add_key_to_report()
と同様に、Nキーロールオーバーが有効かどうかで del_key_byte()
と del_key_bit()
の呼び出しをルーティングしている
void clear_keys_from_report(report_keyboard_t* keyboard_report)
keyboard_report
からキーの情報をすべて消去する関数のようだ
まとめ
今回は、とりあえず keymap.h
に include されているファイルについて見ていった
定義のみのファイルや、 HID デバイスとして動くために重要そうなファイルもあった
次回予告
次回は、続きの host.h
から見ていこうと思う