/* Copyright 2012,2013 Jun Wako 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 . */ #include "host.h" #include "keycode.h" #include "keyboard.h" #include "mousekey.h" #include "command.h" #include "led.h" #include "backlight.h" #include "action_layer.h" #include "action_tapping.h" #include "action_macro.h" #include "action_util.h" #include "action.h" #ifdef DEBUG_ACTION #include "debug.h" #else #include "nodebug.h" #endif #ifdef FAUXCLICKY_ENABLE #include #endif void action_exec(keyevent_t event) { if (!IS_NOEVENT(event)) { dprint("\n---- action_exec: start -----\n"); dprint("EVENT: "); debug_event(event); dprintln(); } #ifdef FAUXCLICKY_ENABLE if (IS_PRESSED(event)) { FAUXCLICKY_ACTION_PRESS; } if (IS_RELEASED(event)) { FAUXCLICKY_ACTION_RELEASE; } fauxclicky_check(); #endif #ifdef ONEHAND_ENABLE if (!IS_NOEVENT(event)) { process_hand_swap(&event); } #endif keyrecord_t record = { .event = event }; #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) if (has_oneshot_layer_timed_out()) { dprintf("Oneshot layer: timeout\n"); clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); } #endif #ifndef NO_ACTION_TAPPING action_tapping_process(record); #else process_record(&record); if (!IS_NOEVENT(record.event)) { dprint("processed: "); debug_record(record); dprintln(); } #endif } #ifdef ONEHAND_ENABLE bool swap_hands = false; void process_hand_swap(keyevent_t *event) { static swap_state_row_t swap_state[MATRIX_ROWS]; keypos_t pos = event->key; swap_state_row_t col_bit = (swap_state_row_t)1<pressed ? swap_hands : swap_state[pos.row] & (col_bit); if (do_swap) { event->key = hand_swap_config[pos.row][pos.col]; swap_state[pos.row] |= col_bit; } else { swap_state[pos.row] &= ~(col_bit); } } #endif #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS) bool disable_action_cache = false; void process_record_nocache(keyrecord_t *record) { disable_action_cache = true; process_record(record); disable_action_cache = false; } #else void process_record_nocache(keyrecord_t *record) { process_record(record); } #endif __attribute__ ((weak)) bool process_record_quantum(keyrecord_t *record) { return true; } void process_record(keyrecord_t *record) { if (IS_NOEVENT(record->event)) { return; } if(!process_record_quantum(record)) return; action_t action = store_or_get_action(record->event.pressed, record->event.key); dprint("ACTION: "); debug_action(action); #ifndef NO_ACTION_LAYER dprint(" layer_state: "); layer_debug(); dprint(" default_layer_state: "); default_layer_debug(); #endif dprintln(); process_action(record, action); } void process_action(keyrecord_t *record, action_t action) { bool do_release_oneshot = false; keyevent_t event = record->event; #ifndef NO_ACTION_TAPPING uint8_t tap_count = record->tap.count; #endif if (event.pressed) { // clear the potential weak mods left by previously pressed keys clear_weak_mods(); } #ifndef NO_ACTION_ONESHOT // notice we only clear the one shot layer if the pressed key is not a modifier. if (is_oneshot_layer_active() && event.pressed && !IS_MOD(action.key.code)) { clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); do_release_oneshot = !is_oneshot_layer_active(); } #endif switch (action.kind.id) { /* Key and Mods */ case ACT_LMODS: case ACT_RMODS: { uint8_t mods = (action.kind.id == ACT_LMODS) ? action.key.mods : action.key.mods<<4; if (event.pressed) { if (mods) { if (IS_MOD(action.key.code) || action.key.code == KC_NO) { // e.g. LSFT(KC_LGUI): we don't want the LSFT to be weak as it would make it useless. // This also makes LSFT(KC_LGUI) behave exactly the same as LGUI(KC_LSFT). // Same applies for some keys like KC_MEH which are declared as MEH(KC_NO). add_mods(mods);
#include <stdint.h>
#include <stdbool.h>
#include "eeprom.h"
#include "eeconfig.h"

void eeconfig_init(void)
{
    eeprom_update_word(EECONFIG_MAGIC,          EECONFIG_MAGIC_NUMBER);
    eeprom_update_byte(EECONFIG_DEBUG,          0);
    eeprom_update_byte(EECONFIG_DEFAULT_LAYER,  0);
    eeprom_update_byte(EECONFIG_KEYMAP,         0);
    eeprom_update_byte(EECONFIG_MOUSEKEY_ACCEL, 0);
#ifdef BACKLIGHT_ENABLE
    eeprom_update_byte(EECONFIG_BACKLIGHT,      0);
#endif
#ifdef AUDIO_ENABLE
    eeprom_update_byte(EECONFIG_AUDIO,             0xFF); // On by default
#endif
#ifdef RGBLIGHT_ENABLE
    eeprom_update_dword(EECONFIG_RGBLIGHT,      0);
#endif
}

void eeconfig_enable(void)
{
    eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
}

void eeconfig_disable(void)
{
    eeprom_update_word(EECONFIG_MAGIC, 0xFFFF);
}

bool eeconfig_is_enabled(void)
{
    return (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER);
}

uint8_t eeconfig_read_debug(void)      { return eeprom_read_byte(EECONFIG_DEBUG); }
void eeconfig_update_debug(uint8_t val) { eeprom_update_byte(EECONFIG_DEBUG, val); }

uint8_t eeconfig_read_default_layer(void)      { return eeprom_read_byte(EECONFIG_DEFAULT_LAYER); }
void eeconfig_update_default_layer(uint8_t val) { eeprom_update_byte(EECONFIG_DEFAULT_LAYER, val); }

uint8_t eeconfig_read_keymap(void)      { return eeprom_read_byte(EECONFIG_KEYMAP); }
void eeconfig_update_keymap(uint8_t val) { eeprom_update_byte(EECONFIG_KEYMAP, val); }

#ifdef BACKLIGHT_ENABLE
uint8_t eeconfig_read_backlight(void)      { return eeprom_read_byte(EECONFIG_BACKLIGHT); }
void eeconfig_update_backlight(uint8_t val) { eeprom_update_byte(EECONFIG_BACKLIGHT, val); }
#endif

#ifdef AUDIO_ENABLE
uint8_t eeconfig_read_audio(void)      { return eeprom_read_byte(EECONFIG_AUDIO); }
void eeconfig_update_audio(uint8_t val) { eeprom_update_byte(EECONFIG_AUDIO, val); }
#endif
case ACT_COMMAND: break; #ifdef ONEHAND_ENABLE case ACT_SWAP_HANDS: switch (action.swap.code) { case OP_SH_TOGGLE: if (event.pressed) { swap_hands = !swap_hands; } break; case OP_SH_ON_OFF: swap_hands = event.pressed; break; case OP_SH_OFF_ON: swap_hands = !event.pressed; break; case OP_SH_ON: if (!event.pressed) { swap_hands = true; } break; case OP_SH_OFF: if (!event.pressed) { swap_hands = false; } break; #ifndef NO_ACTION_TAPPING case OP_SH_TAP_TOGGLE: /* tap toggle */ if (tap_count > 0) { if (!event.pressed) { swap_hands = !swap_hands; } } else { swap_hands = event.pressed; } break; default: if (tap_count > 0) { if (event.pressed) { register_code(action.swap.code); } else { unregister_code(action.swap.code); } } else { swap_hands = event.pressed; } #endif } #endif #ifndef NO_ACTION_FUNCTION case ACT_FUNCTION: action_function(record, action.func.id, action.func.opt); break; #endif default: break; } #ifndef NO_ACTION_ONESHOT /* Because we switch layers after a oneshot event, we need to release the * key before we leave the layer or no key up event will be generated. */ if (do_release_oneshot && !(get_oneshot_layer_state() & ONESHOT_PRESSED ) ) { record->event.pressed = false; layer_on(get_oneshot_layer()); process_record(record); layer_off(get_oneshot_layer()); } #endif } /* * Utilities for actions. */ void register_code(uint8_t code) { if (code == KC_NO) { return; } #ifdef LOCKING_SUPPORT_ENABLE else if (KC_LOCKING_CAPS == code) { #ifdef LOCKING_RESYNC_ENABLE // Resync: ignore if caps lock already is on if (host_keyboard_leds() & (1<>8, action.kind.param&0xff); }