Пример #1
0
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);
				}
			}
		}
	}
}
Пример #2
0
/*
 * [name]
 *   Toggle
 *
 * [description]
 *   Toggle the key pressed or unpressed
 */
void kbfun_toggle(void) {
	uint8_t keycode = kb_layout_get(LAYER, ROW, COL);

	if (_kbfun_is_pressed(keycode))
		_kbfun_press_release(false, keycode);
	else
		_kbfun_press_release(true, keycode);
}
Пример #3
0
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);
}
Пример #4
0
static void layer_disable_all() {
  // FIXME clean this up

  // letting go off a key releases *all* layers on that key
  for (uint8_t layer=0; layer <= KB_LAYERS; layer++) {
    void (*key_function)(void) = kb_layout_release_get(layer, main_arg_row, main_arg_col);

    if (is_layer_disable(key_function)) {
      uint8_t disable_layer = kb_layout_get(layer, main_arg_row, main_arg_col);
      main_layers_disable(disable_layer);
    }
  }
}
Пример #5
0
static void layer_enable_upto(uint8_t max_layer) {
  // FIXME clean this up

  // pressing a key implicitly activates all lower layers as well
  for (uint8_t layer=0; layer <= KB_LAYERS; layer++) {
    void (*key_function)(void) = kb_layout_press_get(layer, main_arg_row, main_arg_col);

    if (is_layer_enable(key_function)) {
      uint8_t enable_layer = kb_layout_get(layer, main_arg_row, main_arg_col);
      if (enable_layer <= max_layer) {
        main_layers_enable(enable_layer, eStickyNone);
      }
    }
  }
}
Пример #6
0
/*
 * [name]
 *   Two keys => capslock
 *
 * [description]
 *   When assigned to two keys (e.g. the physical left and right shift keys)
 *   (in both the press and release matrices), pressing and holding down one of
 *   the keys will make the second key toggle capslock
 *
 * [note]
 *   If either of the shifts are pressed when the second key is pressed, they
 *   wil be released so that capslock will register properly when pressed.
 *   Capslock will then be pressed and released, and the original state of the
 *   shifts will be restored
 */
void kbfun_2_keys_capslock_press_release(void) {
	static uint8_t keys_pressed;
	static bool lshift_pressed;
	static bool rshift_pressed;

	uint8_t keycode = kb_layout_get(LAYER, ROW, COL);

	if (!IS_PRESSED) keys_pressed--;

	// take care of the key that was actually pressed
	_kbfun_press_release(IS_PRESSED, keycode);

	// take care of capslock (only on the press of the 2nd key)
	if (keys_pressed == 1 && IS_PRESSED) {
		// save the state of left and right shift
		lshift_pressed = _kbfun_is_pressed(KEY_LeftShift);
		rshift_pressed = _kbfun_is_pressed(KEY_RightShift);
		// disable both
		_kbfun_press_release(false, KEY_LeftShift);
		_kbfun_press_release(false, KEY_RightShift);

		// press capslock, then release it
		_kbfun_press_release(true, KEY_CapsLock);
		usb_keyboard_send();
		_kbfun_press_release(false, KEY_CapsLock);
		usb_keyboard_send();

		// restore the state of left and right shift
		if (lshift_pressed)
			_kbfun_press_release(true, KEY_LeftShift);
		if (rshift_pressed)
			_kbfun_press_release(true, KEY_RightShift);
	}

	if (IS_PRESSED) keys_pressed++;
}
Пример #7
0
/*
 * [name]
 *   Press|Release and preserve top layer sticky key state
 *
 * [description]
 *   Generate a normal keypress or keyrelease
 *   While basing the sticky key state transition on whether
 *    kbfun_press_release() was called after kbfun_transparent() generally
 *    works in practice, it is not always the desired behavior. One of the
 *    benefits of sticky keys is avoiding key chording, so we want to make sure
 *    that standard modifiers do not interrupt the sticky key cycle. Use
 *    kbfun_press_release_preserve_sticky() if you want to define a standard
 *    modifier key (shift, control, alt, gui) on the sticky layer instead of
 *    defining the key to be transparent for the layer.
 */
void kbfun_press_release_preserve_sticky(void) {
	uint8_t keycode = kb_layout_get(LAYER, ROW, COL);
	_kbfun_press_release(IS_PRESSED, keycode);
}
Пример #8
0
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 (;;) {
		static uint8_t current_layer = 0;

		// swap `kb_is_pressed` and `kb_was_pressed`, then update
		bool (*temp)[KB_ROWS][KB_COLUMNS] = kb_was_pressed;
		kb_was_pressed = kb_is_pressed;
		kb_is_pressed = temp;

		kb_update_matrix(*kb_is_pressed);

		// call the appropriate function for each key, then send the usb report
		// if necessary
		// - 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), and "lib/key-functions.c"
		//   for their definitions
		for (uint8_t row=0; row<KB_ROWS; row++) {
			for (uint8_t col=0; col<KB_COLUMNS; col++) {
				bool is_pressed = (*kb_is_pressed)[row][col];
				bool was_pressed = (*kb_was_pressed)[row][col];
				if (is_pressed != was_pressed) {
					if (is_pressed) {
						kbfun_funptr_t press_function =
								kb_layout_press_get(current_layer, row, col);
						if (press_function) {
							(*press_function)(
									kb_layout_get(current_layer, row, col),
									&current_layer, &row, &col );
						}
					} else {
						kbfun_funptr_t release_function =
								kb_layout_release_get(current_layer, row, col);
						if (release_function) {
							(*release_function)(
									kb_layout_get(current_layer, row, col),
									&current_layer, &row, &col );
						}
					}

					usb_keyboard_send();
					_delay_ms(KB_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(); }
	}

	return 0;
}
Пример #9
0
/*
 * [name]
 *   Media Key Press Release
 *
 * [description]
 *   Generate a keypress for a media key, such as play/pause, next track, or
 *   previous track
 *
 */
void kbfun_mediakey_press_release(void) {
	uint8_t keycode = kb_layout_get(LAYER, ROW, COL);
	_kbfun_mediakey_press_release(IS_PRESSED, keycode);
}
Пример #10
0
/*
 * [name]
 *   Numpad on
 *
 * [description]
 *   Set the numpad to on (put the numpad layer, specified in the keymap, in an
 *   element at the top of the layer stack, and record that element's id) and
 *   toggle numlock (regardless of whether or not numlock is currently on)
 *
 * [note]
 *   Meant to be assigned (along with "numpad off") instead of a normal numlock
 *   key
 */
void kbfun_layer_push_numpad(void) {
	uint8_t keycode = kb_layout_get(LAYER, ROW, COL);
	main_layers_pop_id(numpad_layer_id);
	numpad_layer_id = main_layers_push(keycode, eStickyNone);
	numpad_toggle_numlock();
}