static void layer_sticky(uint8_t local_id) { uint8_t keycode = kb_layout_get(LAYER, ROW, COL); if (IS_PRESSED) { uint8_t topLayer = main_layers_peek(0); uint8_t topSticky = main_layers_peek_sticky(0); layer_pop(local_id); if (topLayer == local_id) { if (topSticky == eStickyOnceUp) layer_ids[local_id] = main_layers_push(keycode, eStickyLock); } else { // only the topmost layer on the stack should be in sticky once state if (topSticky == eStickyOnceDown || topSticky == eStickyOnceUp) { layer_pop(topLayer); } layer_ids[local_id] = main_layers_push(keycode, eStickyOnceDown); // this should be the only place we care about this flag being cleared main_arg_any_non_trans_key_pressed = false; } } else { uint8_t topLayer = main_layers_peek(0); uint8_t topSticky = main_layers_peek_sticky(0); if (topLayer == local_id) { if (topSticky == eStickyOnceDown) { // When releasing this sticky key, pop the layer always layer_pop(local_id); if (!main_arg_any_non_trans_key_pressed) { // If no key defined for this layer (a non-transparent key) // was pressed, push the layer again, but in the // StickyOnceUp state layer_ids[local_id] = main_layers_push(keycode, eStickyOnceUp); } } } } }
/* * [name] * Transparent * * [description] * Execute the key that would have been executed if the current layer was not * active */ void kbfun_transparent(void) { main_arg_trans_key_pressed = true; LAYER_OFFSET++; LAYER = main_layers_peek(LAYER_OFFSET); main_layers_pressed[ROW][COL] = LAYER; main_exec_key(); }
/* * Execute the key that would have been executed if the current layer was not * active */ void kbfun_transparent(void) { // TODO maybe re-implement this cleaner? main_arg_trans_key_pressed = true; main_arg_layer_offset++; main_arg_layer = main_layers_peek(main_arg_layer_offset); main_layers_pressed[main_arg_row][main_arg_col] = main_arg_layer; main_exec_key(); }
static void layer_push(uint8_t local_id) { uint8_t keycode = kb_layout_get(LAYER, ROW, COL); layer_pop(local_id); // Only the topmost layer on the stack should be in sticky once state, pop // the top layer if it is in sticky once state uint8_t topSticky = main_layers_peek_sticky(0); if (topSticky == eStickyOnceDown || topSticky == eStickyOnceUp) { main_layers_pop_id(main_layers_peek(0)); } layer_ids[local_id] = main_layers_push(keycode, eStickyNone); }
/* * main() */ int main(void) { kb_init(); // does controller initialization too kb_led_state_power_on(); usb_init(); while (!usb_configured()); kb_led_delay_usb_init(); // give the OS time to load drivers, etc. kb_led_state_ready(); for (;;) { // swap `main_kb_is_pressed` and `main_kb_was_pressed`, then update bool (*temp)[KB_ROWS][KB_COLUMNS] = main_kb_was_pressed; main_kb_was_pressed = main_kb_is_pressed; main_kb_is_pressed = temp; kb_update_matrix(*main_kb_is_pressed); // this loop is responsible to // - "execute" keys when they change state // - keep track of which layers the keys were on when they were pressed // (so they can be released using the function from that layer) // // note // - everything else is the key function's responsibility // - see the keyboard layout file ("keyboard/ergodox/layout/*.c") for // which key is assigned which function (per layer) // - see "lib/key-functions/public/*.c" for the function definitions #define row main_loop_row #define col main_loop_col #define layer main_arg_layer #define is_pressed main_arg_is_pressed #define was_pressed main_arg_was_pressed for (row=0; row<KB_ROWS; row++) { for (col=0; col<KB_COLUMNS; col++) { is_pressed = (*main_kb_is_pressed)[row][col]; was_pressed = (*main_kb_was_pressed)[row][col]; if (is_pressed != was_pressed) { if (is_pressed) { layer = main_layers_peek(0); main_layers_pressed[row][col] = layer; main_arg_trans_key_pressed = false; } else { layer = main_layers_pressed[row][col]; main_arg_trans_key_pressed = main_kb_was_transparent[row][col]; } // set remaining vars, and "execute" key main_arg_row = row; main_arg_col = col; main_arg_layer_offset = 0; main_exec_key(); main_kb_was_transparent[row][col] = main_arg_trans_key_pressed; } } } #undef row #undef col #undef layer #undef is_pressed #undef was_pressed // send the USB report (even if nothing's changed) usb_keyboard_send(); usb_extra_consumer_send(); _delay_ms(MAKEFILE_DEBOUNCE_TIME); // update LEDs /*if (keyboard_leds & (1<<0)) { kb_led_num_on(); }*/ /*else { kb_led_num_off(); }*/ if (keyboard_leds & (1<<1)) { kb_led_caps_on(); } else { kb_led_caps_off(); } if (keyboard_leds & (1<<2)) { kb_led_scroll_on(); } else { kb_led_scroll_off(); } if (keyboard_leds & (1<<3)) { kb_led_compose_on(); } else { kb_led_compose_off(); } if (keyboard_leds & (1<<4)) { kb_led_kana_on(); } else { kb_led_kana_off(); } if (layers_head != 0) { kb_led_num_on(); } else { kb_led_num_off(); } } return 0; }