2013-01-28 05:06:42 +00:00
/*
Copyright 2012 , 2013 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/>.
*/
2012-12-15 17:32:07 +00:00
# ifndef ACTION_H
# define ACTION_H
# include "keyboard.h"
2013-01-31 08:50:53 +00:00
# include "keycode.h"
2013-02-25 06:30:37 +00:00
# include "action_macro.h"
2012-12-15 17:32:07 +00:00
2013-01-27 07:38:19 +00:00
2013-02-01 05:48:11 +00:00
/* Struct to record event and tap count */
2013-02-26 07:27:09 +00:00
typedef union {
struct {
bool interrupted : 1 ;
bool reserved2 : 1 ;
bool reserved1 : 1 ;
bool reserved0 : 1 ;
uint8_t count : 4 ;
} ;
} tap_t ;
2013-02-01 05:48:11 +00:00
typedef struct {
keyevent_t event ;
2013-02-26 07:27:09 +00:00
tap_t tap ;
2013-02-01 05:48:11 +00:00
} keyrecord_t ;
2013-01-27 07:38:19 +00:00
/* Action struct.
*
2013-02-13 02:47:19 +00:00
* In avr - gcc bit field seems to be assigned from LSB ( bit0 ) to MSB ( bit15 ) .
2013-01-27 07:38:19 +00:00
* AVR looks like a little endian in avr - gcc .
*
2013-01-28 05:06:42 +00:00
* NOTE : not portable across compiler / endianness ?
2013-01-27 07:38:19 +00:00
* Byte order and bit order of 0x1234 :
* Big endian : 15 . . . 8 7 . . . 210
* | 0x12 | 0x34 |
* 0001 0010 0011 0100
* Little endian : 012 . . . 7 8 . . . 15
* | 0x34 | 0x12 |
* 0010 1100 0100 1000
*/
typedef union {
uint16_t code ;
struct action_kind {
uint16_t param : 12 ;
2013-02-04 13:53:45 +00:00
uint8_t id : 4 ;
2013-01-27 07:38:19 +00:00
} kind ;
struct action_key {
2013-02-04 13:53:45 +00:00
uint8_t code : 8 ;
uint8_t mods : 4 ;
uint8_t kind : 4 ;
2013-01-27 07:38:19 +00:00
} key ;
struct action_layer {
2013-02-04 13:53:45 +00:00
uint8_t code : 8 ;
uint8_t val : 4 ;
uint8_t kind : 4 ;
2013-01-27 07:38:19 +00:00
} layer ;
struct action_usage {
uint16_t code : 10 ;
2013-02-04 13:53:45 +00:00
uint8_t page : 2 ;
uint8_t kind : 4 ;
2013-01-27 07:38:19 +00:00
} usage ;
struct action_command {
2013-02-04 13:53:45 +00:00
uint8_t id : 8 ;
uint8_t opt : 4 ;
uint8_t kind : 4 ;
2013-01-27 07:38:19 +00:00
} command ;
struct action_function {
uint8_t id : 8 ;
uint8_t opt : 4 ;
uint8_t kind : 4 ;
} func ;
} action_t ;
2013-02-13 02:47:19 +00:00
/* Execute action per keyevent */
void action_exec ( keyevent_t event ) ;
/* action for key */
action_t action_for_key ( uint8_t layer , key_t key ) ;
2013-02-25 06:30:37 +00:00
/* macro */
const prog_macro_t * action_get_macro ( keyrecord_t * record , uint8_t id , uint8_t opt ) ;
2013-02-13 02:47:19 +00:00
/* user defined special function */
void action_function ( keyrecord_t * record , uint8_t id , uint8_t opt ) ;
2013-01-23 14:53:51 +00:00
/*
* Utilities for actions .
*/
void register_code ( uint8_t code ) ;
void unregister_code ( uint8_t code ) ;
void add_mods ( uint8_t mods ) ;
void del_mods ( uint8_t mods ) ;
void set_mods ( uint8_t mods ) ;
void clear_keyboard ( void ) ;
void clear_keyboard_but_mods ( void ) ;
bool sending_anykey ( void ) ;
void layer_switch ( uint8_t new_layer ) ;
2013-01-26 17:42:48 +00:00
bool is_tap_key ( key_t key ) ;
2013-02-01 05:48:11 +00:00
bool waiting_buffer_has_anykey_pressed ( void ) ;
2013-01-23 14:53:51 +00:00
/*
2013-01-27 07:38:19 +00:00
* Action codes
* = = = = = = = = = = = =
* 16 bit code : action_kind ( 4 bit ) + action_parameter ( 12 bit )
*
2013-02-25 06:30:37 +00:00
* Keyboard Keys ( 00 XX )
* - - - - - - - - - - - - - - - - - - -
2013-02-13 02:47:19 +00:00
* ACT_LMODS ( 0000 ) :
* 0000 | 0000 | 000000 | 00 No action
* 0000 | 0000 | 000000 | 01 Transparent
* 0000 | 0000 | keycode Key
* 0000 | mods | 000000 | 00 Left mods
* 0000 | mods | keycode Key & Left mods
*
* ACT_RMODS ( 0001 ) :
* 0001 | 0000 | 000000 | 00 No action ( not used )
* 0001 | 0000 | 000000 | 01 Transparent ( not used )
* 0001 | 0000 | keycode Key ( no used )
* 0001 | mods | 000000 | 00 Right mods
* 0001 | mods | keycode Key & Right mods
*
* ACT_LMODS_TAP ( 0010 ) :
* 0010 | mods | 000000 | 00 Left mods OneShot
* 0010 | mods | 000000 | 01 ( reserved )
* 0010 | mods | 000000 | 10 ( reserved )
* 0010 | mods | 000000 | 11 ( reserved )
* 0010 | mods | keycode Left mods + tap Key
*
* ACT_RMODS_TAP ( 0011 ) :
* 0011 | mods | 000000 | 00 Right mods OneShot
* 0011 | mods | 000000 | 01 ( reserved )
* 0011 | mods | 000000 | 10 ( reserved )
* 0011 | mods | 000000 | 11 ( reserved )
* 0011 | mods | keycode Right mods + tap Key
*
*
2013-02-25 06:30:37 +00:00
* Other keys ( 01 XX )
* - - - - - - - - - - - - - - - - - - - -
2013-02-13 02:47:19 +00:00
* This action handles other usages than keyboard .
* ACT_USAGE ( 0100 ) :
* 0100 | 00 | usage ( 10 ) System control ( 0x80 ) - General Desktop page ( 0x01 )
* 0100 | 01 | usage ( 10 ) Consumer control ( 0x01 ) - Consumer page ( 0x0C )
* 0100 | 10 | usage ( 10 ) ( reserved )
* 0100 | 11 | usage ( 10 ) ( reserved )
*
* ACT_MOUSEKEY ( 0110 ) :
* 0101 | XXXX | keycode Mouse key
*
*
2013-02-25 06:30:37 +00:00
* Layer Actions ( 10 XX )
* - - - - - - - - - - - - - - - - - - -
2013-02-20 02:16:13 +00:00
* ACT_KEYMAP :
2013-02-20 06:52:32 +00:00
* 1000 | - - xx | 0000 0000 Clear keyamp and overlay
* 1000 | LLLL | 0000 00 xx Reset default layer and clear keymap and overlay
2013-02-20 02:16:13 +00:00
* 1000 | LLLL | keycode Invert with tap key
* 1000 | LLLL | 1111 0000 Invert with tap toggle
2013-02-23 04:42:59 +00:00
* 1000 | LLLL | 1111 00 xx Invert [ ^ = 1 < < L ]
2013-02-20 02:16:13 +00:00
* 1000 | LLLL | 1111 0100 On / Off
2013-02-23 04:42:59 +00:00
* 1000 | LLLL | 1111 01 xx On [ | = 1 < < L ]
2013-02-20 02:16:13 +00:00
* 1000 | LLLL | 1111 1000 Off / On
2013-02-23 04:42:59 +00:00
* 1000 | LLLL | 1111 10 xx Off [ & = ~ ( 1 < < L ) ]
* 1000 | LLLL | 1111 1100 Set / Clear
* 1000 | LLLL | 1111 11 xx Set [ = 1 < < L ]
2013-02-20 02:16:13 +00:00
* default layer : 0 - 15 ( 4 bit )
* xx : On { 00 : for special use , 01 : press , 10 : release , 11 : both }
2013-02-13 02:47:19 +00:00
*
2013-02-20 02:16:13 +00:00
* ACT_OVERLAY :
* 1011 | 0000 | 0000 0000 Clear overlay
* 1011 | LLLL | 0000 00 ss Invert 4 - bit chunk [ ^ = L < < ( 4 * ss ) ]
* 1011 | LLLL | keycode Invert with tap key
* 1011 | LLLL | 1111 0000 Invert with tap toggle
* 1011 | LLLL | 1111 00 xx Invert [ ^ = 1 < < L ]
* 1011 | LLLL | 1111 0100 On / Off ( momentary )
* 1011 | LLLL | 1111 01 xx On [ | = 1 < < L ]
* 1011 | LLLL | 1111 1000 Off / On
2013-02-23 04:42:59 +00:00
* 1011 | LLLL | 1111 10 xx Off [ & = ~ ( 1 < < L ) ]
* 1011 | LLLL | 1111 1100 Set / Clear
2013-02-20 02:16:13 +00:00
* 1011 | LLLL | 1111 11 xx Set [ = 1 < < L ]
* overlays : 16 - layer on / off status ( 16 bit )
* xx : On { 00 : for special use , 01 : press , 10 : release , 11 : both }
2013-02-13 02:47:19 +00:00
*
*
* Extensions ( 11 XX )
* - - - - - - - - - - - - - - - -
* ACT_MACRO ( 1100 ) :
* 1100 | opt | id ( 8 ) Macro play ?
* 1100 | 1111 | id ( 8 ) Macro record ?
*
* ACT_COMMAND ( 1110 ) :
* 1110 | opt | id ( 8 ) Built - in Command exec
*
* ACT_FUNCTION ( 1111 ) :
* 1111 | address ( 12 ) Function ?
* 1111 | opt | id ( 8 ) Function ?
*
2013-01-27 07:38:19 +00:00
*/
enum action_kind_id {
2013-01-15 10:04:58 +00:00
ACT_LMODS = 0 b0000 ,
ACT_RMODS = 0 b0001 ,
ACT_LMODS_TAP = 0 b0010 ,
ACT_RMODS_TAP = 0 b0011 ,
ACT_USAGE = 0 b0100 ,
ACT_MOUSEKEY = 0 b0101 ,
2013-02-20 02:16:13 +00:00
ACT_KEYMAP = 0 b1000 ,
ACT_OVERLAY = 0 b1001 ,
2013-01-15 10:04:58 +00:00
ACT_MACRO = 0 b1100 ,
ACT_COMMAND = 0 b1110 ,
ACT_FUNCTION = 0 b1111
2012-12-15 17:32:07 +00:00
} ;
2013-01-23 14:53:51 +00:00
2013-01-31 08:50:53 +00:00
/* action utility */
2013-01-09 13:33:33 +00:00
# define ACTION_NO 0
2013-02-13 00:23:52 +00:00
# define ACTION_TRANSPARENT 1
2013-01-09 13:33:33 +00:00
# define ACTION(kind, param) ((kind)<<12 | (param))
2013-01-31 08:50:53 +00:00
# define MODS4(mods) (((mods)>>4 | (mods)) & 0x0F)
2012-12-15 17:32:07 +00:00
2013-02-15 09:48:36 +00:00
/*
2013-02-14 06:22:59 +00:00
* Key
*/
2012-12-15 17:32:07 +00:00
# define ACTION_KEY(key) ACTION(ACT_LMODS, key)
2013-01-31 08:50:53 +00:00
/* Mods & key */
2013-02-12 08:12:04 +00:00
# define ACTION_LMODS(mods) ACTION(ACT_LMODS, MODS4(mods)<<8 | 0x00)
# define ACTION_LMODS_KEY(mods, key) ACTION(ACT_LMODS, MODS4(mods)<<8 | (key))
# define ACTION_RMODS(mods) ACTION(ACT_RMODS, MODS4(mods)<<8 | 0x00)
# define ACTION_RMODS_KEY(mods, key) ACTION(ACT_RMODS, MODS4(mods)<<8 | (key))
2013-01-31 08:50:53 +00:00
# define ACTION_LMOD(mod) ACTION(ACT_LMODS, MODS4(MOD_BIT(mod))<<8 | 0x00)
# define ACTION_LMOD_KEY(mod, key) ACTION(ACT_LMODS, MODS4(MOD_BIT(mod))<<8 | (key))
# define ACTION_RMOD(mod) ACTION(ACT_RMODS, MODS4(MOD_BIT(mod))<<8 | 0x00)
# define ACTION_RMOD_KEY(mod, key) ACTION(ACT_RMODS, MODS4(MOD_BIT(mod))<<8 | (key))
2013-02-14 06:22:59 +00:00
/* Tap key */
2013-02-07 15:50:51 +00:00
enum mods_codes {
MODS_ONESHOT = 0x00 ,
} ;
2013-01-31 08:50:53 +00:00
# define ACTION_LMODS_TAP_KEY(mods, key) ACTION(ACT_LMODS_TAP, MODS4(mods)<<8 | (key))
2013-02-07 15:50:51 +00:00
# define ACTION_LMODS_ONESHOT(mods) ACTION(ACT_LMODS_TAP, MODS4(mods)<<8 | MODS_ONESHOT)
2013-01-31 08:50:53 +00:00
# define ACTION_RMODS_TAP_KEY(mods, key) ACTION(ACT_RMODS_TAP, MODS4(mods)<<8 | (key))
2013-02-07 15:50:51 +00:00
# define ACTION_RMODS_ONESHOT(mods) ACTION(ACT_RMODS_TAP, MODS4(mods)<<8 | MODS_ONESHOT)
2013-01-31 08:50:53 +00:00
# define ACTION_LMOD_TAP_KEY(mod, key) ACTION(ACT_LMODS_TAP, MODS4(MOD_BIT(mod))<<8 | (key))
2013-02-07 15:50:51 +00:00
# define ACTION_LMOD_ONESHOT(mod) ACTION(ACT_LMODS_TAP, MODS4(MOD_BIT(mod))<<8 | MODS_ONESHOT)
2013-01-31 08:50:53 +00:00
# define ACTION_RMOD_TAP_KEY(mod, key) ACTION(ACT_RMODS_TAP, MODS4(MOD_BIT(mod))<<8 | (key))
2013-02-07 15:50:51 +00:00
# define ACTION_RMOD_ONESHOT(mod) ACTION(ACT_RMODS_TAP, MODS4(MOD_BIT(mod))<<8 | MODS_ONESHOT)
2013-02-25 06:30:37 +00:00
/* HID Usage */
enum usage_pages {
PAGE_SYSTEM ,
PAGE_CONSUMER
} ;
# define ACTION_USAGE_SYSTEM(id) ACTION(ACT_USAGE, PAGE_SYSTEM<<10 | (id))
# define ACTION_USAGE_CONSUMER(id) ACTION(ACT_USAGE, PAGE_CONSUMER<<10 | (id))
/* Mousekey */
# define ACTION_MOUSEKEY(key) ACTION(ACT_MOUSEKEY, key)
2013-02-07 15:50:51 +00:00
2013-02-25 06:30:37 +00:00
/* Layer Actions:
2013-02-20 02:16:13 +00:00
* Invert layer ^ = ( 1 < < layer )
* On layer | = ( 1 < < layer )
* Off layer & = ~ ( 1 < < layer )
* Set layer = ( 1 < < layer )
* Clear layer = 0
2013-02-07 15:50:51 +00:00
*/
2013-02-20 02:16:13 +00:00
enum layer_params {
ON_PRESS = 1 ,
ON_RELEASE = 2 ,
ON_BOTH = 3 ,
OP_RESET = 0x00 ,
OP_INV4 = 0x00 ,
OP_INV = 0xF0 ,
OP_ON = 0xF4 ,
OP_OFF = 0xF8 ,
OP_SET = 0xFC ,
2013-02-07 15:50:51 +00:00
} ;
2013-02-20 02:16:13 +00:00
2013-02-20 06:52:32 +00:00
/*
2013-02-20 02:16:13 +00:00
* Default Layer
2013-02-07 15:50:51 +00:00
*/
2013-03-04 17:42:28 +00:00
# define ACTION_DEFAULT_LAYER ACTION(ACT_KEYMAP, ON_RELEASE<<8 | OP_RESET | 0)
# define ACTION_DEFAULT_LAYER_SET(layer) ACTION_DEFAULT_LAYER_TO(layer, ON_RELEASE)
# define ACTION_DEFAULT_LAYER_TO(layer, on) ACTION(ACT_KEYMAP, (layer)<<8 | OP_RESET | (on))
2013-02-20 06:52:32 +00:00
/*
* Keymap Layer
*/
# define ACTION_KEYMAP_MOMENTARY(layer) ACTION_KEYMAP_ON_OFF(layer)
2013-03-04 17:42:28 +00:00
# define ACTION_KEYMAP_TOGGLE(layer) ACTION_KEYMAP_INV(layer, ON_RELEASE)
2013-02-20 02:16:13 +00:00
/* Keymap Invert */
2013-03-04 17:42:28 +00:00
# define ACTION_KEYMAP_INV(layer, on) ACTION(ACT_KEYMAP, (layer)<<8 | OP_INV | (on))
2013-02-20 02:16:13 +00:00
# define ACTION_KEYMAP_TAP_TOGGLE(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_INV | 0)
/* Keymap On */
2013-03-04 17:42:28 +00:00
# define ACTION_KEYMAP_ON(layer, on) ACTION(ACT_KEYMAP, (layer)<<8 | OP_ON | (on))
2013-02-20 02:16:13 +00:00
# define ACTION_KEYMAP_ON_OFF(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_ON | 0)
/* Keymap Off */
2013-03-04 17:42:28 +00:00
# define ACTION_KEYMAP_OFF(layer, on) ACTION(ACT_KEYMAP, (layer)<<8 | OP_OFF | (on))
2013-02-20 02:16:13 +00:00
# define ACTION_KEYMAP_OFF_ON(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_OFF | 0)
/* Keymap Set */
2013-03-04 17:42:28 +00:00
# define ACTION_KEYMAP_SET(layer, on) ACTION(ACT_KEYMAP, (layer)<<8 | OP_SET | (on))
2013-02-20 02:16:13 +00:00
# define ACTION_KEYMAP_SET_CLEAR(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_SET | 0)
/* Keymap Invert with tap key */
# define ACTION_KEYMAP_TAP_KEY(layer, key) ACTION(ACT_KEYMAP, (layer)<<8 | (key))
2013-02-14 06:22:59 +00:00
/*
2013-02-20 02:16:13 +00:00
* Overlay Layer
2013-02-14 06:22:59 +00:00
*/
2013-02-20 02:16:13 +00:00
# define ACTION_OVERLAY_MOMENTARY(layer) ACTION_OVERLAY_ON_OFF(layer)
2013-03-04 17:42:28 +00:00
# define ACTION_OVERLAY_TOGGLE(layer) ACTION_OVERLAY_INV(layer, ON_RELEASE)
2013-02-20 02:16:13 +00:00
/* Overlay Clear */
2013-03-04 17:42:28 +00:00
# define ACTION_OVERLAY_CLEAR(on) ACTION(ACT_OVERLAY, 0<<8 | OP_INV4 | (on))
2013-02-20 02:16:13 +00:00
/* Overlay Invert 4-bit chunk */
# define ACTION_OVERLAY_INV4(bits, shift) ACTION(ACT_OVERLAY, (bits)<<8 | OP_INV4 | shift)
/* Overlay Invert */
2013-03-04 17:42:28 +00:00
# define ACTION_OVERLAY_INV(layer, on) ACTION(ACT_OVERLAY, (layer)<<8 | OP_INV | (on))
2013-02-20 02:16:13 +00:00
# define ACTION_OVERLAY_TAP_TOGGLE(layer) ACTION(ACT_OVERLAY, (layer)<<8 | OP_INV | 0)
/* Overlay On */
2013-03-04 17:42:28 +00:00
# define ACTION_OVERLAY_ON(layer, on) ACTION(ACT_OVERLAY, (layer)<<8 | OP_ON | (on))
2013-02-20 02:16:13 +00:00
# define ACTION_OVERLAY_ON_OFF(layer) ACTION(ACT_OVERLAY, (layer)<<8 | OP_ON | 0)
/* Overlay Off */
2013-03-04 17:42:28 +00:00
# define ACTION_OVERLAY_OFF(layer, on) ACTION(ACT_OVERLAY, (layer)<<8 | OP_OFF | (on))
2013-02-20 02:16:13 +00:00
# define ACTION_OVERLAY_OFF_ON(layer) ACTION(ACT_OVERLAY, (layer)<<8 | OP_OFF | 0)
/* Overlay Set */
2013-03-04 17:42:28 +00:00
# define ACTION_OVERLAY_SET(layer, on) ACTION(ACT_OVERLAY, (layer)<<8 | OP_SET | (on))
2013-02-20 02:16:13 +00:00
# define ACTION_OVERLAY_SET_CLEAR(layer) ACTION(ACT_OVERLAY, (layer)<<8 | OP_SET | 0)
/* Overlay Invert with tap key */
# define ACTION_OVERLAY_TAP_KEY(layer, key) ACTION(ACT_OVERLAY, (layer)<<8 | (key))
2013-02-07 15:50:51 +00:00
2013-01-09 13:33:33 +00:00
2013-02-14 06:22:59 +00:00
/*
2013-02-25 06:30:37 +00:00
* Extensions
2013-02-14 06:22:59 +00:00
*/
2012-12-15 17:32:07 +00:00
/* Macro */
2013-02-25 06:30:37 +00:00
# define ACTION_MACRO(id) ACTION(ACT_MACRO, (id))
2013-02-26 07:27:09 +00:00
# define ACTION_MACRO_TAP(id) ACTION(ACT_MACRO, FUNC_TAP<<8 | (id))
2013-02-25 06:30:37 +00:00
# define ACTION_MACRO_OPT(id, opt) ACTION(ACT_MACRO, (opt)<<8 | (id))
2013-01-31 08:50:53 +00:00
2012-12-15 17:32:07 +00:00
/* Command */
2013-02-25 06:30:37 +00:00
# define ACTION_COMMAND(id, opt) ACTION(ACT_COMMAND, (opt)<<8 | (addr))
2013-01-31 08:50:53 +00:00
2012-12-15 17:32:07 +00:00
/* Function */
2013-02-07 15:50:51 +00:00
enum function_opts {
2013-02-10 15:02:11 +00:00
FUNC_TAP = 0x8 , /* indciates function is tappable */
2013-02-07 15:50:51 +00:00
} ;
2013-02-26 07:27:09 +00:00
# define ACTION_FUNCTION(id) ACTION(ACT_FUNCTION, (id))
# define ACTION_FUNCTION_TAP(id) ACTION(ACT_FUNCTION, FUNC_TAP<<8 | (id))
# define ACTION_FUNCTION_OPT(id, opt) ACTION(ACT_FUNCTION, (opt)<<8 | (id))
2012-12-15 17:32:07 +00:00
# endif /* ACTION_H */