@@ -373,6 +373,12 @@ void register_code(uint8_t code) | |||
host_add_mods(MOD_BIT(code)); | |||
host_send_keyboard_report(); | |||
} | |||
else if IS_SYSTEM(code) { | |||
host_system_send(KEYCODE2SYSTEM(code)); | |||
} | |||
else if IS_CONSUMER(code) { | |||
host_consumer_send(KEYCODE2CONSUMER(code)); | |||
} | |||
} | |||
void unregister_code(uint8_t code) | |||
@@ -400,6 +406,12 @@ void unregister_code(uint8_t code) | |||
host_del_mods(MOD_BIT(code)); | |||
host_send_keyboard_report(); | |||
} | |||
else if IS_SYSTEM(code) { | |||
host_system_send(0); | |||
} | |||
else if IS_CONSUMER(code) { | |||
host_consumer_send(0); | |||
} | |||
} | |||
void add_mods(uint8_t mods) |
@@ -33,9 +33,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
* r: Left/Right flag(Left:0, Right:1) | |||
* | |||
* ACT_MODS_TAP(001r): | |||
* 0010|mods|0000 0000 Modifiers with OneShot | |||
* 0010|mods|0000 00xx (reserved) | |||
* 0010|mods| keycode Modifiers with Tap Key | |||
* 001r|mods|0000 0000 Modifiers with OneShot | |||
* 001r|mods|0000 00xx (reserved) | |||
* 001r|mods| keycode Modifiers with Tap Key | |||
* | |||
* | |||
* Other Keys(01xx) |
@@ -36,31 +36,31 @@ void action_macro_play(const macro_t *macro_p) | |||
if (!macro_p) return; | |||
while (true) { | |||
switch (MACRO_READ()) { | |||
case INTERVAL: | |||
interval = MACRO_READ(); | |||
debug("INTERVAL("); debug_dec(interval); debug(")\n"); | |||
break; | |||
case WAIT: | |||
case KEY_DOWN: | |||
MACRO_READ(); | |||
debug("WAIT("); debug_dec(macro); debug(")\n"); | |||
{ uint8_t ms = macro; while (ms--) _delay_ms(1); } | |||
dprintf("KEY_DOWN(%02X)\n", macro); | |||
register_code(macro); | |||
break; | |||
case MODS_DOWN: | |||
case KEY_UP: | |||
MACRO_READ(); | |||
debug("MODS_DOWN("); debug_hex(macro); debug(")\n"); | |||
add_mods(macro); | |||
dprintf("KEY_UP(%02X)\n", macro); | |||
unregister_code(macro); | |||
break; | |||
case MODS_UP: | |||
case WAIT: | |||
MACRO_READ(); | |||
debug("MODS_UP("); debug_hex(macro); debug(")\n"); | |||
del_mods(macro); | |||
dprintf("WAIT(%u)\n", macro); | |||
{ uint8_t ms = macro; while (ms--) _delay_ms(1); } | |||
break; | |||
case INTERVAL: | |||
interval = MACRO_READ(); | |||
dprintf("INTERVAL(%u)\n", interval); | |||
break; | |||
case 0x04 ... 0x73: | |||
debug("DOWN("); debug_hex(macro); debug(")\n"); | |||
dprintf("DOWN(%02X)\n", macro); | |||
register_code(macro); | |||
break; | |||
case 0x84 ... 0xF3: | |||
debug("UP("); debug_hex(macro); debug(")\n"); | |||
dprintf("UP(%02X)\n", macro); | |||
unregister_code(macro&0x7F); | |||
break; | |||
case END: |
@@ -35,80 +35,68 @@ void action_macro_play(const macro_t *macro_p); | |||
/* TODO: NOT FINISHED | |||
normal mode command: | |||
key(down): 0x04-7f/73(F24) | |||
key(up): 0x84-ff | |||
command: 0x00-03, 0x80-83(0x74-7f, 0xf4-ff) | |||
mods down 0x00 | |||
mods up 0x01 | |||
wait 0x02 | |||
interval 0x03 | |||
extkey down 0x80 | |||
extkey up 0x81 | |||
ext commad 0x82 | |||
ext mode 0x83 | |||
end 0xff | |||
extension mode command: NOT IMPLEMENTED | |||
key down 0x00 | |||
key up 0x01 | |||
key down + wait | |||
key up + wait | |||
mods push | |||
mods pop | |||
wait | |||
interval | |||
if | |||
loop | |||
push | |||
pop | |||
all up | |||
end | |||
*/ | |||
/* Macro commands | |||
* code(0x04-73) // key down(1byte) | |||
* code(0x04-73) | 0x80 // key up(1byte) | |||
* { KEY_DOWN, code(0x04-0xff) } // key down(2bytes) | |||
* { KEY_UP, code(0x04-0xff) } // key up(2bytes) | |||
* WAIT // wait milli-seconds | |||
* INTERVAL // set interval between macro commands | |||
* END // stop macro execution | |||
* | |||
* Ideas(Not implemented): | |||
* modifiers | |||
* system usage | |||
* consumer usage | |||
* unicode usage | |||
* function call | |||
* conditionals | |||
* loop | |||
*/ | |||
enum macro_command_id{ | |||
/* 0x00 - 0x03 */ | |||
END = 0x00, | |||
MODS_DOWN = 0x01, | |||
MODS_UP = 0x02, | |||
MODS_SET, | |||
MODS_PUSH, | |||
MODS_POP, | |||
KEY_DOWN, | |||
KEY_UP, | |||
/* 0x04 - 0x73 (reserved for keycode down) */ | |||
/* 0x74 - 0x83 */ | |||
WAIT = 0x74, | |||
INTERVAL, | |||
/* 0x74 - 0x7f */ | |||
/* 0x80 - 0x84 */ | |||
EXT_DOWN, | |||
EXT_UP, | |||
EXT_WAIT, | |||
EXT_INTERVAL, | |||
COMPRESSION_MODE, | |||
/* 0x84 - 0xf3 (reserved for keycode up) */ | |||
EXTENSION_MODE = 0xff, | |||
/* 0xf4 - 0xff */ | |||
}; | |||
/* normal mode */ | |||
#define DOWN(key) (key) | |||
#define UP(key) ((key) | 0x80) | |||
#define TYPE(key) (key), (key | 0x80) | |||
#define MODS_DOWN(mods) MODS_DOWN, (mods) | |||
#define MODS_UP(mods) MODS_UP, (mods) | |||
/* TODO: keycode:0x04-0x73 can be handled by 1byte command else 2bytes are needed | |||
* if keycode between 0x04 and 0x73 | |||
* keycode / (keycode|0x80) | |||
* else | |||
* {KEY_DOWN, keycode} / {KEY_UP, keycode} | |||
*/ | |||
#define DOWN(key) KEY_DOWN, (key) | |||
#define UP(key) KEY_UP, (key) | |||
#define TYPE(key) DOWN(key), UP(key) | |||
#define WAIT(ms) WAIT, (ms) | |||
#define INTERVAL(ms) INTERVAL, (ms) | |||
/* key down */ | |||
#define D(key) DOWN(KC_##key) | |||
/* key up */ | |||
#define U(key) UP(KC_##key) | |||
/* key type */ | |||
#define T(key) TYPE(KC_##key) | |||
#define MD(key) MODS_DOWN(MOD_BIT(KC_##key)) | |||
#define MU(key) MODS_UP(MOD_BIT(KC_##key)) | |||
/* wait */ | |||
#define W(ms) WAIT(ms) | |||
/* interval */ | |||
#define I(ms) INTERVAL(ms) | |||
/* extension mode */ | |||
/* for backward comaptibility */ | |||
#define MD(key) DOWN(KC_##key) | |||
#define MU(key) UP(KC_##key) | |||
#endif /* ACTION_MACRO_H */ |
@@ -30,7 +30,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
#define IS_SPECIAL(code) ((0xA5 <= (code) && (code) <= 0xDF) || (0xE8 <= (code) && (code) <= 0xFF)) | |||
#define IS_SYSTEM(code) (KC_POWER <= (code) && (code) <= KC_WAKE) | |||
#define IS_SYSTEM(code) (KC_PWR <= (code) && (code) <= KC_WAKE) | |||
#define IS_CONSUMER(code) (KC_MUTE <= (code) && (code) <= KC_WFAV) | |||
#define IS_FN(code) (KC_FN0 <= (code) && (code) <= KC_FN31) | |||
#define IS_MOUSEKEY(code) (KC_MS_UP <= (code) && (code) <= KC_MS_ACCEL2) |
@@ -363,21 +363,19 @@ Default Layer also has bitwise operations, they are executed when key is release | |||
`Macro` action indicates complex key strokes. | |||
MACRO( MD(LSHIFT), D(D), END ) | |||
MACRO( U(D), MU(LSHIFT), END ) | |||
MACRO( D(LSHIFT), D(D), END ) | |||
MACRO( U(D), U(LSHIFT), END ) | |||
MACRO( I(255), T(H), T(E), T(L), T(L), W(255), T(O), END ) | |||
#### 2.3.1 Normal mode | |||
#### 2.3.1 Macro Commands | |||
- **I()** change interavl of stroke. | |||
- **D()** press key | |||
- **U()** release key | |||
- **T()** type key(press and release) | |||
- **W()** wait | |||
- **MD()** modifier down | |||
- **MU()** modifier up | |||
- **END** end mark | |||
#### 2.3.2 Extended mode | |||
#### 2.3.2 Examples | |||
***TODO: sample impl*** | |||
See `keyboard/hhkb/keymap.c` for sample. |
@@ -67,7 +67,7 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSPC, \ | |||
LCTL,A, S, D, F, G, H, J, K, L, FN3, QUOT,FN4, \ | |||
FN5,Z, X, C, V, B, N, M, COMM,DOT, FN2, RSFT,FN1, \ | |||
LGUI,LALT, FN6, RALT,NO), | |||
LGUI,LALT, FN6, RALT,RGUI), | |||
/* Layer 1: HHKB mode (HHKB Fn) | |||
* ,-----------------------------------------------------------. | |||
@@ -179,6 +179,7 @@ enum macro_id { | |||
LSHIFT_PAREN, | |||
RSHIFT_PAREN, | |||
HELLO, | |||
VOLUP, | |||
}; | |||
@@ -203,6 +204,7 @@ static const uint16_t PROGMEM fn_actions[] = { | |||
// [13] = ACTION_MACRO_TAP(LSHIFT_PAREN), // Macro: LShift with tap '(' | |||
// [14] = ACTION_MACRO_TAP(RSHIFT_PAREN), // Macro: RShift with tap ')' | |||
// [15] = ACTION_MACRO(HELLO), // Macro: say hello | |||
// [9] = ACTION_MACRO(VOLUP), // Macro: media key | |||
}; | |||
@@ -218,23 +220,27 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
case LSHIFT_PAREN: | |||
if (tap.count > 0 && !tap.interrupted) { | |||
return (event.pressed ? | |||
MACRO( MD(LSHIFT), D(9), U(9), MU(LSHIFT), END ) : MACRO_NONE); | |||
MACRO( D(LSHIFT), D(9), U(9), U(LSHIFT), END ) : MACRO_NONE); | |||
} else { | |||
return (event.pressed ? | |||
MACRO( MD(LSHIFT), END ) : MACRO( MU(LSHIFT), END ) ); | |||
MACRO( D(LSHIFT), END ) : MACRO( U(LSHIFT), END ) ); | |||
} | |||
case RSHIFT_PAREN: | |||
if (tap.count > 0 && !tap.interrupted) { | |||
return (event.pressed ? | |||
MACRO( MD(RSHIFT), D(0), U(0), MU(RSHIFT), END ) : MACRO_NONE); | |||
MACRO( D(RSHIFT), D(0), U(0), U(RSHIFT), END ) : MACRO_NONE); | |||
} else { | |||
return (event.pressed ? | |||
MACRO( MD(RSHIFT), END ) : MACRO( MU(RSHIFT), END ) ); | |||
MACRO( D(RSHIFT), END ) : MACRO( U(RSHIFT), END ) ); | |||
} | |||
case HELLO: | |||
return (event.pressed ? | |||
MACRO( I(0), T(H), T(E), T(L), T(L), W(255), T(O), END ) : | |||
MACRO_NONE ); | |||
case VOLUP: | |||
return (event.pressed ? | |||
MACRO( D(VOLU), U(VOLU), END ) : | |||
MACRO_NONE ); | |||
} | |||
return MACRO_NONE; | |||
} |