~ruther/qmk_firmware

a207e848b3b308406263576c1e0d066067888416 — tmk 12 years ago 6778324
Add tap flags on record_t
4 files changed, 104 insertions(+), 104 deletions(-)

M common/action.c
M common/action.h
M common/action_macro.c
M keyboard/hhkb/keymap.c
M common/action.c => common/action.c +25 -21
@@ 206,7 206,7 @@ void action_exec(keyevent_t event)
static void process_action(keyrecord_t *record)
{
    keyevent_t event = record->event;
    uint8_t tap_count = record->tap_count;
    uint8_t tap_count = record->tap.count;

    if (IS_NOEVENT(event)) { return; }



@@ 295,7 295,7 @@ static void process_action(keyrecord_t *record)
                                if (waiting_buffer_has_anykey_pressed()) {
                                    debug("MODS_TAP: Tap: Cancel: add_mods\n");
                                    // ad hoc: set 0 to cancel tap
                                    record->tap_count = 0;
                                    record->tap.count = 0;
                                    add_mods(mods);
                                } else {
                                    debug("MODS_TAP: Tap: register_code\n");


@@ 697,16 697,17 @@ static bool process_tapping(keyrecord_t *keyp)
    // if tapping
    if (IS_TAPPING_PRESSED()) {
        if (WITHIN_TAPPING_TERM(event)) {
            if (tapping_key.tap_count == 0) {
            if (tapping_key.tap.count == 0) {
                if (IS_TAPPING_KEY(event.key) && !event.pressed) {
                    // first tap!
                    debug("Tapping: First tap(0->1).\n");
                    tapping_key.tap_count = 1;
                    tapping_key.tap.count = 1;
                    tapping_key.tap.interrupted  = (waiting_buffer_has_anykey_pressed() ? true : false);
                    debug_tapping_key();
                    process_action(&tapping_key);

                    // enqueue
                    keyp->tap_count = tapping_key.tap_count;
                    keyp->tap = tapping_key.tap;
                    return false;
                }
#if TAPPING_TERM >= 500


@@ 730,19 731,19 @@ static bool process_tapping(keyrecord_t *keyp)
            // tap_count > 0
            else {
                if (IS_TAPPING_KEY(event.key) && !event.pressed) {
                    debug("Tapping: Tap release("); debug_dec(tapping_key.tap_count); debug(")\n");
                    keyp->tap_count = tapping_key.tap_count;
                    debug("Tapping: Tap release("); debug_dec(tapping_key.tap.count); debug(")\n");
                    keyp->tap = tapping_key.tap;
                    process_action(keyp);
                    tapping_key = *keyp;
                    debug_tapping_key();
                    return true;
                }
                else if (is_tap_key(keyp->event.key) && event.pressed) {
                    if (tapping_key.tap_count > 1) {
                    if (tapping_key.tap.count > 1) {
                        debug("Tapping: Start new tap with releasing last tap(>1).\n");
                        // unregister key
                        process_action(&(keyrecord_t){
                                .tap_count = tapping_key.tap_count,
                                .tap = tapping_key.tap,
                                .event.key = tapping_key.event.key,
                                .event.time = event.time,
                                .event.pressed = false


@@ 766,7 767,7 @@ static bool process_tapping(keyrecord_t *keyp)
        }
        // after TAPPING_TERM
        else {
            if (tapping_key.tap_count == 0) {
            if (tapping_key.tap.count == 0) {
                debug("Tapping: End. Timeout. Not tap(0): ");
                debug_event(event); debug("\n");
                process_action(&tapping_key);


@@ 776,17 777,17 @@ static bool process_tapping(keyrecord_t *keyp)
            }  else {
                if (IS_TAPPING_KEY(event.key) && !event.pressed) {
                    debug("Tapping: End. last timeout tap release(>0).");
                    keyp->tap_count = tapping_key.tap_count;
                    keyp->tap = tapping_key.tap;
                    process_action(keyp);
                    tapping_key = (keyrecord_t){};
                    return true;
                }
                else if (is_tap_key(keyp->event.key) && event.pressed) {
                    if (tapping_key.tap_count > 1) {
                    if (tapping_key.tap.count > 1) {
                        debug("Tapping: Start new tap with releasing last timeout tap(>1).\n");
                        // unregister key
                        process_action(&(keyrecord_t){
                                .tap_count = tapping_key.tap_count,
                                .tap = tapping_key.tap,
                                .event.key = tapping_key.event.key,
                                .event.time = event.time,
                                .event.pressed = false


@@ 810,10 811,11 @@ static bool process_tapping(keyrecord_t *keyp)
        }
    } else if (IS_TAPPING_RELEASED()) {
        if (WITHIN_TAPPING_TERM(event)) {
            if (tapping_key.tap_count > 0 && IS_TAPPING_KEY(event.key) && event.pressed) {
            if (tapping_key.tap.count > 0 && IS_TAPPING_KEY(event.key) && event.pressed) {
                // sequential tap.
                keyp->tap_count = tapping_key.tap_count + 1;
                debug("Tapping: Tap press("); debug_dec(keyp->tap_count); debug(")\n");
                keyp->tap = tapping_key.tap;
                keyp->tap.count += 1;
                debug("Tapping: Tap press("); debug_dec(keyp->tap.count); debug(")\n");
                process_action(keyp);
                tapping_key = *keyp;
                debug_tapping_key();


@@ 858,16 860,16 @@ static bool process_tapping(keyrecord_t *keyp)
static void waiting_buffer_scan_tap(void)
{
    // tapping already is settled
    if (tapping_key.tap_count > 0) return;
    // invalid state: tapping_key released && tap_count == 0
    if (tapping_key.tap.count > 0) return;
    // invalid state: tapping_key released && tap.count == 0
    if (!tapping_key.event.pressed) return;

    for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
        if (IS_TAPPING_KEY(waiting_buffer[i].event.key) &&
                !waiting_buffer[i].event.pressed &&
                WITHIN_TAPPING_TERM(waiting_buffer[i].event)) {
            tapping_key.tap_count = 1;
            waiting_buffer[i].tap_count = 1;
            tapping_key.tap.count = 1;
            waiting_buffer[i].tap.count = 1;
            process_action(&tapping_key);

            debug("waiting_buffer_scan_tap: found at ["); debug_dec(i); debug("]\n");


@@ 987,6 989,7 @@ bool is_tap_key(key_t key)
                default:
                    return false;
            }
        case ACT_MACRO:
        case ACT_FUNCTION:
            if (action.func.opt & FUNC_TAP) { return true; }
            return false;


@@ 1006,7 1009,8 @@ static void debug_event(keyevent_t event)
}
static void debug_record(keyrecord_t record)
{
    debug_event(record.event); debug(":"); debug_dec(record.tap_count);
    debug_event(record.event); debug(":"); debug_dec(record.tap.count);
    if (record.tap.interrupted) debug("-");
}
static void debug_action(action_t action)
{

M common/action.h => common/action.h +15 -3
@@ 23,9 23,19 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.


/* Struct to record event and tap count  */
typedef union {
    struct {
        bool    interrupted :1;
        bool    reserved2   :1;
        bool    reserved1   :1;
        bool    reserved0   :1;
        uint8_t count       :4;
    };
} tap_t;

typedef struct {
    keyevent_t  event;
    uint8_t     tap_count;
    tap_t tap;
} keyrecord_t;

/* Action struct.


@@ 377,6 387,7 @@ enum layer_params {
 */
/* Macro */
#define ACTION_MACRO(id)                ACTION(ACT_MACRO, (id))
#define ACTION_MACRO_TAP(id)            ACTION(ACT_MACRO, FUNC_TAP<<8 | (id))
#define ACTION_MACRO_OPT(id, opt)       ACTION(ACT_MACRO, (opt)<<8 | (id))

/* Command */


@@ 386,7 397,8 @@ enum layer_params {
enum function_opts {
    FUNC_TAP        = 0x8,      /* indciates function is tappable */
};
#define ACTION_FUNCTION(id, opt)        ACTION(ACT_FUNCTION, (opt)<<8 | id)
#define ACTION_FUNCTION_TAP(id)         ACTION(ACT_FUNCTION, FUNC_TAP<<8 | id)
#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))

#endif  /* ACTION_H */

M common/action_macro.c => common/action_macro.c +0 -1
@@ 41,7 41,6 @@ void action_macro_play(const prog_macro_t *macro_p)
            case MODS_DOWN:
                MACRO_READ();
                debug("MODS_DOWN("); debug_hex(macro); debug(")\n");
                debug("MODS_UP("); debug_hex(macro); debug(")\n");
                add_mods(macro);
                break;
            case MODS_UP:

M keyboard/hhkb/keymap.c => keyboard/hhkb/keymap.c +64 -79
@@ 56,18 56,18 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
     * |-----------------------------------------------------------|
     * |Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|Backs|
     * |-----------------------------------------------------------|
     * |Fn6   |  A|  S|  D|  F|  G|  H|  J|  K|  L|Fn3|  '|Return  |
     * |Contro|  A|  S|  D|  F|  G|  H|  J|  K|  L|Fn3|  '|Fn4     |
     * |-----------------------------------------------------------|
     * |Fn8     |  Z|  X|  C|  V|  B|  N|  M|  ,|  .|Fn2|Fn12  |Fn1|
     * |Fn5     |  Z|  X|  C|  V|  B|  N|  M|  ,|  .|Fn2|Shift |Fn1|
     * `-----------------------------------------------------------'
     *       |Gui|Alt  |          Fn5          |Alt  |Fn4|
     *       |Gui|Alt  |         Fn6           |Alt  |Fn7|
     *       `-------------------------------------------'
     */
    KEYMAP(ESC, 1,   2,   3,   4,   5,   6,   7,   8,   9,   0,   MINS,EQL, BSLS,GRV, \
           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,FN7, \
           LSFT,Z,   X,   C,   V,   B,   N,   M,   COMM,DOT, FN2, FN12,FN9, \
                LGUI,LALT,          FN5,                FN14,FN4),
           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,FN7),

    /* Layer 1: HHKB mode (HHKB Fn)
     * ,-----------------------------------------------------------.


@@ 77,7 77,7 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
     * |-----------------------------------------------------------|
     * |Contro|VoD|VoU|Mut|   |   |  *|  /|Hom|PgU|Lef|Rig|Enter   |
     * |-----------------------------------------------------------|
     * |Shift   |   |   |   |   |   |  +|  -|End|PgD|Dow|Shift |Fn0|
     * |Shift   |   |   |   |   |   |  +|  -|End|PgD|Dow|Shift |   |
     * `-----------------------------------------------------------'
     *       |Gui|Alt  |         Space         |Alt  |Gui|
     *       `-------------------------------------------'


@@ 127,7 127,7 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
           LSFT,NO,  NO,  NO,  NO,  BTN3,BTN2,BTN1,BTN4,BTN5,SLSH,RSFT,NO, \
                LGUI,LALT,          BTN1,               RALT,TRNS),

    /* Layer 4: Matias half keyboard style (Space)
    /* Layer 4: Matias half-qwerty keyboard style (Space)
     * ,-----------------------------------------------------------.
     * |  -|  0|  9|  8|  7|  6|  5|  4|  3|  2|  1|   |   |   |Esc|
     * |-----------------------------------------------------------|


@@ 176,7 176,8 @@ enum function_id {
};

enum macro_id {
    SHIFT_D,
    LSHIFT_PAREN,
    RSHIFT_PAREN,
    HELLO,
};



@@ 184,26 185,26 @@ enum macro_id {
/*
 * Fn action definition
 */
// TODO: use [1] = KEYMAP(...) to prevent from changing index of element?
static const uint16_t PROGMEM fn_actions[] = {
    ACTION_DEFAULT_LAYER,                           // FN0
    ACTION_KEYMAP(1),                            // FN1
    ACTION_KEYMAP_TAP_KEY(2, KC_SLASH),          // FN2  Layer with Slash
    ACTION_KEYMAP_TAP_KEY(3, KC_SCLN),           // FN3  Layer with Semicolon

    ACTION_KEYMAP(3),                            // FN4
//  ACTION_KEYMAP_TOGGLE(3),                     // FN4
//  ACTION_FUNCTION(MACRO, 0),                      // FN4
    ACTION_KEYMAP_TAP_KEY(5, KC_SPC),            // FN5
//  ACTION_LMOD_TAP_KEY(KC_LCTL, KC_BSPC),          // FN6  Control with tap Backspace
    ACTION_LMOD_TAP_KEY(KC_LCTL, KC_ESC),           // FN6  Control with tap Backspace
    ACTION_RMOD_TAP_KEY(KC_RCTL, KC_ENT),           // FN7  Control with tap Enter
    ACTION_LMOD_ONESHOT(KC_LSFT),                   // FN8  Oneshot Shift
    [9]  = ACTION_KEYMAP_TAP_TOGGLE(1),                 // FN9
    [11] = ACTION_FUNCTION_TAP(LSHIFT_LPAREN),             // FN11 Function: LShift with tap '('
    [12] = ACTION_FUNCTION_TAP(RSHIFT_RPAREN),             // FN12 Function: RShift with tap ')'
    [13] = ACTION_MACRO(SHIFT_D),                           
    [14] = ACTION_MACRO(HELLO),                             
    [0] = ACTION_DEFAULT_LAYER,                        // Default layer(not used)
//  [1] = ACTION_KEYMAP(1),                            // HHKB layer
    [1] = ACTION_KEYMAP_TAP_TOGGLE(1),                 // HHKB layer(toggle with 5 taps)
    [2] = ACTION_KEYMAP_TAP_KEY(2, KC_SLASH),          // Cursor layer with Slash*
    [3] = ACTION_KEYMAP_TAP_KEY(3, KC_SCLN),           // Mousekey layer with Semicolon*
    [4] = ACTION_RMOD_TAP_KEY(KC_RCTL, KC_ENT),        // RControl with tap Enter*
    [5] = ACTION_LMOD_ONESHOT(KC_LSFT),                // Oneshot Shift*
//  [6] = ACTION_KEYMAP_TAP_KEY(4, KC_SPC),            // Half-qwerty layer with Space
    [6] = ACTION_KEYMAP_TAP_KEY(5, KC_SPC),            // Mousekey layer with Space
//  [7] = ACTION_KEYMAP(3),                            // Mousekey layer
    [7] = ACTION_KEYMAP_TOGGLE(3),                     // Mousekey layer(toggle)

//  [8] = ACTION_LMOD_TAP_KEY(KC_LCTL, KC_BSPC),       // LControl with tap Backspace
//  [9] = ACTION_LMOD_TAP_KEY(KC_LCTL, KC_ESC),        // LControl with tap Esc
//  [11] = ACTION_FUNCTION_TAP(LSHIFT_LPAREN),         // Function: LShift with tap '('
//  [12] = ACTION_FUNCTION_TAP(RSHIFT_RPAREN),         // Function: RShift with tap ')'
//  [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
};




@@ 213,13 214,25 @@ static const uint16_t PROGMEM fn_actions[] = {
const prog_macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
    keyevent_t event = record->event;
    //uint8_t tap_count = record->tap_count;
    tap_t tap = record->tap;

    switch (id) {
        case SHIFT_D:
            return (event.pressed ?
                    MACRO( MD(LSHIFT), D(D), END ) :
                    MACRO( U(D), MU(LSHIFT), END ) );
        case LSHIFT_PAREN:
            if (tap.count > 0 && !tap.interrupted) {
                return (event.pressed ?
                        MACRO( MD(LSHIFT), D(9), U(9), MU(LSHIFT), END ) : MACRO_NONE);
            } else {
                return (event.pressed ?
                        MACRO( MD(LSHIFT), END ) : MACRO( MU(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);
            } else {
                return (event.pressed ?
                        MACRO( MD(RSHIFT), END ) : MACRO( MU(RSHIFT), END ) );
            }
        case HELLO:
            return (event.pressed ?
                    MACRO( I(0), T(H), T(E), T(L), T(L), W(255), T(O), END ) :


@@ 236,74 249,46 @@ const prog_macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t op
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
{
    keyevent_t event = record->event;
    uint8_t tap_count = record->tap_count;

    debug("action_call_function: ");
    if (event.pressed) debug("pressed"); else debug("released");
    debug(" id: "); debug_hex(id);
    debug(" tap_count: "); debug_dec(tap_count);
    debug("\n");
    tap_t tap = record->tap;

    switch (id) {
        case LSHIFT_LPAREN:
            // LShft + tap '('
            // NOTE: cant use register_code to avoid conflicting with magic key bind
            if (event.pressed) {
                if (tap_count == 0) {
                if (tap.count == 0 || tap.interrupted) {
                    add_mods(MOD_BIT(KC_LSHIFT));
                } else {
                    if (waiting_buffer_has_anykey_pressed()) {
                        // ad hoc: set 0 to cancel tap
                        record->tap_count = 0;
                        add_mods(MOD_BIT(KC_LSHIFT));
                    } else {
                        // NOTE to avoid conflicting command key bind(LShift+RShift)
                        //register_code(KC_LSHIFT);
                        //register_code(KC_9);
                        host_add_mods(MOD_BIT(KC_LSHIFT));
                        host_add_key(KC_9);
                        host_send_keyboard_report();
                    }
                }
            } else {
                if (tap_count == 0) {
                    del_mods(MOD_BIT(KC_LSHIFT));
                } else {
                    //unregister_code(KC_9);
                    //unregister_code(KC_LSHIFT);
                    host_add_mods(MOD_BIT(KC_LSHIFT));
                    host_add_key(KC_9);
                    host_send_keyboard_report();
                    host_del_mods(MOD_BIT(KC_LSHIFT));
                    host_del_key(KC_9);
                    host_send_keyboard_report();
                }
            } else {
                if (tap.count == 0 || tap.interrupted) {
                    del_mods(MOD_BIT(KC_LSHIFT));
                }
            }
            break;
        case RSHIFT_RPAREN:
            // RShift + tap ')'
            if (event.pressed) {
                if (tap_count == 0) {
                if (tap.count == 0 || tap.interrupted) {
                    add_mods(MOD_BIT(KC_RSHIFT));
                } else {
                    if (waiting_buffer_has_anykey_pressed()) {
                        // ad hoc: set 0 to cancel tap
                        record->tap_count = 0;
                        add_mods(MOD_BIT(KC_RSHIFT));
                    } else {
                        //register_code(KC_RSHIFT);
                        //register_code(KC_0);
                        host_add_mods(MOD_BIT(KC_RSHIFT));
                        host_add_key(KC_0);
                        host_send_keyboard_report();
                    }
                }
            } else {
                if (tap_count == 0) {
                    del_mods(MOD_BIT(KC_RSHIFT));
                } else {
                    //unregister_code(KC_0);
                    //unregister_code(KC_RSHIFT);
                    host_add_mods(MOD_BIT(KC_RSHIFT));
                    host_add_key(KC_0);
                    host_send_keyboard_report();
                    host_del_mods(MOD_BIT(KC_RSHIFT));
                    host_del_key(KC_0);
                    host_send_keyboard_report();
                }
            } else {
                if (tap.count == 0 || tap.interrupted) {
                    del_mods(MOD_BIT(KC_RSHIFT));
                }
            }
            break;
    }