2 Copyright 2013 Jun Wako <wakojun@gmail.com>
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #ifndef ACTION_MACRO_H
18 #define ACTION_MACRO_H
24 typedef uint8_t macro_t;
26 #define MACRO_NONE (macro_t*)0
27 #define MACRO(...) ({ static const macro_t __m[] PROGMEM = { __VA_ARGS__ }; &__m[0]; })
28 #define MACRO_GET(p) pgm_read_byte(p)
30 // Sends press when the macro key is pressed, release when release, or tap_macro when the key has been tapped
31 #define MACRO_TAP_HOLD(record, press, release, tap_macro) ( ((record)->event.pressed) ? \
32 ( ((record)->tap.count <= 0 || (record)->tap.interrupted) ? (press) : MACRO_NONE ) : \
33 ( ((record)->tap.count > 0 && !((record)->tap.interrupted)) ? (tap_macro) : (release) ) )
35 // Holds down the modifier mod when the macro key is held, or sends macro instead when tapped
36 #define MACRO_TAP_HOLD_MOD(record, macro, mod) MACRO_TAP_HOLD(record, (MACRO(D(mod), END)), MACRO(U(mod), END), macro)
38 // Holds down the modifier mod when the macro key is held, or pressed a shifted key when tapped (eg: shift+3 for #)
39 #define MACRO_TAP_SHFT_KEY_HOLD_MOD(record, key, mod) MACRO_TAP_HOLD_MOD(record, (MACRO(I(10), D(LSFT), T(key), U(LSFT), END)), mod)
42 // Momentary switch layer when held, sends macro if tapped
43 #define MACRO_TAP_HOLD_LAYER(record, macro, layer) ( ((record)->event.pressed) ? \
44 ( ((record)->tap.count <= 0 || (record)->tap.interrupted) ? ({layer_on((layer)); MACRO_NONE; }) : MACRO_NONE ) : \
45 ( ((record)->tap.count > 0 && !((record)->tap.interrupted)) ? (macro) : ({layer_off((layer)); MACRO_NONE; }) ) )
47 // Momentary switch layer when held, presses a shifted key when tapped (eg: shift+3 for #)
48 #define MACRO_TAP_SHFT_KEY_HOLD_LAYER(record, key, layer) MACRO_TAP_HOLD_LAYER(record, MACRO(I(10), D(LSFT), T(key), U(LSFT), END), layer)
52 #ifndef NO_ACTION_MACRO
53 void action_macro_play(const macro_t *macro_p);
55 #define action_macro_play(macro)
61 * code(0x04-73) // key down(1byte)
62 * code(0x04-73) | 0x80 // key up(1byte)
63 * { KEY_DOWN, code(0x04-0xff) } // key down(2bytes)
64 * { KEY_UP, code(0x04-0xff) } // key up(2bytes)
65 * WAIT // wait milli-seconds
66 * INTERVAL // set interval between macro commands
67 * END // stop macro execution
69 * Ideas(Not implemented):
78 enum macro_command_id{
84 /* 0x04 - 0x73 (reserved for keycode down) */
90 /* 0x84 - 0xf3 (reserved for keycode up) */
96 /* TODO: keycode:0x04-0x73 can be handled by 1byte command else 2bytes are needed
97 * if keycode between 0x04 and 0x73
98 * keycode / (keycode|0x80)
100 * {KEY_DOWN, keycode} / {KEY_UP, keycode}
102 #define DOWN(key) KEY_DOWN, (key)
103 #define UP(key) KEY_UP, (key)
104 #define TYPE(key) DOWN(key), UP(key)
105 #define WAIT(ms) WAIT, (ms)
106 #define INTERVAL(ms) INTERVAL, (ms)
109 #define D(key) DOWN(KC_##key)
111 #define U(key) UP(KC_##key)
113 #define T(key) TYPE(KC_##key)
115 #define W(ms) WAIT(ms)
117 #define I(ms) INTERVAL(ms)
119 /* for backward comaptibility */
120 #define MD(key) DOWN(KC_##key)
121 #define MU(key) UP(KC_##key)
124 #endif /* ACTION_MACRO_H */