~ruther/qmk_firmware

d95463f2e0369dc0e28497bb923b3012fb09e900 — tmk 12 years ago e760953
Add legacy keymap support.
5 files changed, 151 insertions(+), 38 deletions(-)

M common/action.c
M common/action.h
M common/keycode.h
A common/keymap.c
M common/keymap.h
M common/action.c => common/action.c +8 -1
@@ 358,6 358,10 @@ static void process_action(keyrecord_t *record)
                    if (event.pressed) {
                        layer_switch(action.layer.opt);
                    }
//TODO: this is ok?
                    else {
                        layer_switch(default_layer);
                    }
                    break;
                case 0xF0:
                    // tap toggle


@@ 394,7 398,10 @@ static void process_action(keyrecord_t *record)
                            debug("LAYER_PRESSED: Tap: unregister_code\n");
                            unregister_code(action.layer.code);
                        } else {
                            debug("LAYER_PRESSED: No tap: NO ACTION\n");
                            //debug("LAYER_PRESSED: No tap: NO ACTION\n");
//TODO: this is ok?
                            debug("LAYER_PRESSED: No tap: return to default layer\n");
                            layer_switch(default_layer);
                        }
                    }
                    break;

M common/action.h => common/action.h +58 -29
@@ 18,6 18,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
#define ACTION_H

#include "keyboard.h"
#include "keycode.h"


/* Action struct.


@@ 107,28 108,28 @@ Keyboard Keys
ACT_LMODS(0000):
0000|0000|000000|00    No action
0000|0000| keycode     Key
0010|mods|000000|00    Left mods Momentary
0000|mods| keycode     Key+Left mods
0000|mods|000000|00    Left mods
0000|mods| keycode     Key & Left mods

ACT_RMODS(0001):
0001|0000|000000|00    No action
0001|0000| keycode     Key(no used)
0001|mods|000000|00    Right mods Momentary
0001|mods| keycode     Key+Right mods
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
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
0011|mods| keycode     Right mods + tap Key
 

Other HID Usage


@@ 143,12 144,20 @@ ACT_USAGE(0100):

Mouse Keys
----------
TODO: can be combined with 'Other HID Usage'? to save action kind id.
ACT_MOUSEKEY(0110):
0101|XXXX| keycode     Mouse key


Layer Actions
-------------
TODO: reconsider layer methods.
1   momemtary + tap key                 up: L,     down: default
1   bitwise   + tap key                 up: xor B, down: xor B
3   momemtary go + tap key?             up: X,     down:
3   toggle(mementary back) + tap key?   up:        down: Y
3   no tap                              up: X,     down: Y

ACT_LAYER_PRESSED(1000):    Set layer on key pressed
ACT_LAYER_RELEASED(1001):   Set layer on key released
ACT_LAYER_BIT(1010):        On/Off layer bit


@@ 222,57 231,77 @@ enum acion_param {
};


/* action_t utility */
/* action utility */
#define ACTION_NO                       0
#define ACTION(kind, param)             ((kind)<<12 | (param))
#define MODS4(mods)                     (((mods)>>4 | (mods)) & 0x0F)

/* Key & Mods */
/* Key */
#define ACTION_KEY(key)                 ACTION(ACT_LMODS,    key)
/* Mods & key */
#define ACTION_LMODS(mods)              ACTION(ACT_LMODS,    (mods)<<8 | 0x00)
#define ACTION_LMODS_KEY(mods, key)     ACTION(ACT_LMODS,    (mods)<<8 | (key))
#define ACTION_RMODS(mods)              ACTION(ACT_RMODS,    (mods)<<8 | 0x00)
#define ACTION_RMODS_KEY(mods, key)     ACTION(ACT_RMODS,    (mods)<<8 | (key))
/* Mod & key */
#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))

/* Mods + Tap key */
#define MODS4(mods)                     (((mods)>>4 | (mods)) & 0x0F)
#define ACTION_LMODS_TAP(mods, key)     ACTION(ACT_LMODS_TAP, MODS4(mods)<<8 | (key))
#define ACTION_LMODS_TAP_KEY(mods, key) ACTION(ACT_LMODS_TAP, MODS4(mods)<<8 | (key))
#define ACTION_LMODS_ONESHOT(mods)      ACTION(ACT_LMODS_TAP, MODS4(mods)<<8 | ONE_SHOT)
#define ACTION_RMODS_TAP(mods, key)     ACTION(ACT_RMODS_TAP, MODS4(mods)<<8 | (key))
#define ACTION_RMODS_TAP_KEY(mods, key) ACTION(ACT_RMODS_TAP, MODS4(mods)<<8 | (key))
#define ACTION_RMODS_ONESHOT(mods)      ACTION(ACT_RMODS_TAP, MODS4(mods)<<8 | ONE_SHOT)
/* Mod + Tap key */
#define ACTION_LMOD_TAP_KEY(mod, key)   ACTION(ACT_LMODS_TAP, MODS4(MOD_BIT(mod))<<8 | (key))
#define ACTION_LMOD_ONESHOT(mod)        ACTION(ACT_LMODS_TAP, MODS4(MOD_BIT(mod))<<8 | ONE_SHOT)
#define ACTION_RMOD_TAP_KEY(mod, key)   ACTION(ACT_RMODS_TAP, MODS4(MOD_BIT(mod))<<8 | (key))
#define ACTION_RMOD_ONESHOT(mod)        ACTION(ACT_RMODS_TAP, MODS4(MOD_BIT(mod))<<8 | ONE_SHOT)

// TODO: contemplate about layer action
/* Switch current layer */
#define ACTION_LAYER_SET_ON_PRESSED(layer)   ACTION(ACT_LAYER_PRESSED,  (layer)<<8 | 0x00)
#define ACTION_LAYER_SET_ON_RELEASED(layer)  ACTION(ACT_LAYER_RELEASED, (layer)<<8 | 0x00)
#define ACTION_LAYER_BIT(bits)               ACTION(ACT_LAYER_BIT,      (bits)<<8 | 0x00)
#define ACTION_LAYER_TO_DEFAULT_ON_PRESSED   ACTION(ACT_LAYER_EXT,      0x0<<8     | 0x00)
#define ACTION_LAYER_TO_DEFAULT_ON_RELEASED  ACTION(ACT_LAYER_EXT,      0x1<<8     | 0x00)
#define ACTION_LAYER_SET(layer)                        ACTION(ACT_LAYER_PRESSED,  (layer)<<8 | 0x00)
#define ACTION_LAYER_SET_ON_PRESSED(layer)             ACTION(ACT_LAYER_PRESSED,  (layer)<<8 | 0x00)
#define ACTION_LAYER_SET_ON_RELEASED(layer)            ACTION(ACT_LAYER_RELEASED, (layer)<<8 | 0x00)
#define ACTION_LAYER_BIT(bits)                         ACTION(ACT_LAYER_BIT,      (bits)<<8 | 0x00)
#define ACTION_LAYER_SET_DEFAULT                       ACTION(ACT_LAYER_EXT,      0x0<<8     | 0x00)
#define ACTION_LAYER_RETURN_DEFAULT                    ACTION(ACT_LAYER_EXT,      0x1<<8     | 0x00)
#define ACTION_LAYER_SET_DEFAULT_ON_PRESSED            ACTION(ACT_LAYER_EXT,      0x0<<8     | 0x00)
#define ACTION_LAYER_SET_DEFAULT_ON_RELEASED           ACTION(ACT_LAYER_EXT,      0x1<<8     | 0x00)
/* Switch default layer */
#define ACTION_LAYER_DEFAULT_SET_ON_PRESSED(layer)   ACTION(ACT_LAYER_PRESSED,  (layer)<<8 | 0xFF)
#define ACTION_LAYER_DEFAULT_SET_ON_RELEASED(layer)  ACTION(ACT_LAYER_RELEASED, (layer)<<8 | 0xFF)
#define ACTION_LAYER_DEFAULT_BIT(bits)               ACTION(ACT_LAYER_BIT, (bits)<<8 | 0xFF)
#define ACTION_LAYER_DEFAULT_SET_CURRENT_ON_PRESSED  ACTION(ACT_LAYER_EXT, 0x0<<8    | 0xFF)
#define ACTION_LAYER_DEFAULT_SET_CURRENT_ON_RELEASED ACTION(ACT_LAYER_EXT, 0x1<<8    | 0xFF)
#define ACTION_LAYER_DEFAULT_SET(layer)                ACTION(ACT_LAYER_PRESSED,  (layer)<<8 | 0xFF)
#define ACTION_LAYER_DEFAULT_SET_ON_PRESSED(layer)     ACTION(ACT_LAYER_PRESSED,  (layer)<<8 | 0xFF)
#define ACTION_LAYER_DEFAULT_SET_ON_RELEASED(layer)    ACTION(ACT_LAYER_RELEASED, (layer)<<8 | 0xFF)
#define ACTION_LAYER_DEFAULT_BIT(bits)                 ACTION(ACT_LAYER_BIT, (bits)<<8 | 0xFF)
#define ACTION_LAYER_DEFAULT_SET_CURRENT_ON_PRESSED    ACTION(ACT_LAYER_EXT, 0x0<<8    | 0xFF)
#define ACTION_LAYER_DEFAULT_SET_CURRENT_ON_RELEASED   ACTION(ACT_LAYER_EXT, 0x1<<8    | 0xFF)
/* Layer switch with tap key */
#define ACTION_LAYER_SET_TAP_KEY(layer, key)  ACTION(ACT_LAYER_PRESSED, (layer)<<8 | (key))
#define ACTION_LAYER_BIT_TAP_KEY(bits, key)   ACTION(ACT_LAYER_BIT,     (bits)<<8 | (key))
#define ACTION_LAYER_DEFAULT_SET_TAP_KEY(key) ACTION(ACT_LAYER_EXT,     0x0<<8     | (key))
/* with tap toggle */
#define ACTION_LAYER_SET_ON_PRESSED_TAP_TOGGLE(layer)   ACTION(ACT_LAYER_PRESSED,  (layer)<<8 | 0xF0)
#define ACTION_LAYER_SET_ON_RELEASED_TAP_TOGGLE(layer)  ACTION(ACT_LAYER_RELEASED, (layer)<<8 | 0xF0)
#define ACTION_LAYER_BIT_TAP_TOGGLE(layer)  ACTION(ACT_LAYER_BIT,     (layer)<<8 | 0xF0)
#define ACTION_LAYER_DEFAULT_TAP_TOGGLE     ACTION(ACT_LAYER_EXT,     0x0<<8     | 0xF0)
#define ACTION_LAYER_SET_TAP_KEY(layer, key)           ACTION(ACT_LAYER_PRESSED, (layer)<<8 | (key))
#define ACTION_LAYER_BIT_TAP_KEY(bits, key)            ACTION(ACT_LAYER_BIT,     (bits)<<8 | (key))
#define ACTION_LAYER_DEFAULT_SET_TAP_KEY(key)          ACTION(ACT_LAYER_EXT,     0x0<<8     | (key))
/* Layer switch with tap toggle */
#define ACTION_LAYER_SET_ON_PRESSED_TAP_TOGGLE(layer)  ACTION(ACT_LAYER_PRESSED,  (layer)<<8 | 0xF0)
#define ACTION_LAYER_SET_ON_RELEASED_TAP_TOGGLE(layer) ACTION(ACT_LAYER_RELEASED, (layer)<<8 | 0xF0)
#define ACTION_LAYER_BIT_TAP_TOGGLE(layer)             ACTION(ACT_LAYER_BIT,     (layer)<<8 | 0xF0)
#define ACTION_LAYER_DEFAULT_TAP_TOGGLE                ACTION(ACT_LAYER_EXT,     0x0<<8     | 0xF0)

/* HID Usage */
#define ACTION_USAGE_PAGE_SYSTEM        0
#define ACTION_USAGE_PAGE_CONSUMER      1
#define ACTION_USAGE_SYSTEM(id)         ACTION(ACT_USAGE,    ACTION_USAGE_PAGE_SYSTEM<<10 | (id))
#define ACTION_USAGE_CONSUMER(id)       ACTION(ACT_USAGE,    ACTION_USAGE_PAGE_CONSUMER<<10 | (id))

/* Mousekey */
#define ACTION_MOUSEKEY(key)            ACTION(ACT_MOUSEKEY, key)

/* Macro */
#define ACTION_MACRO(opt, id)           ACTION(ACT_FUNCTION, (opt)<<8 | (addr))

/* Command */
#define ACTION_COMMAND(opt, id)         ACTION(ACT_COMMAND,  (opt)<<8 | (addr))

/* Function */
#define ACTION_FUNCTION(id, opt)        ACTION(ACT_FUNCTION, (opt)<<8 | id)


M common/keycode.h => common/keycode.h +2 -2
@@ 28,14 28,14 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
#define IS_KEY(code)             (KC_A         <= (code) && (code) <= KC_EXSEL)
#define IS_MOD(code)             (KC_LCTRL     <= (code) && (code) <= KC_RGUI)

#define IS_FN(code)              (KC_FN0       <= (code) && (code) <= KC_FN7)
#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_BTN5)
#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 IS_SPECIAL(code)         ((0xB0 <= (code) && (code) <= 0xDF) || (0xE8 <= (code) && (code) <= 0xFF))
#define IS_SPECIAL(code)         ((0xA5 <= (code) && (code) <= 0xDF) || (0xE8 <= (code) && (code) <= 0xFF))
#define IS_CONSUMER(code)        (KC_MUTE      <= (code) && (code) <= KC_WFAV)
#define IS_SYSTEM(code)          (KC_POWER     <= (code) && (code) <= KC_WAKE)


A common/keymap.c => common/keymap.c +73 -0
@@ 0,0 1,73 @@
/*
Copyright 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/>.
*/
#include "keymap.h"
#include "report.h"
#include "keycode.h"


/* layer */
uint8_t default_layer = 0;
uint8_t current_layer = 0;


#ifndef NO_LEGACY_KEYMAP_SUPPORT
/* legacy support with weak reference */
__attribute__ ((weak))
action_t keymap_get_action(uint8_t layer, uint8_t row, uint8_t col)
{
    /* convert from legacy keycode to action */
    uint8_t key = keymap_get_keycode(layer, row, col);
    action_t action;
    switch (key) {
        case KC_A ... KC_EXSEL:
            action.code = ACTION_KEY(key);
            break;
        case KC_LCTRL ... KC_LGUI:
            action.code = ACTION_LMOD(key);
            break;
        case KC_RCTRL ... KC_RGUI:
            action.code = ACTION_RMOD(key);
            break;
        case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE:
            action.code = ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(key));
            break;
        case KC_AUDIO_MUTE ... KC_WWW_FAVORITES:
            action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(key));
            break;
        case KC_MS_UP ... KC_MS_ACCEL2:
            action.code = ACTION_MOUSEKEY(key);
            break;
        case KC_FN0 ... KC_FN31:
            {
                uint8_t layer = keymap_fn_layer(FN_INDEX(key));
                uint8_t code = keymap_fn_keycode(FN_INDEX(key));
                action.code = ACTION_LAYER_SET_TAP_KEY(layer, code);
            }
            break;
        case KC_NO ... KC_UNDEFINED:
        default:
            action.code = ACTION_NO;
            break;
    }
    return action;
}
#endif

__attribute__ ((weak))
void action_call_function(keyevent_t event, uint8_t id)
{
}

M common/keymap.h => common/keymap.h +10 -6
@@ 28,18 28,22 @@ extern uint8_t current_layer;
/* layer to return or start with */
extern uint8_t default_layer;


/* 
 * legacy keymap interface: keycode
 * new keymap interface: action
 */
action_t keymap_get_action(uint8_t layer, uint8_t row, uint8_t col);


#ifndef NO_LEGACY_KEYMAP_SUPPORT
/* keycode of key */
uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col);

/* layer to move during press Fn key */
uint8_t keymap_fn_layer(uint8_t fn_bits);

/* keycode to send when release Fn key without using */
uint8_t keymap_fn_keycode(uint8_t fn_bits);

/* 
 * new keymap interface: action
 */
action_t keymap_get_action(uint8_t layer, uint8_t row, uint8_t col);
#endif

#endif