void matrix_scan_keymap(void) { // runs frequently to update info uint8_t modifiers = get_mods(); uint8_t led_usb_state = host_keyboard_leds(); uint8_t one_shot = get_oneshot_mods(); if (!skip_leds) { ergodox_board_led_off(); ergodox_right_led_1_off(); ergodox_right_led_2_off(); ergodox_right_led_3_off(); // Since we're not using the LEDs here for layer indication anymore, // then lets use them for modifier indicators. Shame we don't have 4... // Also, no "else", since we want to know each, independently. if ( ( modifiers | one_shot ) & MOD_MASK_SHIFT || led_usb_state & (1<<USB_LED_CAPS_LOCK) ) { ergodox_right_led_2_on(); ergodox_right_led_2_set( 50 ); } if ( ( modifiers | one_shot ) & MOD_MASK_CTRL) { ergodox_right_led_1_on(); ergodox_right_led_1_set( 10 ); } if ( ( modifiers | one_shot ) & MOD_MASK_ALT) { ergodox_right_led_3_on(); ergodox_right_led_3_set( 10 ); } } };
bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { uint16_t idx = keycode - QK_TAP_DANCE; qk_tap_dance_action_t *action; if (last_td && last_td != keycode) { (&tap_dance_actions[last_td - QK_TAP_DANCE])->state.interrupted = true; } switch(keycode) { case QK_TAP_DANCE ... QK_TAP_DANCE_MAX: if ((int16_t)idx > highest_td) highest_td = idx; action = &tap_dance_actions[idx]; action->state.pressed = record->event.pressed; if (record->event.pressed) { action->state.keycode = keycode; action->state.count++; action->state.timer = timer_read(); action->state.oneshot_mods = get_oneshot_mods(); action->state.weak_mods = get_mods(); action->state.weak_mods |= get_weak_mods(); process_tap_dance_action_on_each_tap (action); if (last_td && last_td != keycode) { qk_tap_dance_action_t *paction = &tap_dance_actions[last_td - QK_TAP_DANCE]; paction->state.interrupted = true; process_tap_dance_action_on_dance_finished (paction); reset_tap_dance (&paction->state); } last_td = keycode; } break; default: if (!record->event.pressed) return true; if (highest_td == -1) return true; for (int i = 0; i <= highest_td; i++) { action = &tap_dance_actions[i]; if (action->state.count == 0) continue; action->state.interrupted = true; process_tap_dance_action_on_dance_finished (action); reset_tap_dance (&action->state); } break; } return true; }
void matrix_scan_indicator(void) { current_mod = get_mods(); current_led = host_keyboard_leds(); current_osm = get_oneshot_mods(); set_rgb_indicators(current_mod, current_led, current_osm); last_mod = current_mod; last_led = current_led; last_osm = current_osm; }
// Runs constantly in the background, in a loop. void matrix_scan_user(void) { uint8_t layer = biton32(layer_state); ergodox_led_all_off(); ergodox_led_all_set(LED_BRIGHTNESS_LO); switch (layer) { case BASE: current_layer = BASE; break; case KEYPAD: current_layer = KEYPAD; break; default: // none break; } // layer leds if (current_layer == KEYPAD) { ergodox_right_led_3_on(); } // capslock if (host_keyboard_leds() & (3<<USB_LED_CAPS_LOCK)) { ergodox_right_led_1_on(); } // Temporary leds // The function layer takes over other layers and we need to reflect that on the leds. // If the current layer is the BASE, we simply turn on the FN led, but if the current // layer is the KEYPAD, than we must turn it off before turning on the FN led. if (layer == FN && !has_oneshot_layer_timed_out()) { ergodox_right_led_3_off(); ergodox_right_led_2_on(); } // if the shifted is pressed I show the case led in a brighter color. This is nice to // differenciate the shift from the capslock. // Notice that I make sure that we're not using the shift on a chord shortcut (pressing // shift togather with other modifiers). if((keyboard_report->mods & (MOD_BIT(KC_LSFT) | MOD_BIT(KC_RSFT)) && // is shift pressed and there is no other !(keyboard_report->mods & (~MOD_BIT(KC_LSFT) & ~MOD_BIT(KC_RSFT)))) || // modifier being pressed as well (get_oneshot_mods() & (MOD_BIT(KC_LSFT) | MOD_BIT(KC_RSFT)) && !has_oneshot_mods_timed_out())) { // or the one shot shift didn't timed out ergodox_right_led_1_set(LED_BRIGHTNESS_HI); ergodox_right_led_1_on(); } };
uint32_t layer_state_set_keymap (uint32_t state) { uint8_t modifiders = get_mods(); uint8_t led_usb_state = host_keyboard_leds(); uint8_t one_shot = get_oneshot_mods(); if (modifiders & MODS_SHIFT_MASK || led_usb_state & (1<<USB_LED_CAPS_LOCK) || one_shot & MODS_SHIFT_MASK) { rgblight_sethsv_at(0, 255, 255, 5); rgblight_sethsv_at(0, 255, 255, 10); } if (modifiders & MODS_CTRL_MASK || one_shot & MODS_CTRL_MASK) { rgblight_sethsv_at(51, 255, 255, 6); rgblight_sethsv_at(51, 255, 255, 9); } if (modifiders & MODS_ALT_MASK || one_shot & MODS_ALT_MASK) { rgblight_sethsv_at(120, 255, 255, 7); rgblight_sethsv_at(120, 255, 255, 8); } return state; }
void matrix_scan_keymap (void) { static uint8_t current_mods; static uint8_t current_host_leds; static uint8_t current_oneshot_mods; static bool has_status_changed = true; if ( current_mods != get_mods() || current_host_leds != host_keyboard_leds() || current_oneshot_mods != get_oneshot_mods()) { has_status_changed = true; current_mods = get_mods(); current_host_leds = host_keyboard_leds(); current_oneshot_mods = get_oneshot_mods(); } if (has_status_changed) { has_status_changed = false; if (current_mods & MODS_SHIFT_MASK || current_host_leds & (1<<USB_LED_CAPS_LOCK) || current_oneshot_mods & MODS_SHIFT_MASK) { rgblight_sethsv_at(0, 255, 255, 5); rgblight_sethsv_at(0, 255, 255, 10); } else { rgblight_sethsv_default_helper(5); rgblight_sethsv_default_helper(10); } if (current_mods & MODS_CTRL_MASK || current_oneshot_mods & MODS_CTRL_MASK) { rgblight_sethsv_at(51, 255, 255, 6); rgblight_sethsv_at(51, 255, 255, 9); } else { rgblight_sethsv_default_helper(6); rgblight_sethsv_default_helper(9); } if (current_mods & MODS_GUI_MASK || current_oneshot_mods & MODS_GUI_MASK) { rgblight_sethsv_at(120, 255, 255, 7); rgblight_sethsv_at(120, 255, 255, 8); } else { rgblight_sethsv_default_helper(7); rgblight_sethsv_default_helper(8); } } }
void matrix_init_rgb(void) { #ifdef INDICATOR_LIGHTS current_mod = last_mod = get_mods(); current_led = last_led = host_keyboard_leds(); current_osm = last_osm = get_oneshot_mods(); #endif if (userspace_config.rgb_layer_change) { rgblight_enable_noeeprom(); switch (biton32(eeconfig_read_default_layer())) { case _COLEMAK: rgblight_sethsv_noeeprom_magenta(); break; case _DVORAK: rgblight_sethsv_noeeprom_springgreen(); break; case _WORKMAN: rgblight_sethsv_noeeprom_goldenrod(); break; default: rgblight_sethsv_noeeprom_cyan(); break; } rgblight_mode_noeeprom(1); } }
void matrix_scan_user(void) { uint8_t layer = biton32(layer_state); if (keyboard_report->mods & MOD_BIT(KC_LSFT) || ((get_oneshot_mods() & MOD_BIT(KC_LSFT)) && !has_oneshot_mods_timed_out())) { ergodox_right_led_1_set(LED_BRIGHTNESS_HI); ergodox_right_led_1_on(); } else if (layer == RAISE || layer == AUX) { ergodox_right_led_1_set(LED_BRIGHTNESS_LO); ergodox_right_led_1_on(); } else { ergodox_right_led_1_off(); } if (keyboard_report->mods & MOD_BIT(KC_LCTL) || ((get_oneshot_mods() & MOD_BIT(KC_LCTL)) && !has_oneshot_mods_timed_out())) { ergodox_right_led_2_set(LED_BRIGHTNESS_HI); ergodox_right_led_2_on(); } else if (layer == LOWER || layer == AUX) { ergodox_right_led_2_set(LED_BRIGHTNESS_LO); ergodox_right_led_2_on(); } else { ergodox_right_led_2_off(); } if (keyboard_report->mods & MOD_BIT(KC_LALT) || ((get_oneshot_mods() & MOD_BIT(KC_LALT)) && !has_oneshot_mods_timed_out())) { ergodox_right_led_3_set(LED_BRIGHTNESS_HI); ergodox_right_led_3_on(); } else if (layer == COLE || layer == AUX) { ergodox_right_led_3_set(LED_BRIGHTNESS_LO); ergodox_right_led_3_on(); } else { ergodox_right_led_3_off(); } LEADER_DICTIONARY() { leading = false; leader_end(); SEQ_THREE_KEYS(KC_W, KC_I, KC_N) { os_type = OS_WIN; }; SEQ_THREE_KEYS(KC_O, KC_S, KC_X) { os_type = OS_OSX; }; SEQ_THREE_KEYS(KC_L, KC_I, KC_N) { os_type = OS_LIN; }; SEQ_ONE_KEY(KC_A) { switch (os_type) { case OS_WIN: tap(KC_NLCK); register_code(KC_RALT); tap(KC_KP_0); tap(KC_KP_2); tap(KC_KP_2); tap(KC_KP_8); unregister_code(KC_RALT); tap(KC_NLCK); break; case OS_OSX: register_code(KC_RALT); register_code(KC_RSFT); register_code(KC_SCLN); unregister_code(KC_SCLN); unregister_code(KC_RSFT); unregister_code(KC_RALT); tap(KC_A); break; case OS_LIN: tap(KC_RALT); tap(KC_DQT); tap(KC_A); break; } } SEQ_TWO_KEYS(KC_A, KC_A) { switch (os_type) { case OS_WIN: tap(KC_NLCK); register_code(KC_RALT); tap(KC_KP_0); tap(KC_KP_1); tap(KC_KP_9); tap(KC_KP_6); unregister_code(KC_RALT); tap(KC_NLCK); break; case OS_OSX: register_code(KC_RALT); register_code(KC_RSFT); register_code(KC_SCLN); unregister_code(KC_SCLN); unregister_code(KC_RSFT); unregister_code(KC_RALT); register_code(KC_LSFT); register_code(KC_A); unregister_code(KC_A); unregister_code(KC_LSFT); break; case OS_LIN: tap(KC_RALT); tap(KC_DQT); register_code(KC_LSFT); register_code(KC_A); unregister_code(KC_A); unregister_code(KC_LSFT); break; } } SEQ_ONE_KEY(KC_O) { switch (os_type) { case OS_WIN: tap(KC_NLCK); register_code(KC_RALT); tap(KC_KP_0); tap(KC_KP_2); tap(KC_KP_4); tap(KC_KP_6); unregister_code(KC_RALT); tap(KC_NLCK); break; case OS_OSX: register_code(KC_RALT); register_code(KC_RSFT); register_code(KC_SCLN); unregister_code(KC_SCLN); unregister_code(KC_RSFT); unregister_code(KC_RALT); tap(KC_O); break; case OS_LIN: tap(KC_RALT); tap(KC_DQT); tap(KC_O); break; } } SEQ_TWO_KEYS(KC_O, KC_O) { switch (os_type) { case OS_WIN: tap(KC_NLCK); register_code(KC_RALT); tap(KC_KP_0); tap(KC_KP_2); tap(KC_KP_1); tap(KC_KP_4); unregister_code(KC_RALT); tap(KC_NLCK); break; case OS_OSX: register_code(KC_RALT); register_code(KC_RSFT); register_code(KC_SCLN); unregister_code(KC_SCLN); unregister_code(KC_RSFT); unregister_code(KC_RALT); tap(LSFT(KC_O)); break; case OS_LIN: tap(KC_RALT); tap(KC_DQT); register_code(KC_LSFT); register_code(KC_O); unregister_code(KC_O); unregister_code(KC_LSFT); break; } } SEQ_ONE_KEY(KC_U) { switch (os_type) { case OS_WIN: tap(KC_NLCK); register_code(KC_RALT); tap(KC_KP_0); tap(KC_KP_2); tap(KC_KP_5); tap(KC_KP_2); unregister_code(KC_RALT); tap(KC_NLCK); break; case OS_OSX: register_code(KC_RALT); register_code(KC_RSFT); register_code(KC_SCLN); unregister_code(KC_SCLN); unregister_code(KC_RSFT); unregister_code(KC_RALT); tap(KC_U); break; case OS_LIN: tap(KC_RALT); tap(KC_DQT); tap(KC_U); break; } } SEQ_TWO_KEYS(KC_U, KC_U) { switch (os_type) { case OS_WIN: tap(KC_NLCK); register_code(KC_RALT); tap(KC_KP_0); tap(KC_KP_2); tap(KC_KP_2); tap(KC_KP_0); unregister_code(KC_RALT); tap(KC_NLCK); break; case OS_OSX: register_code(KC_RALT); register_code(KC_RSFT); register_code(KC_SCLN); unregister_code(KC_SCLN); unregister_code(KC_RSFT); unregister_code(KC_RALT); tap(LSFT(KC_U)); break; case OS_LIN: tap(KC_RALT); tap(KC_DQT); register_code(KC_LSFT); register_code(KC_U); unregister_code(KC_U); unregister_code(KC_LSFT); break; } } SEQ_ONE_KEY(KC_S) { switch (os_type) { case OS_WIN: tap(KC_NLCK); register_code(KC_RALT); tap(KC_KP_0); tap(KC_KP_2); tap(KC_KP_2); tap(KC_KP_3); unregister_code(KC_RALT); tap(KC_NLCK); break; case OS_OSX: register_code(KC_RALT); tap(KC_S); unregister_code(KC_RALT); break; case OS_LIN: tap(KC_RALT); tap(KC_S); tap(KC_S); break; } } } }
void matrix_scan_indicator(void) { if (has_initialized) { set_rgb_indicators(get_mods(), host_keyboard_leds(), get_oneshot_mods()); } }
void render_status(void) { oled_write_P(PSTR("Layer"), false); switch (biton32(layer_state)) { case 0: oled_write_P(PSTR("Base "), false); break; case _RAISE: oled_write_P(PSTR("Raise"), false); break; case _LOWER: oled_write_P(PSTR("Lower"), false); break; case _ADJUST: oled_write_P(PSTR("Adjst"), false); break; default: oled_write_P(PSTR("Unkn "), false); break; } oled_write_P(PSTR("Lyout"), false); switch (biton32(default_layer_state)) { case _QWERTY: oled_write_P(PSTR("QWRTY"), false); break; case _COLEMAK: oled_write_P(PSTR("COLMK"), false); break; case _DVORAK: oled_write_P(PSTR("DVRAK"), false); break; case _WORKMAN: oled_write_P(PSTR("WRKMN"), false); break; case _NORMAN: oled_write_P(PSTR("NORMN"), false); break; case _MALTRON: oled_write_P(PSTR("MLTRN"), false); break; case _EUCALYN: oled_write_P(PSTR("ECLYN"), false); break; case _CARPLAX: oled_write_P(PSTR("CRPLX"), false); break; } uint8_t modifiers = get_mods(); uint8_t one_shot = get_oneshot_mods(); oled_write_P(PSTR("Mods:"), false); oled_write_P( (modifiers & MOD_MASK_SHIFT || one_shot & MOD_MASK_SHIFT) ? PSTR(" SFT ") : PSTR(" "), false); oled_write_P( (modifiers & MOD_MASK_CTRL || one_shot & MOD_MASK_CTRL ) ? PSTR(" CTL ") : PSTR(" "), false); oled_write_P( (modifiers & MOD_MASK_ALT || one_shot & MOD_MASK_ALT ) ? PSTR(" ALT ") : PSTR(" "), false); oled_write_P( (modifiers & MOD_MASK_GUI || one_shot & MOD_MASK_GUI ) ? PSTR(" GUI ") : PSTR(" "), false); oled_write_P(PSTR("BTMGK"), false); if (keymap_config.swap_lalt_lgui) { oled_write_P(PSTR(" Mac "), false); } else { oled_write_P(PSTR(" Win "), false); } uint8_t led_usb_state = host_keyboard_leds(); oled_write_P(PSTR("Lock:"), false); oled_write_P(led_usb_state & (1<<USB_LED_NUM_LOCK) ? PSTR(" NUM ") : PSTR(" "), false); oled_write_P(led_usb_state & (1<<USB_LED_CAPS_LOCK) ? PSTR(" CAPS") : PSTR(" "), false); oled_write_P(led_usb_state & (1<<USB_LED_SCROLL_LOCK) ? PSTR(" SCRL") : PSTR(" "), false); oled_write(keylog_str, false); }
static DECLARE_THREAD_FUNCTION(visualizerThread, arg) { (void)arg; GListener event_listener; geventListenerInit(&event_listener); geventAttachSource(&event_listener, (GSourceHandle)¤t_status, 0); visualizer_keyboard_status_t initial_status = { .default_layer = 0xFFFFFFFF, .layer = 0xFFFFFFFF, .mods = 0xFF, .leds = 0xFFFFFFFF, .suspended = false, }; visualizer_state_t state = { .status = initial_status, .current_lcd_color = 0, #ifdef LCD_ENABLE .font_fixed5x8 = gdispOpenFont("fixed_5x8"), .font_dejavusansbold12 = gdispOpenFont("DejaVuSansBold12") #endif }; initialize_user_visualizer(&state); state.prev_lcd_color = state.current_lcd_color; #ifdef LCD_BACKLIGHT_ENABLE lcd_backlight_color( LCD_HUE(state.current_lcd_color), LCD_SAT(state.current_lcd_color), LCD_INT(state.current_lcd_color)); #endif systemticks_t sleep_time = TIME_INFINITE; systemticks_t current_time = gfxSystemTicks(); while(true) { systemticks_t new_time = gfxSystemTicks(); systemticks_t delta = new_time - current_time; current_time = new_time; bool enabled = visualizer_enabled; if (!same_status(&state.status, ¤t_status)) { if (visualizer_enabled) { if (current_status.suspended) { stop_all_keyframe_animations(); visualizer_enabled = false; state.status = current_status; user_visualizer_suspend(&state); } else { state.status = current_status; update_user_visualizer_state(&state); } state.prev_lcd_color = state.current_lcd_color; } } if (!enabled && state.status.suspended && current_status.suspended == false) { // Setting the status to the initial status will force an update // when the visualizer is enabled again state.status = initial_status; state.status.suspended = false; stop_all_keyframe_animations(); user_visualizer_resume(&state); state.prev_lcd_color = state.current_lcd_color; } sleep_time = TIME_INFINITE; for (int i=0;i<MAX_SIMULTANEOUS_ANIMATIONS;i++) { if (animations[i]) { update_keyframe_animation(animations[i], &state, delta, &sleep_time); } } #ifdef LED_ENABLE gdispGFlush(LED_DISPLAY); #endif #ifdef EMULATOR draw_emulator(); #endif // The animation can enable the visualizer // And we might need to update the state when that happens // so don't sleep if (enabled != visualizer_enabled) { sleep_time = 0; } systemticks_t after_update = gfxSystemTicks(); unsigned update_delta = after_update - current_time; if (sleep_time != TIME_INFINITE) { if (sleep_time > update_delta) { sleep_time -= update_delta; } else { sleep_time = 0; } } dprintf("Update took %d, last delta %d, sleep_time %d\n", update_delta, delta, sleep_time); #ifdef PROTOCOL_CHIBIOS // The gEventWait function really takes milliseconds, even if the documentation says ticks. // Unfortunately there's no generic ugfx conversion from system time to milliseconds, // so let's do it in a platform dependent way. // On windows the system ticks is the same as milliseconds anyway if (sleep_time != TIME_INFINITE) { sleep_time = ST2MS(sleep_time); } #endif geventEventWait(&event_listener, sleep_time); } #ifdef LCD_ENABLE gdispCloseFont(state.font_fixed5x8); gdispCloseFont(state.font_dejavusansbold12); #endif return 0; } void visualizer_init(void) { gfxInit(); #ifdef LCD_BACKLIGHT_ENABLE lcd_backlight_init(); #endif #ifdef SERIAL_LINK_ENABLE add_remote_objects(remote_objects, sizeof(remote_objects) / sizeof(remote_object_t*) ); #endif #ifdef LCD_ENABLE LCD_DISPLAY = get_lcd_display(); #endif #ifdef LED_ENABLE LED_DISPLAY = get_led_display(); #endif // We are using a low priority thread, the idea is to have it run only // when the main thread is sleeping during the matrix scanning gfxThreadCreate(visualizerThreadStack, sizeof(visualizerThreadStack), VISUALIZER_THREAD_PRIORITY, visualizerThread, NULL); } void update_status(bool changed) { if (changed) { GSourceListener* listener = geventGetSourceListener((GSourceHandle)¤t_status, NULL); if (listener) { geventSendEvent(listener); } } #ifdef SERIAL_LINK_ENABLE static systime_t last_update = 0; systime_t current_update = chVTGetSystemTimeX(); systime_t delta = current_update - last_update; if (changed || delta > MS2ST(10)) { last_update = current_update; visualizer_keyboard_status_t* r = begin_write_current_status(); *r = current_status; end_write_current_status(); } #endif } uint8_t visualizer_get_mods() { uint8_t mods = get_mods(); #ifndef NO_ACTION_ONESHOT if (!has_oneshot_mods_timed_out()) { mods |= get_oneshot_mods(); } #endif return mods; } void visualizer_update(uint32_t default_state, uint32_t state, uint8_t mods, uint32_t leds) { // Note that there's a small race condition here, the thread could read // a state where one of these are set but not the other. But this should // not really matter as it will be fixed during the next loop step. // Alternatively a mutex could be used instead of the volatile variables bool changed = false; #ifdef SERIAL_LINK_ENABLE if (is_serial_link_connected ()) { visualizer_keyboard_status_t* new_status = read_current_status(); if (new_status) { if (!same_status(¤t_status, new_status)) { changed = true; current_status = *new_status; } } } else { #else { #endif visualizer_keyboard_status_t new_status = { .layer = state, .default_layer = default_state, .mods = mods, .leds = leds, .suspended = current_status.suspended, }; if (!same_status(¤t_status, &new_status)) { changed = true; current_status = new_status; } } update_status(changed); } void visualizer_suspend(void) { current_status.suspended = true; update_status(true); } void visualizer_resume(void) { current_status.suspended = false; update_status(true); }