예제 #1
0
bool process_record_quantum(keyrecord_t *record) {

  /* This gets the keycode from the key pressed */
  keypos_t key = record->event.key;
  uint16_t keycode;

  #if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
    /* TODO: Use store_or_get_action() or a similar function. */
    if (!disable_action_cache) {
      uint8_t layer;

      if (record->event.pressed) {
        layer = layer_switch_get_layer(key);
        update_source_layers_cache(key, layer);
      } else {
        layer = read_source_layers_cache(key);
      }
      keycode = keymap_key_to_keycode(layer, key);
    } else
  #endif
    keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key);

    // This is how you use actions here
    // if (keycode == KC_LEAD) {
    //   action_t action;
    //   action.code = ACTION_DEFAULT_LAYER_SET(0);
    //   process_action(record, action);
    //   return false;
    // }

  #ifdef TAP_DANCE_ENABLE
    preprocess_tap_dance(keycode, record);
  #endif

  if (!(
  #if defined(KEY_LOCK_ENABLE)
    // Must run first to be able to mask key_up events.
    process_key_lock(&keycode, record) &&
  #endif
  #if defined(AUDIO_ENABLE) && defined(AUDIO_CLICKY)
      process_clicky(keycode, record) &&
  #endif //AUDIO_CLICKY
    process_record_kb(keycode, record) &&
  #if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_KEYPRESSES)
    process_rgb_matrix(keycode, record) &&
  #endif
  #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
    process_midi(keycode, record) &&
  #endif
  #ifdef AUDIO_ENABLE
    process_audio(keycode, record) &&
  #endif
  #ifdef STENO_ENABLE
    process_steno(keycode, record) &&
  #endif
  #if ( defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))) && !defined(NO_MUSIC_MODE)
    process_music(keycode, record) &&
  #endif
  #ifdef TAP_DANCE_ENABLE
    process_tap_dance(keycode, record) &&
  #endif
  #ifdef LEADER_ENABLE
    process_leader(keycode, record) &&
  #endif
  #ifdef COMBO_ENABLE
    process_combo(keycode, record) &&
  #endif
  #ifdef UNICODE_ENABLE
    process_unicode(keycode, record) &&
  #endif
  #ifdef UCIS_ENABLE
    process_ucis(keycode, record) &&
  #endif
  #ifdef PRINTING_ENABLE
    process_printer(keycode, record) &&
  #endif
  #ifdef AUTO_SHIFT_ENABLE
    process_auto_shift(keycode, record) &&
  #endif
  #ifdef UNICODEMAP_ENABLE
    process_unicode_map(keycode, record) &&
  #endif
  #ifdef TERMINAL_ENABLE
    process_terminal(keycode, record) &&
  #endif
      true)) {
    return false;
  }

  // Shift / paren setup

  switch(keycode) {
    case RESET:
      if (record->event.pressed) {
        reset_keyboard();
      }
    return false;
    case DEBUG:
      if (record->event.pressed) {
          debug_enable = true;
          print("DEBUG: enabled.\n");
      }
    return false;
  #ifdef FAUXCLICKY_ENABLE
  case FC_TOG:
    if (record->event.pressed) {
      FAUXCLICKY_TOGGLE;
    }
    return false;
  case FC_ON:
    if (record->event.pressed) {
      FAUXCLICKY_ON;
    }
    return false;
  case FC_OFF:
    if (record->event.pressed) {
      FAUXCLICKY_OFF;
    }
    return false;
  #endif
  #if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
  case RGB_TOG:
    // Split keyboards need to trigger on key-up for edge-case issue
    #ifndef SPLIT_KEYBOARD
    if (record->event.pressed) {
    #else
    if (!record->event.pressed) {
    #endif
      rgblight_toggle();
      #ifdef SPLIT_KEYBOARD
          RGB_DIRTY = true;
      #endif
    }
    return false;
  case RGB_MODE_FORWARD:
    if (record->event.pressed) {
      uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT));
      if(shifted) {
        rgblight_step_reverse();
      }
      else {
        rgblight_step();
      }
      #ifdef SPLIT_KEYBOARD
          RGB_DIRTY = true;
      #endif
    }
    return false;
  case RGB_MODE_REVERSE:
    if (record->event.pressed) {
      uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT));
      if(shifted) {
        rgblight_step();
      }
      else {
        rgblight_step_reverse();
      }
      #ifdef SPLIT_KEYBOARD
          RGB_DIRTY = true;
      #endif
    }
    return false;
  case RGB_HUI:
    // Split keyboards need to trigger on key-up for edge-case issue
    #ifndef SPLIT_KEYBOARD
    if (record->event.pressed) {
    #else
    if (!record->event.pressed) {
    #endif
      rgblight_increase_hue();
      #ifdef SPLIT_KEYBOARD
          RGB_DIRTY = true;
      #endif
    }
    return false;
  case RGB_HUD:
    // Split keyboards need to trigger on key-up for edge-case issue
    #ifndef SPLIT_KEYBOARD
    if (record->event.pressed) {
    #else
    if (!record->event.pressed) {
    #endif
      rgblight_decrease_hue();
      #ifdef SPLIT_KEYBOARD
          RGB_DIRTY = true;
      #endif
    }
    return false;
  case RGB_SAI:
    // Split keyboards need to trigger on key-up for edge-case issue
    #ifndef SPLIT_KEYBOARD
    if (record->event.pressed) {
    #else
    if (!record->event.pressed) {
    #endif
      rgblight_increase_sat();
      #ifdef SPLIT_KEYBOARD
          RGB_DIRTY = true;
      #endif
    }
    return false;
  case RGB_SAD:
    // Split keyboards need to trigger on key-up for edge-case issue
    #ifndef SPLIT_KEYBOARD
    if (record->event.pressed) {
    #else
    if (!record->event.pressed) {
    #endif
      rgblight_decrease_sat();
      #ifdef SPLIT_KEYBOARD
          RGB_DIRTY = true;
      #endif
    }
    return false;
  case RGB_VAI:
    // Split keyboards need to trigger on key-up for edge-case issue
    #ifndef SPLIT_KEYBOARD
    if (record->event.pressed) {
    #else
    if (!record->event.pressed) {
    #endif
      rgblight_increase_val();
      #ifdef SPLIT_KEYBOARD
          RGB_DIRTY = true;
      #endif
    }
    return false;
  case RGB_VAD:
    // Split keyboards need to trigger on key-up for edge-case issue
    #ifndef SPLIT_KEYBOARD
    if (record->event.pressed) {
    #else
    if (!record->event.pressed) {
    #endif
      rgblight_decrease_val();
      #ifdef SPLIT_KEYBOARD
          RGB_DIRTY = true;
      #endif
    }
    return false;
  case RGB_SPI:
    if (record->event.pressed) {
      rgblight_increase_speed();
    }
    return false;
  case RGB_SPD:
    if (record->event.pressed) {
      rgblight_decrease_speed();
    }
    return false;
  case RGB_MODE_PLAIN:
    if (record->event.pressed) {
      rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT);
      #ifdef SPLIT_KEYBOARD
          RGB_DIRTY = true;
      #endif
    }
    return false;
  case RGB_MODE_BREATHE:
  #ifdef RGBLIGHT_EFFECT_BREATHING
    if (record->event.pressed) {
      if ((RGBLIGHT_MODE_BREATHING <= rgblight_get_mode()) &&
          (rgblight_get_mode() < RGBLIGHT_MODE_BREATHING_end)) {
        rgblight_step();
      } else {
        rgblight_mode(RGBLIGHT_MODE_BREATHING);
      }
    }
  #endif
    return false;
  case RGB_MODE_RAINBOW:
  #ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
    if (record->event.pressed) {
      if ((RGBLIGHT_MODE_RAINBOW_MOOD <= rgblight_get_mode()) &&
          (rgblight_get_mode() < RGBLIGHT_MODE_RAINBOW_MOOD_end)) {
        rgblight_step();
      } else {
        rgblight_mode(RGBLIGHT_MODE_RAINBOW_MOOD);
      }
    }
  #endif
    return false;
  case RGB_MODE_SWIRL:
  #ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
    if (record->event.pressed) {
      if ((RGBLIGHT_MODE_RAINBOW_SWIRL <= rgblight_get_mode()) &&
          (rgblight_get_mode() < RGBLIGHT_MODE_RAINBOW_SWIRL_end)) {
        rgblight_step();
      } else {
        rgblight_mode(RGBLIGHT_MODE_RAINBOW_SWIRL);
      }
    }
  #endif
    return false;
  case RGB_MODE_SNAKE:
  #ifdef RGBLIGHT_EFFECT_SNAKE
    if (record->event.pressed) {
      if ((RGBLIGHT_MODE_SNAKE <= rgblight_get_mode()) &&
          (rgblight_get_mode() < RGBLIGHT_MODE_SNAKE_end)) {
        rgblight_step();
      } else {
        rgblight_mode(RGBLIGHT_MODE_SNAKE);
      }
    }
  #endif
    return false;
  case RGB_MODE_KNIGHT:
  #ifdef RGBLIGHT_EFFECT_KNIGHT
    if (record->event.pressed) {
      if ((RGBLIGHT_MODE_KNIGHT <= rgblight_get_mode()) &&
          (rgblight_get_mode() < RGBLIGHT_MODE_KNIGHT_end)) {
        rgblight_step();
      } else {
        rgblight_mode(RGBLIGHT_MODE_KNIGHT);
      }
    }
  #endif
    return false;
  case RGB_MODE_XMAS:
  #ifdef RGBLIGHT_EFFECT_CHRISTMAS
    if (record->event.pressed) {
      rgblight_mode(RGBLIGHT_MODE_CHRISTMAS);
    }
  #endif
    return false;
  case RGB_MODE_GRADIENT:
  #ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
    if (record->event.pressed) {
      if ((RGBLIGHT_MODE_STATIC_GRADIENT <= rgblight_get_mode()) &&
          (rgblight_get_mode() < RGBLIGHT_MODE_STATIC_GRADIENT_end)) {
        rgblight_step();
      } else {
        rgblight_mode(RGBLIGHT_MODE_STATIC_GRADIENT);
      }
    }
  #endif
    return false;
  case RGB_MODE_RGBTEST:
  #ifdef RGBLIGHT_EFFECT_RGB_TEST
    if (record->event.pressed) {
      rgblight_mode(RGBLIGHT_MODE_RGB_TEST);
    }
  #endif
    return false;
  #endif // defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
    #ifdef PROTOCOL_LUFA
    case OUT_AUTO:
      if (record->event.pressed) {
        set_output(OUTPUT_AUTO);
      }
      return false;
    case OUT_USB:
      if (record->event.pressed) {
        set_output(OUTPUT_USB);
      }
      return false;
    #ifdef BLUETOOTH_ENABLE
    case OUT_BT:
      if (record->event.pressed) {
        set_output(OUTPUT_BLUETOOTH);
      }
      return false;
    #endif
    #endif
    case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO:
      if (record->event.pressed) {
        // MAGIC actions (BOOTMAGIC without the boot)
        if (!eeconfig_is_enabled()) {
            eeconfig_init();
        }
        /* keymap config */
        keymap_config.raw = eeconfig_read_keymap();
        switch (keycode)
        {
          case MAGIC_SWAP_CONTROL_CAPSLOCK:
            keymap_config.swap_control_capslock = true;
            break;
          case MAGIC_CAPSLOCK_TO_CONTROL:
            keymap_config.capslock_to_control = true;
            break;
          case MAGIC_SWAP_LALT_LGUI:
            keymap_config.swap_lalt_lgui = true;
            break;
          case MAGIC_SWAP_RALT_RGUI:
            keymap_config.swap_ralt_rgui = true;
            break;
          case MAGIC_NO_GUI:
            keymap_config.no_gui = true;
            break;
          case MAGIC_SWAP_GRAVE_ESC:
            keymap_config.swap_grave_esc = true;
            break;
          case MAGIC_SWAP_BACKSLASH_BACKSPACE:
            keymap_config.swap_backslash_backspace = true;
            break;
          case MAGIC_HOST_NKRO:
            keymap_config.nkro = true;
            break;
          case MAGIC_SWAP_ALT_GUI:
            keymap_config.swap_lalt_lgui = true;
            keymap_config.swap_ralt_rgui = true;
            #ifdef AUDIO_ENABLE
              PLAY_SONG(ag_swap_song);
            #endif
            break;
          case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
            keymap_config.swap_control_capslock = false;
            break;
          case MAGIC_UNCAPSLOCK_TO_CONTROL:
            keymap_config.capslock_to_control = false;
            break;
          case MAGIC_UNSWAP_LALT_LGUI:
            keymap_config.swap_lalt_lgui = false;
            break;
          case MAGIC_UNSWAP_RALT_RGUI:
            keymap_config.swap_ralt_rgui = false;
            break;
          case MAGIC_UNNO_GUI:
            keymap_config.no_gui = false;
            break;
          case MAGIC_UNSWAP_GRAVE_ESC:
            keymap_config.swap_grave_esc = false;
            break;
          case MAGIC_UNSWAP_BACKSLASH_BACKSPACE:
            keymap_config.swap_backslash_backspace = false;
            break;
          case MAGIC_UNHOST_NKRO:
            keymap_config.nkro = false;
            break;
          case MAGIC_UNSWAP_ALT_GUI:
            keymap_config.swap_lalt_lgui = false;
            keymap_config.swap_ralt_rgui = false;
            #ifdef AUDIO_ENABLE
              PLAY_SONG(ag_norm_song);
            #endif
            break;
          case MAGIC_TOGGLE_ALT_GUI:
            keymap_config.swap_lalt_lgui = !keymap_config.swap_lalt_lgui;
            keymap_config.swap_ralt_rgui = !keymap_config.swap_ralt_rgui;
            #ifdef AUDIO_ENABLE
              if (keymap_config.swap_ralt_rgui) {
                PLAY_SONG(ag_swap_song);
              } else {
                PLAY_SONG(ag_norm_song);
              }
            #endif
            break;
          case MAGIC_TOGGLE_NKRO:
            keymap_config.nkro = !keymap_config.nkro;
            break;
          default:
            break;
        }
        eeconfig_update_keymap(keymap_config.raw);
        clear_keyboard(); // clear to prevent stuck keys

        return false;
      }
      break;
    case KC_LSPO: {
      if (record->event.pressed) {
        shift_interrupted[0] = false;
        scs_timer[0] = timer_read ();
        register_mods(MOD_BIT(KC_LSFT));
      }
      else {
        #ifdef DISABLE_SPACE_CADET_ROLLOVER
          if (get_mods() & MOD_BIT(KC_RSFT)) {
            shift_interrupted[0] = true;
            shift_interrupted[1] = true;
          }
        #endif
        if (!shift_interrupted[0] && timer_elapsed(scs_timer[0]) < TAPPING_TERM) {
          register_code(LSPO_KEY);
          unregister_code(LSPO_KEY);
        }
        unregister_mods(MOD_BIT(KC_LSFT));
      }
      return false;
    }

    case KC_RSPC: {
      if (record->event.pressed) {
        shift_interrupted[1] = false;
        scs_timer[1] = timer_read ();
        register_mods(MOD_BIT(KC_RSFT));
      }
      else {
        #ifdef DISABLE_SPACE_CADET_ROLLOVER
          if (get_mods() & MOD_BIT(KC_LSFT)) {
            shift_interrupted[0] = true;
            shift_interrupted[1] = true;
          }
        #endif
        if (!shift_interrupted[1] && timer_elapsed(scs_timer[1]) < TAPPING_TERM) {
          register_code(RSPC_KEY);
          unregister_code(RSPC_KEY);
        }
        unregister_mods(MOD_BIT(KC_RSFT));
      }
      return false;
    }

    case KC_SFTENT: {
      if (record->event.pressed) {
        shift_interrupted[1] = false;
        scs_timer[1] = timer_read ();
        register_mods(MOD_BIT(KC_RSFT));
      }
      else if (!shift_interrupted[1] && timer_elapsed(scs_timer[1]) < TAPPING_TERM) {
        unregister_mods(MOD_BIT(KC_RSFT));
        register_code(SFTENT_KEY);
        unregister_code(SFTENT_KEY);
      }
      else {
        unregister_mods(MOD_BIT(KC_RSFT));
      }
      return false;
    }

    case GRAVE_ESC: {
      uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)
                                      |MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)));

#ifdef GRAVE_ESC_ALT_OVERRIDE
      // if ALT is pressed, ESC is always sent
      // this is handy for the cmd+opt+esc shortcut on macOS, among other things.
      if (get_mods() & (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT))) {
        shifted = 0;
      }
#endif

#ifdef GRAVE_ESC_CTRL_OVERRIDE
      // if CTRL is pressed, ESC is always sent
      // this is handy for the ctrl+shift+esc shortcut on windows, among other things.
      if (get_mods() & (MOD_BIT(KC_LCTL) | MOD_BIT(KC_RCTL))) {
        shifted = 0;
      }
#endif

#ifdef GRAVE_ESC_GUI_OVERRIDE
      // if GUI is pressed, ESC is always sent
      if (get_mods() & (MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI))) {
        shifted = 0;
      }
#endif

#ifdef GRAVE_ESC_SHIFT_OVERRIDE
      // if SHIFT is pressed, ESC is always sent
      if (get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) {
        shifted = 0;
      }
#endif

      if (record->event.pressed) {
        grave_esc_was_shifted = shifted;
        add_key(shifted ? KC_GRAVE : KC_ESCAPE);
      }
      else {
        del_key(grave_esc_was_shifted ? KC_GRAVE : KC_ESCAPE);
      }

      send_keyboard_report();
      return false;
    }

#if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_BREATHING)
    case BL_BRTG: {
      if (record->event.pressed)
        breathing_toggle();
      return false;
    }
#endif

    default: {
      shift_interrupted[0] = true;
      shift_interrupted[1] = true;
      break;
    }
  }

  return process_action_kb(record);
}

__attribute__ ((weak))
const bool ascii_to_shift_lut[0x80] PROGMEM = {
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 1, 1, 1, 1, 1, 1, 0,
    1, 1, 1, 1, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 1, 0, 1, 0, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 0, 0, 0, 1, 1,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 1, 1, 1, 1, 0
};

__attribute__ ((weak))
const uint8_t ascii_to_keycode_lut[0x80] PROGMEM = {
    0, 0, 0, 0, 0, 0, 0, 0,
    KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, KC_ESC, 0, 0, 0, 0,
    KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
    KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
    KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
    KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
    KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
    KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
    KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
    KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
    KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
    KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
    KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
    KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
};

void send_string(const char *str) {
  send_string_with_delay(str, 0);
}

void send_string_P(const char *str) {
  send_string_with_delay_P(str, 0);
}

void send_string_with_delay(const char *str, uint8_t interval) {
    while (1) {
        char ascii_code = *str;
        if (!ascii_code) break;
        if (ascii_code == 1) {
          // tap
          uint8_t keycode = *(++str);
          register_code(keycode);
          unregister_code(keycode);
        } else if (ascii_code == 2) {
          // down
          uint8_t keycode = *(++str);
          register_code(keycode);
        } else if (ascii_code == 3) {
          // up
          uint8_t keycode = *(++str);
          unregister_code(keycode);
        } else {
          send_char(ascii_code);
        }
        ++str;
        // interval
        { uint8_t ms = interval; while (ms--) wait_ms(1); }
    }
}

void send_string_with_delay_P(const char *str, uint8_t interval) {
    while (1) {
        char ascii_code = pgm_read_byte(str);
        if (!ascii_code) break;
        if (ascii_code == 1) {
          // tap
          uint8_t keycode = pgm_read_byte(++str);
          register_code(keycode);
          unregister_code(keycode);
        } else if (ascii_code == 2) {
          // down
          uint8_t keycode = pgm_read_byte(++str);
          register_code(keycode);
        } else if (ascii_code == 3) {
          // up
          uint8_t keycode = pgm_read_byte(++str);
          unregister_code(keycode);
        } else {
          send_char(ascii_code);
        }
        ++str;
        // interval
        { uint8_t ms = interval; while (ms--) wait_ms(1); }
    }
}

void send_char(char ascii_code) {
  uint8_t keycode;
  keycode = pgm_read_byte(&ascii_to_keycode_lut[(uint8_t)ascii_code]);
  if (pgm_read_byte(&ascii_to_shift_lut[(uint8_t)ascii_code])) {
      register_code(KC_LSFT);
      register_code(keycode);
      unregister_code(keycode);
      unregister_code(KC_LSFT);
  } else {
      register_code(keycode);
      unregister_code(keycode);
  }
}

void set_single_persistent_default_layer(uint8_t default_layer) {
  #if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
    PLAY_SONG(default_layer_songs[default_layer]);
  #endif
  eeconfig_update_default_layer(1U<<default_layer);
  default_layer_set(1U<<default_layer);
}

uint32_t update_tri_layer_state(uint32_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3) {
  uint32_t mask12 = (1UL << layer1) | (1UL << layer2);
  uint32_t mask3 = 1UL << layer3;
  return (state & mask12) == mask12 ? (state | mask3) : (state & ~mask3);
}

void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
  layer_state_set(update_tri_layer_state(layer_state, layer1, layer2, layer3));
}

void tap_random_base64(void) {
  #if defined(__AVR_ATmega32U4__)
    uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64;
  #else
    uint8_t key = rand() % 64;
  #endif
  switch (key) {
    case 0 ... 25:
      register_code(KC_LSFT);
      register_code(key + KC_A);
      unregister_code(key + KC_A);
      unregister_code(KC_LSFT);
      break;
    case 26 ... 51:
      register_code(key - 26 + KC_A);
      unregister_code(key - 26 + KC_A);
      break;
    case 52:
      register_code(KC_0);
      unregister_code(KC_0);
      break;
    case 53 ... 61:
      register_code(key - 53 + KC_1);
      unregister_code(key - 53 + KC_1);
      break;
    case 62:
      register_code(KC_LSFT);
      register_code(KC_EQL);
      unregister_code(KC_EQL);
      unregister_code(KC_LSFT);
      break;
    case 63:
      register_code(KC_SLSH);
      unregister_code(KC_SLSH);
      break;
  }
}
예제 #2
0
bool process_record_quantum(keyrecord_t *record) {

  /* This gets the keycode from the key pressed */
  keypos_t key = record->event.key;
  uint16_t keycode;

  #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
    /* TODO: Use store_or_get_action() or a similar function. */
    if (!disable_action_cache) {
      uint8_t layer;

      if (record->event.pressed) {
        layer = layer_switch_get_layer(key);
        update_source_layers_cache(key, layer);
      } else {
        layer = read_source_layers_cache(key);
      }
      keycode = keymap_key_to_keycode(layer, key);
    } else
  #endif
    keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key);

    // This is how you use actions here
    // if (keycode == KC_LEAD) {
    //   action_t action;
    //   action.code = ACTION_DEFAULT_LAYER_SET(0);
    //   process_action(record, action);
    //   return false;
    // }

  if (!(
  #if defined(KEY_LOCK_ENABLE)
    // Must run first to be able to mask key_up events.
    process_key_lock(&keycode, record) &&
  #endif
    process_record_kb(keycode, record) &&
  #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
    process_midi(keycode, record) &&
  #endif
  #ifdef AUDIO_ENABLE
    process_audio(keycode, record) &&
  #endif
  #ifdef STENO_ENABLE
    process_steno(keycode, record) &&
  #endif
  #if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
    process_music(keycode, record) &&
  #endif
  #ifdef TAP_DANCE_ENABLE
    process_tap_dance(keycode, record) &&
  #endif
  #ifndef DISABLE_LEADER
    process_leader(keycode, record) &&
  #endif
  #ifndef DISABLE_CHORDING
    process_chording(keycode, record) &&
  #endif
  #ifdef COMBO_ENABLE
    process_combo(keycode, record) &&
  #endif
  #ifdef UNICODE_ENABLE
    process_unicode(keycode, record) &&
  #endif
  #ifdef UCIS_ENABLE
    process_ucis(keycode, record) &&
  #endif
  #ifdef PRINTING_ENABLE
    process_printer(keycode, record) &&
  #endif
  #ifdef AUTO_SHIFT_ENABLE
    process_auto_shift(keycode, record) &&
  #endif
  #ifdef UNICODEMAP_ENABLE
    process_unicode_map(keycode, record) &&
  #endif
  #ifdef TERMINAL_ENABLE
    process_terminal(keycode, record) &&
  #endif
      true)) {
    return false;
  }

  // Shift / paren setup

  switch(keycode) {
    case RESET:
      if (record->event.pressed) {
        reset_keyboard();
      }
    return false;
    case DEBUG:
      if (record->event.pressed) {
          debug_enable = true;
          print("DEBUG: enabled.\n");
      }
    return false;
  #ifdef FAUXCLICKY_ENABLE
  case FC_TOG:
    if (record->event.pressed) {
      FAUXCLICKY_TOGGLE;
    }
    return false;
  case FC_ON:
    if (record->event.pressed) {
      FAUXCLICKY_ON;
    }
    return false;
  case FC_OFF:
    if (record->event.pressed) {
      FAUXCLICKY_OFF;
    }
    return false;
  #endif
  #ifdef RGBLIGHT_ENABLE
  case RGB_TOG:
    if (record->event.pressed) {
      rgblight_toggle();
    }
    return false;
  case RGB_MOD:
    if (record->event.pressed) {
      rgblight_step();
    }
    return false;
  case RGB_SMOD:
    // same as RBG_MOD, but if shift is pressed, it will use the reverese direction instead.
    if (record->event.pressed) {
      uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT));
      if(shifted) {
        rgblight_step_reverse();
      }
      else {
        rgblight_step();
      }
    }
    return false;
  case RGB_HUI:
    if (record->event.pressed) {
      rgblight_increase_hue();
    }
    return false;
  case RGB_HUD:
    if (record->event.pressed) {
      rgblight_decrease_hue();
    }
    return false;
  case RGB_SAI:
    if (record->event.pressed) {
      rgblight_increase_sat();
    }
    return false;
  case RGB_SAD:
    if (record->event.pressed) {
      rgblight_decrease_sat();
    }
    return false;
  case RGB_VAI:
    if (record->event.pressed) {
      rgblight_increase_val();
    }
    return false;
  case RGB_VAD:
    if (record->event.pressed) {
      rgblight_decrease_val();
    }
    return false;
  case RGB_MODE_PLAIN:
    if (record->event.pressed) {
      rgblight_mode(1);
    }
    return false;
  case RGB_MODE_BREATHE:
    if (record->event.pressed) {
      if ((2 <= rgblight_get_mode()) && (rgblight_get_mode() < 5)) {
        rgblight_step();
      } else {
        rgblight_mode(2);
      }
    }
    return false;
  case RGB_MODE_RAINBOW:
    if (record->event.pressed) {
      if ((6 <= rgblight_get_mode()) && (rgblight_get_mode() < 8)) {
        rgblight_step();
      } else {
        rgblight_mode(6);
      }
    }
    return false;
  case RGB_MODE_SWIRL:
    if (record->event.pressed) {
      if ((9 <= rgblight_get_mode()) && (rgblight_get_mode() < 14)) {
        rgblight_step();
      } else {
        rgblight_mode(9);
      }
    }
    return false;
  case RGB_MODE_SNAKE:
    if (record->event.pressed) {
      if ((15 <= rgblight_get_mode()) && (rgblight_get_mode() < 20)) {
        rgblight_step();
      } else {
        rgblight_mode(15);
      }
    }
    return false;
  case RGB_MODE_KNIGHT:
    if (record->event.pressed) {
      if ((21 <= rgblight_get_mode()) && (rgblight_get_mode() < 23)) {
        rgblight_step();
      } else {
        rgblight_mode(21);
      }
    }
    return false;
  case RGB_MODE_XMAS:
    if (record->event.pressed) {
      rgblight_mode(24);
    }
    return false;
  case RGB_MODE_GRADIENT:
    if (record->event.pressed) {
      if ((25 <= rgblight_get_mode()) && (rgblight_get_mode() < 34)) {
        rgblight_step();
      } else {
        rgblight_mode(25);
      }
    }
    return false;
  #endif
    #ifdef PROTOCOL_LUFA
    case OUT_AUTO:
      if (record->event.pressed) {
        set_output(OUTPUT_AUTO);
      }
      return false;
    case OUT_USB:
      if (record->event.pressed) {
        set_output(OUTPUT_USB);
      }
      return false;
    #ifdef BLUETOOTH_ENABLE
    case OUT_BT:
      if (record->event.pressed) {
        set_output(OUTPUT_BLUETOOTH);
      }
      return false;
    #endif
    #endif
    case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO:
      if (record->event.pressed) {
        // MAGIC actions (BOOTMAGIC without the boot)
        if (!eeconfig_is_enabled()) {
            eeconfig_init();
        }
        /* keymap config */
        keymap_config.raw = eeconfig_read_keymap();
        switch (keycode)
        {
          case MAGIC_SWAP_CONTROL_CAPSLOCK:
            keymap_config.swap_control_capslock = true;
            break;
          case MAGIC_CAPSLOCK_TO_CONTROL:
            keymap_config.capslock_to_control = true;
            break;
          case MAGIC_SWAP_LALT_LGUI:
            keymap_config.swap_lalt_lgui = true;
            break;
          case MAGIC_SWAP_RALT_RGUI:
            keymap_config.swap_ralt_rgui = true;
            break;
          case MAGIC_NO_GUI:
            keymap_config.no_gui = true;
            break;
          case MAGIC_SWAP_GRAVE_ESC:
            keymap_config.swap_grave_esc = true;
            break;
          case MAGIC_SWAP_BACKSLASH_BACKSPACE:
            keymap_config.swap_backslash_backspace = true;
            break;
          case MAGIC_HOST_NKRO:
            keymap_config.nkro = true;
            break;
          case MAGIC_SWAP_ALT_GUI:
            keymap_config.swap_lalt_lgui = true;
            keymap_config.swap_ralt_rgui = true;
            #ifdef AUDIO_ENABLE
              PLAY_SONG(ag_swap_song);
            #endif
            break;
          case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
            keymap_config.swap_control_capslock = false;
            break;
          case MAGIC_UNCAPSLOCK_TO_CONTROL:
            keymap_config.capslock_to_control = false;
            break;
          case MAGIC_UNSWAP_LALT_LGUI:
            keymap_config.swap_lalt_lgui = false;
            break;
          case MAGIC_UNSWAP_RALT_RGUI:
            keymap_config.swap_ralt_rgui = false;
            break;
          case MAGIC_UNNO_GUI:
            keymap_config.no_gui = false;
            break;
          case MAGIC_UNSWAP_GRAVE_ESC:
            keymap_config.swap_grave_esc = false;
            break;
          case MAGIC_UNSWAP_BACKSLASH_BACKSPACE:
            keymap_config.swap_backslash_backspace = false;
            break;
          case MAGIC_UNHOST_NKRO:
            keymap_config.nkro = false;
            break;
          case MAGIC_UNSWAP_ALT_GUI:
            keymap_config.swap_lalt_lgui = false;
            keymap_config.swap_ralt_rgui = false;
            #ifdef AUDIO_ENABLE
              PLAY_SONG(ag_norm_song);
            #endif
            break;
          case MAGIC_TOGGLE_NKRO:
            keymap_config.nkro = !keymap_config.nkro;
            break;
          default:
            break;
        }
        eeconfig_update_keymap(keymap_config.raw);
        clear_keyboard(); // clear to prevent stuck keys

        return false;
      }
      break;
    case KC_LSPO: {
      if (record->event.pressed) {
        shift_interrupted[0] = false;
        scs_timer[0] = timer_read ();
        register_mods(MOD_BIT(KC_LSFT));
      }
      else {
        #ifdef DISABLE_SPACE_CADET_ROLLOVER
          if (get_mods() & MOD_BIT(KC_RSFT)) {
            shift_interrupted[0] = true;
            shift_interrupted[1] = true;
          }
        #endif
        if (!shift_interrupted[0] && timer_elapsed(scs_timer[0]) < TAPPING_TERM) {
          register_code(LSPO_KEY);
          unregister_code(LSPO_KEY);
        }
        unregister_mods(MOD_BIT(KC_LSFT));
      }
      return false;
    }

    case KC_RSPC: {
      if (record->event.pressed) {
        shift_interrupted[1] = false;
        scs_timer[1] = timer_read ();
        register_mods(MOD_BIT(KC_RSFT));
      }
      else {
        #ifdef DISABLE_SPACE_CADET_ROLLOVER
          if (get_mods() & MOD_BIT(KC_LSFT)) {
            shift_interrupted[0] = true;
            shift_interrupted[1] = true;
          }
        #endif
        if (!shift_interrupted[1] && timer_elapsed(scs_timer[1]) < TAPPING_TERM) {
          register_code(RSPC_KEY);
          unregister_code(RSPC_KEY);
        }
        unregister_mods(MOD_BIT(KC_RSFT));
      }
      return false;
    }
    case GRAVE_ESC: {
      uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)
                                      |MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)));

#ifdef GRAVE_ESC_ALT_OVERRIDE
      // if ALT is pressed, ESC is always sent
      // this is handy for the cmd+opt+esc shortcut on macOS, among other things.
      if (get_mods() & (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT))) {
        shifted = 0;
      }
#endif

#ifdef GRAVE_ESC_CTRL_OVERRIDE
      // if CTRL is pressed, ESC is always sent
      // this is handy for the ctrl+shift+esc shortcut on windows, among other things.
      if (get_mods() & (MOD_BIT(KC_LCTL) | MOD_BIT(KC_RCTL))) {
        shifted = 0;
      }
#endif

#ifdef GRAVE_ESC_GUI_OVERRIDE
      // if GUI is pressed, ESC is always sent
      if (get_mods() & (MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI))) {
        shifted = 0;
      }
#endif

#ifdef GRAVE_ESC_SHIFT_OVERRIDE
      // if SHIFT is pressed, ESC is always sent
      if (get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) {
        shifted = 0;
      }
#endif

      if (record->event.pressed) {
        grave_esc_was_shifted = shifted;
        add_key(shifted ? KC_GRAVE : KC_ESCAPE);
      }
      else {
        del_key(grave_esc_was_shifted ? KC_GRAVE : KC_ESCAPE);
      }

      send_keyboard_report();
    }
    default: {
      shift_interrupted[0] = true;
      shift_interrupted[1] = true;
      break;
    }
  }

  return process_action_kb(record);
}
예제 #3
0
bool process_record_quantum(keyrecord_t *record) {

  /* This gets the keycode from the key pressed */
  keypos_t key = record->event.key;
  uint16_t keycode;

  #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
    /* TODO: Use store_or_get_action() or a similar function. */
    if (!disable_action_cache) {
      uint8_t layer;

      if (record->event.pressed) {
        layer = layer_switch_get_layer(key);
        update_source_layers_cache(key, layer);
      } else {
        layer = read_source_layers_cache(key);
      }
      keycode = keymap_key_to_keycode(layer, key);
    } else
  #endif
    keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key);

    // This is how you use actions here
    // if (keycode == KC_LEAD) {
    //   action_t action;
    //   action.code = ACTION_DEFAULT_LAYER_SET(0);
    //   process_action(record, action);
    //   return false;
    // }

  if (!(
    process_record_kb(keycode, record) &&
  #ifdef MIDI_ENABLE
    process_midi(keycode, record) &&
  #endif
  #ifdef AUDIO_ENABLE
    process_music(keycode, record) &&
  #endif
  #ifdef TAP_DANCE_ENABLE
    process_tap_dance(keycode, record) &&
  #endif
  #ifndef DISABLE_LEADER
    process_leader(keycode, record) &&
  #endif
  #ifndef DISABLE_CHORDING
    process_chording(keycode, record) &&
  #endif
  #ifdef UNICODE_ENABLE
    process_unicode(keycode, record) &&
  #endif
  #ifdef UCIS_ENABLE
    process_ucis(keycode, record) &&
  #endif
      true)) {
    return false;
  }

  // Shift / paren setup

  switch(keycode) {
    case RESET:
      if (record->event.pressed) {
        reset_keyboard();
      }
	  return false;
      break;
    case DEBUG:
      if (record->event.pressed) {
          print("\nDEBUG: enabled.\n");
          debug_enable = true;
      }
	  return false;
      break;
	#ifdef RGBLIGHT_ENABLE
	case RGB_TOG:
		if (record->event.pressed) {
			rgblight_toggle();
      }
	  return false;
      break;
	case RGB_MOD:
		if (record->event.pressed) {
			rgblight_step();
      }
	  return false;
      break;
	case RGB_HUI:
		if (record->event.pressed) {
			rgblight_increase_hue();
      }
	  return false;
      break;
	case RGB_HUD:
		if (record->event.pressed) {
			rgblight_decrease_hue();
      }
	  return false;
      break;
	case RGB_SAI:
		if (record->event.pressed) {
			rgblight_increase_sat();
      }
	  return false;
      break;
	case RGB_SAD:
		if (record->event.pressed) {
			rgblight_decrease_sat();
      }
	  return false;
      break;
	case RGB_VAI:
		if (record->event.pressed) {
			rgblight_increase_val();
      }
	  return false;
      break;
	case RGB_VAD:
		if (record->event.pressed) {
			rgblight_decrease_val();
      }
	  return false;
      break;
	#endif
    case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_UNSWAP_ALT_GUI:
      if (record->event.pressed) {
        // MAGIC actions (BOOTMAGIC without the boot)
        if (!eeconfig_is_enabled()) {
            eeconfig_init();
        }
        /* keymap config */
        keymap_config.raw = eeconfig_read_keymap();
        if (keycode == MAGIC_SWAP_CONTROL_CAPSLOCK) {
            keymap_config.swap_control_capslock = 1;
        } else if (keycode == MAGIC_CAPSLOCK_TO_CONTROL) {
            keymap_config.capslock_to_control = 1;
        } else if (keycode == MAGIC_SWAP_LALT_LGUI) {
            keymap_config.swap_lalt_lgui = 1;
        } else if (keycode == MAGIC_SWAP_RALT_RGUI) {
            keymap_config.swap_ralt_rgui = 1;
        } else if (keycode == MAGIC_NO_GUI) {
            keymap_config.no_gui = 1;
        } else if (keycode == MAGIC_SWAP_GRAVE_ESC) {
            keymap_config.swap_grave_esc = 1;
        } else if (keycode == MAGIC_SWAP_BACKSLASH_BACKSPACE) {
            keymap_config.swap_backslash_backspace = 1;
        } else if (keycode == MAGIC_HOST_NKRO) {
            keymap_config.nkro = 1;
        } else if (keycode == MAGIC_SWAP_ALT_GUI) {
            keymap_config.swap_lalt_lgui = 1;
            keymap_config.swap_ralt_rgui = 1;
        }
        /* UNs */
        else if (keycode == MAGIC_UNSWAP_CONTROL_CAPSLOCK) {
            keymap_config.swap_control_capslock = 0;
        } else if (keycode == MAGIC_UNCAPSLOCK_TO_CONTROL) {
            keymap_config.capslock_to_control = 0;
        } else if (keycode == MAGIC_UNSWAP_LALT_LGUI) {
            keymap_config.swap_lalt_lgui = 0;
        } else if (keycode == MAGIC_UNSWAP_RALT_RGUI) {
            keymap_config.swap_ralt_rgui = 0;
        } else if (keycode == MAGIC_UNNO_GUI) {
            keymap_config.no_gui = 0;
        } else if (keycode == MAGIC_UNSWAP_GRAVE_ESC) {
            keymap_config.swap_grave_esc = 0;
        } else if (keycode == MAGIC_UNSWAP_BACKSLASH_BACKSPACE) {
            keymap_config.swap_backslash_backspace = 0;
        } else if (keycode == MAGIC_UNHOST_NKRO) {
            keymap_config.nkro = 0;
        } else if (keycode == MAGIC_UNSWAP_ALT_GUI) {
            keymap_config.swap_lalt_lgui = 0;
            keymap_config.swap_ralt_rgui = 0;
        }
        eeconfig_update_keymap(keymap_config.raw);
        return false;
      }
      break;
    case KC_LSPO: {
      if (record->event.pressed) {
        shift_interrupted[0] = false;
        register_mods(MOD_BIT(KC_LSFT));
      }
      else {
        #ifdef DISABLE_SPACE_CADET_ROLLOVER
          if (get_mods() & MOD_BIT(KC_RSFT)) {
            shift_interrupted[0] = true;
            shift_interrupted[1] = true;
          }
        #endif
        if (!shift_interrupted[0]) {
          register_code(LSPO_KEY);
          unregister_code(LSPO_KEY);
        }
        unregister_mods(MOD_BIT(KC_LSFT));
      }
      return false;
      break;
    }

    case KC_RSPC: {
      if (record->event.pressed) {
        shift_interrupted[1] = false;
        register_mods(MOD_BIT(KC_RSFT));
      }
      else {
        #ifdef DISABLE_SPACE_CADET_ROLLOVER
          if (get_mods() & MOD_BIT(KC_LSFT)) {
            shift_interrupted[0] = true;
            shift_interrupted[1] = true;
          }
        #endif
        if (!shift_interrupted[1]) {
          register_code(RSPC_KEY);
          unregister_code(RSPC_KEY);
        }
        unregister_mods(MOD_BIT(KC_RSFT));
      }
      return false;
      break;
    }
    default: {
      shift_interrupted[0] = true;
      shift_interrupted[1] = true;
      break;
    }
  }

  return process_action_kb(record);
}
예제 #4
0
bool process_record_quantum(keyrecord_t *record) {

  /* This gets the keycode from the key pressed */
  keypos_t key = record->event.key;
  uint16_t keycode;

  #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
    /* TODO: Use store_or_get_action() or a similar function. */
    if (!disable_action_cache) {
      uint8_t layer;

      if (record->event.pressed) {
        layer = layer_switch_get_layer(key);
        update_source_layers_cache(key, layer);
      } else {
        layer = read_source_layers_cache(key);
      }
      keycode = keymap_key_to_keycode(layer, key);
    } else
  #endif
    keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key);

    // This is how you use actions here
    // if (keycode == KC_LEAD) {
    //   action_t action;
    //   action.code = ACTION_DEFAULT_LAYER_SET(0);
    //   process_action(record, action);
    //   return false;
    // }

  if (!(
    process_record_kb(keycode, record) &&
  #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
    process_midi(keycode, record) &&
  #endif
  #ifdef AUDIO_ENABLE
    process_audio(keycode, record) &&
  #endif
  #if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
    process_music(keycode, record) &&
  #endif
  #ifdef TAP_DANCE_ENABLE
    process_tap_dance(keycode, record) &&
  #endif
  #ifndef DISABLE_LEADER
    process_leader(keycode, record) &&
  #endif
  #ifndef DISABLE_CHORDING
    process_chording(keycode, record) &&
  #endif
  #ifdef COMBO_ENABLE
    process_combo(keycode, record) &&
  #endif
  #ifdef UNICODE_ENABLE
    process_unicode(keycode, record) &&
  #endif
  #ifdef UCIS_ENABLE
    process_ucis(keycode, record) &&
  #endif
  #ifdef PRINTING_ENABLE
    process_printer(keycode, record) &&
  #endif
  #ifdef UNICODEMAP_ENABLE
    process_unicode_map(keycode, record) &&
  #endif
      true)) {
    return false;
  }

  // Shift / paren setup

  switch(keycode) {
    case RESET:
      if (record->event.pressed) {
        reset_keyboard();
      }
	  return false;
      break;
    case DEBUG:
      if (record->event.pressed) {
          print("\nDEBUG: enabled.\n");
          debug_enable = true;
      }
	  return false;
      break;
  #ifdef FAUXCLICKY_ENABLE
  case FC_TOG:
    if (record->event.pressed) {
      FAUXCLICKY_TOGGLE;
    }
    return false;
    break;
  case FC_ON:
    if (record->event.pressed) {
      FAUXCLICKY_ON;
    }
    return false;
    break;
  case FC_OFF:
    if (record->event.pressed) {
      FAUXCLICKY_OFF;
    }
    return false;
    break;
  #endif
	#ifdef RGBLIGHT_ENABLE
	case RGB_TOG:
		if (record->event.pressed) {
			rgblight_toggle();
      }
	  return false;
      break;
	case RGB_MOD:
		if (record->event.pressed) {
			rgblight_step();
      }
	  return false;
      break;
	case RGB_HUI:
		if (record->event.pressed) {
			rgblight_increase_hue();
      }
	  return false;
      break;
	case RGB_HUD:
		if (record->event.pressed) {
			rgblight_decrease_hue();
      }
	  return false;
      break;
	case RGB_SAI:
		if (record->event.pressed) {
			rgblight_increase_sat();
      }
	  return false;
      break;
	case RGB_SAD:
		if (record->event.pressed) {
			rgblight_decrease_sat();
      }
	  return false;
      break;
	case RGB_VAI:
		if (record->event.pressed) {
			rgblight_increase_val();
      }
	  return false;
      break;
	case RGB_VAD:
		if (record->event.pressed) {
			rgblight_decrease_val();
      }
	  return false;
      break;
	#endif
    #ifdef PROTOCOL_LUFA
    case OUT_AUTO:
      if (record->event.pressed) {
        set_output(OUTPUT_AUTO);
      }
      return false;
      break;
    case OUT_USB:
      if (record->event.pressed) {
        set_output(OUTPUT_USB);
      }
      return false;
      break;
    #ifdef BLUETOOTH_ENABLE
    case OUT_BT:
      if (record->event.pressed) {
        set_output(OUTPUT_BLUETOOTH);
      }
      return false;
      break;
    #endif
    #endif
    case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO:
      if (record->event.pressed) {
        // MAGIC actions (BOOTMAGIC without the boot)
        if (!eeconfig_is_enabled()) {
            eeconfig_init();
        }
        /* keymap config */
        keymap_config.raw = eeconfig_read_keymap();
        switch (keycode)
        {
          case MAGIC_SWAP_CONTROL_CAPSLOCK:
            keymap_config.swap_control_capslock = true;
            break;
          case MAGIC_CAPSLOCK_TO_CONTROL:
            keymap_config.capslock_to_control = true;
            break;
          case MAGIC_SWAP_LALT_LGUI:
            keymap_config.swap_lalt_lgui = true;
            break;
          case MAGIC_SWAP_RALT_RGUI:
            keymap_config.swap_ralt_rgui = true;
            break;
          case MAGIC_NO_GUI:
            keymap_config.no_gui = true;
            break;
          case MAGIC_SWAP_GRAVE_ESC:
            keymap_config.swap_grave_esc = true;
            break;
          case MAGIC_SWAP_BACKSLASH_BACKSPACE:
            keymap_config.swap_backslash_backspace = true;
            break;
          case MAGIC_HOST_NKRO:
            keymap_config.nkro = true;
            break;
          case MAGIC_SWAP_ALT_GUI:
            keymap_config.swap_lalt_lgui = true;
            keymap_config.swap_ralt_rgui = true;
            break;
          case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
            keymap_config.swap_control_capslock = false;
            break;
          case MAGIC_UNCAPSLOCK_TO_CONTROL:
            keymap_config.capslock_to_control = false;
            break;
          case MAGIC_UNSWAP_LALT_LGUI:
            keymap_config.swap_lalt_lgui = false;
            break;
          case MAGIC_UNSWAP_RALT_RGUI:
            keymap_config.swap_ralt_rgui = false;
            break;
          case MAGIC_UNNO_GUI:
            keymap_config.no_gui = false;
            break;
          case MAGIC_UNSWAP_GRAVE_ESC:
            keymap_config.swap_grave_esc = false;
            break;
          case MAGIC_UNSWAP_BACKSLASH_BACKSPACE:
            keymap_config.swap_backslash_backspace = false;
            break;
          case MAGIC_UNHOST_NKRO:
            keymap_config.nkro = false;
            break;
          case MAGIC_UNSWAP_ALT_GUI:
            keymap_config.swap_lalt_lgui = false;
            keymap_config.swap_ralt_rgui = false;
            break;
          case MAGIC_TOGGLE_NKRO:
            keymap_config.nkro = !keymap_config.nkro;
            break;
          default:
            break;
        }
        eeconfig_update_keymap(keymap_config.raw);
        clear_keyboard(); // clear to prevent stuck keys

        return false;
      }
      break;
    case KC_LSPO: {
      if (record->event.pressed) {
        shift_interrupted[0] = false;
        scs_timer[0] = timer_read ();
        register_mods(MOD_BIT(KC_LSFT));
      }
      else {
        #ifdef DISABLE_SPACE_CADET_ROLLOVER
          if (get_mods() & MOD_BIT(KC_RSFT)) {
            shift_interrupted[0] = true;
            shift_interrupted[1] = true;
          }
        #endif
        if (!shift_interrupted[0] && timer_elapsed(scs_timer[0]) < TAPPING_TERM) {
          register_code(LSPO_KEY);
          unregister_code(LSPO_KEY);
        }
        unregister_mods(MOD_BIT(KC_LSFT));
      }
      return false;
      // break;
    }

    case KC_RSPC: {
      if (record->event.pressed) {
        shift_interrupted[1] = false;
        scs_timer[1] = timer_read ();
        register_mods(MOD_BIT(KC_RSFT));
      }
      else {
        #ifdef DISABLE_SPACE_CADET_ROLLOVER
          if (get_mods() & MOD_BIT(KC_LSFT)) {
            shift_interrupted[0] = true;
            shift_interrupted[1] = true;
          }
        #endif
        if (!shift_interrupted[1] && timer_elapsed(scs_timer[1]) < TAPPING_TERM) {
          register_code(RSPC_KEY);
          unregister_code(RSPC_KEY);
        }
        unregister_mods(MOD_BIT(KC_RSFT));
      }
      return false;
      // break;
    }
    case GRAVE_ESC: {
      void (*method)(uint8_t) = (record->event.pressed) ? &add_key : &del_key;
      uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)
                                      |MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)));

      method(shifted ? KC_GRAVE : KC_ESCAPE);
      send_keyboard_report(); 
    }
    default: {
      shift_interrupted[0] = true;
      shift_interrupted[1] = true;
      break;
    }
  }

  return process_action_kb(record);
}
예제 #5
0
void process_action(keyrecord_t *record)
{
    keyevent_t event = record->event;
#ifndef NO_ACTION_TAPPING
    uint8_t tap_count = record->tap.count;
#endif

    if (IS_NOEVENT(event)) {
        return;
    }

    process_action_kb(record);

    action_t action = store_or_get_action(event.pressed, 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();

    if (event.pressed) {
        // clear the potential weak mods left by previously pressed keys
        clear_weak_mods();
    }
    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)) {
                    // 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)
                    add_mods(mods);
                } else {
                    add_weak_mods(mods);
                }
                send_keyboard_report();
            }
            register_code(action.key.code);
        } else {
            unregister_code(action.key.code);
            if (mods) {
                if (IS_MOD(action.key.code)) {
                    del_mods(mods);
                } else {
                    del_weak_mods(mods);
                }
                send_keyboard_report();
            }
        }
    }
    break;
#ifndef NO_ACTION_TAPPING
    case ACT_LMODS_TAP:
    case ACT_RMODS_TAP:
    {
        uint8_t mods = (action.kind.id == ACT_LMODS_TAP) ?  action.key.mods :
                       action.key.mods<<4;
        switch (action.layer_tap.code) {
#ifndef NO_ACTION_ONESHOT
        case MODS_ONESHOT:
            // Oneshot modifier
            if (event.pressed) {
                if (tap_count == 0) {
                    register_mods(mods);
                }
                else if (tap_count == 1) {
                    dprint("MODS_TAP: Oneshot: start\n");
                    set_oneshot_mods(mods);
                }
                else {
                    register_mods(mods);
                }
            } else {
                if (tap_count == 0) {
                    clear_oneshot_mods();
                    unregister_mods(mods);
                }
                else if (tap_count == 1) {
                    // Retain Oneshot mods
                }
                else {
                    clear_oneshot_mods();
                    unregister_mods(mods);
                }
            }
            break;
#endif
        case MODS_TAP_TOGGLE:
            if (event.pressed) {
                if (tap_count <= TAPPING_TOGGLE) {
                    register_mods(mods);
                }
            } else {
                if (tap_count < TAPPING_TOGGLE) {
                    unregister_mods(mods);
                }
            }
            break;
        default:
            if (event.pressed) {
                if (tap_count > 0) {
#ifndef IGNORE_MOD_TAP_INTERRUPT
                    if (record->tap.interrupted) {
                        dprint("mods_tap: tap: cancel: add_mods\n");
                        // ad hoc: set 0 to cancel tap
                        record->tap.count = 0;
                        register_mods(mods);
                    } else
#endif
                    {
                        dprint("MODS_TAP: Tap: register_code\n");
                        register_code(action.key.code);
                    }
                } else {
                    dprint("MODS_TAP: No tap: add_mods\n");
                    register_mods(mods);
                }
            } else {
                if (tap_count > 0) {
                    dprint("MODS_TAP: Tap: unregister_code\n");
                    unregister_code(action.key.code);
                } else {
                    dprint("MODS_TAP: No tap: add_mods\n");
                    unregister_mods(mods);
                }
            }
            break;
        }
    }
    break;
#endif
#ifdef EXTRAKEY_ENABLE
    /* other HID usage */
    case ACT_USAGE:
        switch (action.usage.page) {
        case PAGE_SYSTEM:
            if (event.pressed) {
                host_system_send(action.usage.code);
            } else {
                host_system_send(0);
            }
            break;
        case PAGE_CONSUMER:
            if (event.pressed) {
                host_consumer_send(action.usage.code);
            } else {
                host_consumer_send(0);
            }
            break;
        }
        break;
#endif
#ifdef MOUSEKEY_ENABLE
    /* Mouse key */
    case ACT_MOUSEKEY:
        if (event.pressed) {
            mousekey_on(action.key.code);
            mousekey_send();
        } else {
            mousekey_off(action.key.code);
            mousekey_send();
        }
        break;
#endif
#ifndef NO_ACTION_LAYER
    case ACT_LAYER:
        if (action.layer_bitop.on == 0) {
            /* Default Layer Bitwise Operation */
            if (!event.pressed) {
                uint8_t shift = action.layer_bitop.part*4;
                uint32_t bits = ((uint32_t)action.layer_bitop.bits)<<shift;
                uint32_t mask = (action.layer_bitop.xbit) ? ~(((uint32_t)0xf)<<shift) : 0;
                switch (action.layer_bitop.op) {
                case OP_BIT_AND:
                    default_layer_and(bits | mask);
                    break;
                case OP_BIT_OR:
                    default_layer_or(bits | mask);
                    break;
                case OP_BIT_XOR:
                    default_layer_xor(bits | mask);
                    break;
                case OP_BIT_SET:
                    default_layer_and(mask);
                    default_layer_or(bits);
                    break;
                }
            }
        } else {
            /* Layer Bitwise Operation */
            if (event.pressed ? (action.layer_bitop.on & ON_PRESS) :
                    (action.layer_bitop.on & ON_RELEASE)) {
                uint8_t shift = action.layer_bitop.part*4;
                uint32_t bits = ((uint32_t)action.layer_bitop.bits)<<shift;
                uint32_t mask = (action.layer_bitop.xbit) ? ~(((uint32_t)0xf)<<shift) : 0;
                switch (action.layer_bitop.op) {
                case OP_BIT_AND:
                    layer_and(bits | mask);
                    break;
                case OP_BIT_OR:
                    layer_or(bits | mask);
                    break;
                case OP_BIT_XOR:
                    layer_xor(bits | mask);
                    break;
                case OP_BIT_SET:
                    layer_and(mask);
                    layer_or(bits);
                    break;
                }
            }
        }
        break;
#ifndef NO_ACTION_TAPPING
    case ACT_LAYER_TAP:
    case ACT_LAYER_TAP_EXT:
        switch (action.layer_tap.code) {
        case 0xe0 ... 0xef:
            /* layer On/Off with modifiers(left only) */
            if (event.pressed) {
                layer_on(action.layer_tap.val);
                register_mods(action.layer_tap.code & 0x0f);
            } else {
                layer_off(action.layer_tap.val);
                unregister_mods(action.layer_tap.code & 0x0f);
            }
            break;
        case OP_TAP_TOGGLE:
            /* tap toggle */
            if (event.pressed) {
                if (tap_count < TAPPING_TOGGLE) {
                    layer_invert(action.layer_tap.val);
                }
            } else {
                if (tap_count <= TAPPING_TOGGLE) {
                    layer_invert(action.layer_tap.val);
                }
            }
            break;
        case OP_ON_OFF:
            event.pressed ? layer_on(action.layer_tap.val) :
            layer_off(action.layer_tap.val);
            break;
        case OP_OFF_ON:
            event.pressed ? layer_off(action.layer_tap.val) :
            layer_on(action.layer_tap.val);
            break;
        case OP_SET_CLEAR:
            event.pressed ? layer_move(action.layer_tap.val) :
            layer_clear();
            break;
        default:
            /* tap key */
            if (event.pressed) {
                if (tap_count > 0) {
                    dprint("KEYMAP_TAP_KEY: Tap: register_code\n");
                    register_code(action.layer_tap.code);
                } else {
                    dprint("KEYMAP_TAP_KEY: No tap: On on press\n");
                    layer_on(action.layer_tap.val);
                }
            } else {
                if (tap_count > 0) {
                    dprint("KEYMAP_TAP_KEY: Tap: unregister_code\n");
                    unregister_code(action.layer_tap.code);
                } else {
                    dprint("KEYMAP_TAP_KEY: No tap: Off on release\n");
                    layer_off(action.layer_tap.val);
                }
            }
            break;
        }
        break;
#endif
#endif
        /* Extentions */
#ifndef NO_ACTION_MACRO
    case ACT_MACRO:
        action_macro_play(action_get_macro(record, action.func.id, action.func.opt));
        break;
#endif
#ifdef BACKLIGHT_ENABLE
    case ACT_BACKLIGHT:
        if (!event.pressed) {
            switch (action.backlight.opt) {
            case BACKLIGHT_INCREASE:
                backlight_increase();
                break;
            case BACKLIGHT_DECREASE:
                backlight_decrease();
                break;
            case BACKLIGHT_TOGGLE:
                backlight_toggle();
                break;
            case BACKLIGHT_STEP:
                backlight_step();
                break;
            case BACKLIGHT_LEVEL:
                backlight_level(action.backlight.level);
                break;
            }
        }
        break;
#endif
    case ACT_COMMAND:
        break;
#ifndef NO_ACTION_FUNCTION
    case ACT_FUNCTION:
        action_function(record, action.func.id, action.func.opt);
        break;
#endif
    default:
        break;
    }
}
예제 #6
0
bool process_record_quantum(keyrecord_t *record) {

  /* This gets the keycode from the key pressed */
  keypos_t key = record->event.key;
  uint16_t keycode;

  #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
    uint8_t layer;

    if (record->event.pressed) {
      layer = layer_switch_get_layer(key);
      update_source_layers_cache(key, layer);
    } else {
      layer = read_source_layers_cache(key);
    }
    keycode = keymap_key_to_keycode(layer, key);
  #else
    keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key);
  #endif

    // This is how you use actions here
    // if (keycode == KC_LEAD) {
    //   action_t action;
    //   action.code = ACTION_DEFAULT_LAYER_SET(0);
    //   process_action(record, action);
    //   return false;
    // }

  if (!(
    process_record_kb(keycode, record) &&
  #ifdef MIDI_ENABLE
    process_midi(keycode, record) &&
  #endif
  #ifdef AUDIO_ENABLE
    process_music(keycode, record) &&
  #endif
  #ifdef TAP_DANCE_ENABLE
    process_tap_dance(keycode, record) &&
  #endif
  #ifndef DISABLE_LEADER
    process_leader(keycode, record) &&
  #endif
  #ifndef DISABLE_CHORDING
    process_chording(keycode, record) &&
  #endif
  #ifdef UNICODE_ENABLE
    process_unicode(keycode, record) &&
  #endif
      true)) {
    return false;
  }

  // Shift / paren setup

  switch(keycode) {
    case RESET:
      if (record->event.pressed) {
        clear_keyboard();
        #ifdef AUDIO_ENABLE
          stop_all_notes();
          shutdown_user();
        #endif
        wait_ms(250);
        #ifdef CATERINA_BOOTLOADER
            *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific
        #endif
        bootloader_jump();
        return false;
      }
      break;
    case DEBUG:
      if (record->event.pressed) {
          print("\nDEBUG: enabled.\n");
          debug_enable = true;
          return false;
      }
      break;
    case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_UNSWAP_ALT_GUI:
      if (record->event.pressed) {
        // MAGIC actions (BOOTMAGIC without the boot)
        if (!eeconfig_is_enabled()) {
            eeconfig_init();
        }
        /* keymap config */
        keymap_config.raw = eeconfig_read_keymap();
        if (keycode == MAGIC_SWAP_CONTROL_CAPSLOCK) {
            keymap_config.swap_control_capslock = 1;
        } else if (keycode == MAGIC_CAPSLOCK_TO_CONTROL) {
            keymap_config.capslock_to_control = 1;
        } else if (keycode == MAGIC_SWAP_LALT_LGUI) {
            keymap_config.swap_lalt_lgui = 1;
        } else if (keycode == MAGIC_SWAP_RALT_RGUI) {
            keymap_config.swap_ralt_rgui = 1;
        } else if (keycode == MAGIC_NO_GUI) {
            keymap_config.no_gui = 1;
        } else if (keycode == MAGIC_SWAP_GRAVE_ESC) {
            keymap_config.swap_grave_esc = 1;
        } else if (keycode == MAGIC_SWAP_BACKSLASH_BACKSPACE) {
            keymap_config.swap_backslash_backspace = 1;
        } else if (keycode == MAGIC_HOST_NKRO) {
            keymap_config.nkro = 1;
        } else if (keycode == MAGIC_SWAP_ALT_GUI) {
            keymap_config.swap_lalt_lgui = 1;
            keymap_config.swap_ralt_rgui = 1;
        }
        /* UNs */
        else if (keycode == MAGIC_UNSWAP_CONTROL_CAPSLOCK) {
            keymap_config.swap_control_capslock = 0;
        } else if (keycode == MAGIC_UNCAPSLOCK_TO_CONTROL) {
            keymap_config.capslock_to_control = 0;
        } else if (keycode == MAGIC_UNSWAP_LALT_LGUI) {
            keymap_config.swap_lalt_lgui = 0;
        } else if (keycode == MAGIC_UNSWAP_RALT_RGUI) {
            keymap_config.swap_ralt_rgui = 0;
        } else if (keycode == MAGIC_UNNO_GUI) {
            keymap_config.no_gui = 0;
        } else if (keycode == MAGIC_UNSWAP_GRAVE_ESC) {
            keymap_config.swap_grave_esc = 0;
        } else if (keycode == MAGIC_UNSWAP_BACKSLASH_BACKSPACE) {
            keymap_config.swap_backslash_backspace = 0;
        } else if (keycode == MAGIC_UNHOST_NKRO) {
            keymap_config.nkro = 0;
        } else if (keycode == MAGIC_UNSWAP_ALT_GUI) {
            keymap_config.swap_lalt_lgui = 0;
            keymap_config.swap_ralt_rgui = 0;
        }
        eeconfig_update_keymap(keymap_config.raw);
        return false;
      }
      break;
    case KC_LSPO: {
      if (record->event.pressed) {
        shift_interrupted[0] = false;
        register_mods(MOD_BIT(KC_LSFT));
      }
      else {
        if (!shift_interrupted[0]) {
          register_code(LSPO_KEY);
          unregister_code(LSPO_KEY);
        }
        unregister_mods(MOD_BIT(KC_LSFT));
      }
      return false;
      break;
    }

    case KC_RSPC: {
      if (record->event.pressed) {
        shift_interrupted[1] = false;
        register_mods(MOD_BIT(KC_RSFT));
      }
      else {
        if (!shift_interrupted[1]) {
          register_code(RSPC_KEY);
          unregister_code(RSPC_KEY);
        }
        unregister_mods(MOD_BIT(KC_RSFT));
      }
      return false;
      break;
    }
    default: {
      shift_interrupted[0] = true;
      shift_interrupted[1] = true;
      break;
    }
  }

  return process_action_kb(record);
}