2012-04-10 10:44:27 +02:00
|
|
|
/* ----------------------------------------------------------------------------
|
|
|
|
* key functions: code
|
2012-04-25 08:22:20 +02:00
|
|
|
*
|
|
|
|
* These functions may do.. pretty much anything rational that thay like. If
|
|
|
|
* they want keycodes to be sent to the host in an aggrate report, they're
|
|
|
|
* responsible for modifying the appropriate report variables.
|
2012-04-10 10:44:27 +02:00
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
|
|
|
* Released under The MIT License (MIT) (see "license.md")
|
|
|
|
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
|
|
|
* ------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
2012-07-06 02:10:18 +02:00
|
|
|
#include <avr/interrupt.h>
|
2012-04-29 08:40:00 +02:00
|
|
|
#include "lib-other/pjrc/usb_keyboard/usb_keyboard.h"
|
|
|
|
#include "lib/data-types.h"
|
2012-05-14 03:06:17 +02:00
|
|
|
#include "lib/usb/usage-page/keyboard.h"
|
2012-04-10 10:44:27 +02:00
|
|
|
#include "keyboard.h"
|
|
|
|
|
2012-06-21 01:56:24 +02:00
|
|
|
#include "key-functions.h"
|
2012-06-15 07:02:57 +02:00
|
|
|
#include "key-functions--private.h"
|
2012-04-28 00:39:26 +02:00
|
|
|
|
2012-06-15 07:02:57 +02:00
|
|
|
|
2012-06-21 01:56:24 +02:00
|
|
|
// ----------------------------------------------------------------------------
|
2012-07-06 00:48:18 +02:00
|
|
|
// public functions (not for keys)
|
2012-06-21 01:56:24 +02:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Exec key
|
|
|
|
* - Execute the keypress or keyrelease function (if it exists) of the key at
|
|
|
|
* the current possition. Pass the keycode at the current position, and pass
|
|
|
|
* all other arguments as received
|
|
|
|
*/
|
|
|
|
void _kbfun_exec_key( KBFUN_FUNCTION_ARGS ) {
|
|
|
|
kbfun_funptr_t key_function =
|
|
|
|
( (pressed_)
|
|
|
|
? kb_layout_press_get(layer_, *row_, *col_)
|
|
|
|
: kb_layout_release_get(layer_, *row_, *col_) );
|
|
|
|
|
|
|
|
if (key_function)
|
|
|
|
(*key_function)(
|
|
|
|
pressed_,
|
|
|
|
kb_layout_get(layer_, *row_, *col_),
|
|
|
|
layer_,
|
|
|
|
row_,
|
|
|
|
col_,
|
|
|
|
current_layer_,
|
|
|
|
current_layers_,
|
|
|
|
pressed_layers_ );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-06-15 07:02:57 +02:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// private functions
|
2012-06-15 01:01:34 +02:00
|
|
|
// ----------------------------------------------------------------------------
|
2012-04-12 06:05:45 +02:00
|
|
|
|
2012-06-15 01:01:34 +02:00
|
|
|
/*
|
|
|
|
* Generate a normal keypress or keyrelease
|
|
|
|
*
|
|
|
|
* Arguments
|
|
|
|
* - keycode: the keycode to use
|
|
|
|
* - pressed: whether to generate a keypress (true) or keyrelease (false)
|
|
|
|
*
|
|
|
|
* Note
|
|
|
|
* - Because of the way USB does things, what this actually does is either add
|
2012-06-15 07:02:57 +02:00
|
|
|
* or remove 'keycode' from the list of currently pressed keys, to be sent at
|
|
|
|
* the end of the current cycle (see main.c)
|
2012-06-15 01:01:34 +02:00
|
|
|
*/
|
2012-06-21 01:56:24 +02:00
|
|
|
void _press_release(bool pressed, uint8_t keycode) {
|
2012-04-25 08:49:17 +02:00
|
|
|
// no-op
|
2012-06-15 01:01:34 +02:00
|
|
|
if (keycode == 0)
|
2012-04-25 08:49:17 +02:00
|
|
|
return;
|
|
|
|
|
2012-04-25 08:22:20 +02:00
|
|
|
// modifier keys
|
2012-06-15 01:01:34 +02:00
|
|
|
switch (keycode) {
|
|
|
|
case KEY_LeftControl: (pressed)
|
|
|
|
? (keyboard_modifier_keys |= (1<<0))
|
|
|
|
: (keyboard_modifier_keys &= ~(1<<0));
|
2012-04-25 08:22:20 +02:00
|
|
|
return;
|
2012-06-15 01:01:34 +02:00
|
|
|
case KEY_LeftShift: (pressed)
|
|
|
|
? (keyboard_modifier_keys |= (1<<1))
|
|
|
|
: (keyboard_modifier_keys &= ~(1<<1));
|
2012-04-25 08:22:20 +02:00
|
|
|
return;
|
2012-06-15 01:01:34 +02:00
|
|
|
case KEY_LeftAlt: (pressed)
|
|
|
|
? (keyboard_modifier_keys |= (1<<2))
|
|
|
|
: (keyboard_modifier_keys &= ~(1<<2));
|
2012-04-25 08:22:20 +02:00
|
|
|
return;
|
2012-06-15 01:01:34 +02:00
|
|
|
case KEY_LeftGUI: (pressed)
|
|
|
|
? (keyboard_modifier_keys |= (1<<3))
|
|
|
|
: (keyboard_modifier_keys &= ~(1<<3));
|
2012-04-25 08:22:20 +02:00
|
|
|
return;
|
2012-06-15 01:01:34 +02:00
|
|
|
case KEY_RightControl: (pressed)
|
|
|
|
? (keyboard_modifier_keys |= (1<<4))
|
|
|
|
: (keyboard_modifier_keys &= ~(1<<4));
|
2012-04-25 08:22:20 +02:00
|
|
|
return;
|
2012-06-15 01:01:34 +02:00
|
|
|
case KEY_RightShift: (pressed)
|
|
|
|
? (keyboard_modifier_keys |= (1<<5))
|
|
|
|
: (keyboard_modifier_keys &= ~(1<<5));
|
2012-04-25 08:22:20 +02:00
|
|
|
return;
|
2012-06-15 01:01:34 +02:00
|
|
|
case KEY_RightAlt: (pressed)
|
|
|
|
? (keyboard_modifier_keys |= (1<<6))
|
|
|
|
: (keyboard_modifier_keys &= ~(1<<6));
|
2012-04-25 08:22:20 +02:00
|
|
|
return;
|
2012-06-15 01:01:34 +02:00
|
|
|
case KEY_RightGUI: (pressed)
|
|
|
|
? (keyboard_modifier_keys |= (1<<7))
|
|
|
|
: (keyboard_modifier_keys &= ~(1<<7));
|
2012-04-25 08:22:20 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// all others
|
2012-06-15 01:01:34 +02:00
|
|
|
for (uint8_t i=0; i<6; i++) {
|
|
|
|
if (pressed) {
|
|
|
|
if (keyboard_keys[i] == 0) {
|
|
|
|
keyboard_keys[i] = keycode;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (keyboard_keys[i] == keycode) {
|
|
|
|
keyboard_keys[i] = 0;
|
|
|
|
return;
|
|
|
|
}
|
2012-04-11 03:58:26 +02:00
|
|
|
}
|
2012-06-15 01:01:34 +02:00
|
|
|
}
|
2012-04-10 10:44:27 +02:00
|
|
|
}
|
|
|
|
|
2012-06-15 07:02:57 +02:00
|
|
|
/*
|
|
|
|
* Set current layer
|
|
|
|
* - Sets any keys currently set to the overall current layer to the new layer,
|
|
|
|
* and then sets the overall current layer
|
|
|
|
*
|
|
|
|
* Arguments
|
2012-07-06 00:48:18 +02:00
|
|
|
* - layer: the new layer value
|
2012-06-15 07:02:57 +02:00
|
|
|
* - current_layer: (a pointer to) the overall current layer (see main.c)
|
2012-06-15 23:36:50 +02:00
|
|
|
* - current_layers: (a pointer to a matrix of) the current layer for each key
|
2012-06-15 07:02:57 +02:00
|
|
|
* (see main.c and lib/key-functions.h)
|
|
|
|
*
|
|
|
|
* Note
|
|
|
|
* - Leaving all non-current layer values alone allows changing layers while
|
|
|
|
* maintaining a possibly enabled layer mask (as might be used to implement
|
|
|
|
* firmware enabled numlock)
|
|
|
|
*/
|
|
|
|
void _layer_set_current(
|
2012-07-06 00:48:18 +02:00
|
|
|
uint8_t layer,
|
2012-06-15 07:02:57 +02:00
|
|
|
uint8_t * current_layer,
|
2012-06-15 23:36:50 +02:00
|
|
|
uint8_t (*current_layers)[KB_ROWS][KB_COLUMNS] ) {
|
2012-06-15 07:02:57 +02:00
|
|
|
|
|
|
|
// don't switch to out-of-bounds layers
|
2012-07-06 00:48:18 +02:00
|
|
|
if ( layer < 0 || layer >= KB_LAYERS )
|
2012-06-15 07:02:57 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
for (uint8_t row=0; row<KB_ROWS; row++)
|
|
|
|
for (uint8_t col=0; col<KB_COLUMNS; col++)
|
2012-07-06 00:48:18 +02:00
|
|
|
// if a key is set to a non-current layer, leave it
|
2012-06-15 23:36:50 +02:00
|
|
|
if ((*current_layers)[row][col] == *current_layer)
|
2012-07-06 00:48:18 +02:00
|
|
|
(*current_layers)[row][col] = layer;
|
2012-06-15 07:02:57 +02:00
|
|
|
|
2012-07-06 00:48:18 +02:00
|
|
|
(*current_layer) = layer;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set layer mask
|
|
|
|
* - Sets the specified key positions to the specified layer
|
|
|
|
*/
|
|
|
|
void _layer_set_mask(
|
|
|
|
uint8_t layer,
|
|
|
|
bool positions[KB_ROWS][KB_COLUMNS],
|
|
|
|
uint8_t (*current_layers)[KB_ROWS][KB_COLUMNS] ) {
|
|
|
|
|
|
|
|
// don't switch to out-of-bounds layers
|
|
|
|
if ( layer < 0 || layer >= KB_LAYERS )
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (uint8_t row=0; row<KB_ROWS; row++)
|
|
|
|
for (uint8_t col=0; col<KB_COLUMNS; col++)
|
|
|
|
if (positions[row][col])
|
|
|
|
(*current_layers)[row][col] = layer;
|
2012-06-15 07:02:57 +02:00
|
|
|
}
|
|
|
|
|
2012-06-15 23:36:50 +02:00
|
|
|
/*
|
|
|
|
* Is the given keycode pressed?
|
|
|
|
*/
|
|
|
|
bool _is_pressed(uint8_t keycode) {
|
|
|
|
// modifier keys
|
|
|
|
switch (keycode) {
|
|
|
|
case KEY_LeftControl: if (keyboard_modifier_keys & (1<<0))
|
|
|
|
return true;
|
|
|
|
case KEY_LeftShift: if (keyboard_modifier_keys & (1<<1))
|
|
|
|
return true;
|
|
|
|
case KEY_LeftAlt: if (keyboard_modifier_keys & (1<<2))
|
|
|
|
return true;
|
|
|
|
case KEY_LeftGUI: if (keyboard_modifier_keys & (1<<3))
|
|
|
|
return true;
|
|
|
|
case KEY_RightControl: if (keyboard_modifier_keys & (1<<4))
|
|
|
|
return true;
|
|
|
|
case KEY_RightShift: if (keyboard_modifier_keys & (1<<5))
|
|
|
|
return true;
|
|
|
|
case KEY_RightAlt: if (keyboard_modifier_keys & (1<<6))
|
|
|
|
return true;
|
|
|
|
case KEY_RightGUI: if (keyboard_modifier_keys & (1<<7))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// all others
|
|
|
|
for (uint8_t i=0; i<6; i++)
|
|
|
|
if (keyboard_keys[i] == keycode)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-06-15 07:02:57 +02:00
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// public functions
|
2012-06-15 01:01:34 +02:00
|
|
|
// ----------------------------------------------------------------------------
|
2012-04-25 08:49:17 +02:00
|
|
|
|
2012-06-15 01:01:34 +02:00
|
|
|
/*
|
2012-06-21 01:56:24 +02:00
|
|
|
* Press|Release
|
|
|
|
* - Generate a normal keypress or keyrelease
|
2012-06-15 01:01:34 +02:00
|
|
|
*/
|
2012-06-21 01:56:24 +02:00
|
|
|
void kbfun_press_release( KBFUN_FUNCTION_ARGS ) {
|
|
|
|
_press_release(pressed_, keycode_);
|
2012-06-15 01:01:34 +02:00
|
|
|
}
|
2012-04-25 08:22:20 +02:00
|
|
|
|
2012-06-15 01:01:34 +02:00
|
|
|
/*
|
2012-06-21 01:56:24 +02:00
|
|
|
* Toggle
|
2012-07-06 00:48:18 +02:00
|
|
|
* - Toggle the key pressed or unpressed
|
2012-06-15 01:01:34 +02:00
|
|
|
*/
|
2012-06-21 01:56:24 +02:00
|
|
|
void kbfun_toggle( KBFUN_FUNCTION_ARGS ) {
|
|
|
|
if (_is_pressed(keycode_))
|
|
|
|
_press_release(false, keycode_);
|
|
|
|
else
|
|
|
|
_press_release(true, keycode_);
|
2012-04-10 10:44:27 +02:00
|
|
|
}
|
|
|
|
|
2012-06-15 01:01:34 +02:00
|
|
|
/*
|
2012-06-15 23:36:50 +02:00
|
|
|
* Increase layer
|
2012-06-21 01:56:24 +02:00
|
|
|
* - Increment the current layer by the value specified in the keymap (for all
|
|
|
|
* non-masked keys)
|
2012-06-15 01:01:34 +02:00
|
|
|
*/
|
bugfix (mostly): changed the way layers are handled
before, if you pressed a key, then shifted layers, then released it, the
first layer's press() would be called, and the 2nd layer's release()
would be called, causing keys to stick, and probably other errors. now,
the layer that the key was on when it was pressed is kept track of, and
the proper release() is called.
also, layers can be shifted per key now, instead of just for the whole
board at once
i also changed how keyboard-private includes are handled. "private"
stuff is now in its own file, instead of being nested in an extra
`#ifdef`.
and i think that's it. i'm pretty tired right now, so there may be
errors, but it seemed to work all right with cursory tests.
2012-06-11 12:27:34 +02:00
|
|
|
void kbfun_layer_inc( KBFUN_FUNCTION_ARGS ) {
|
2012-06-15 07:02:57 +02:00
|
|
|
_layer_set_current(
|
2012-06-15 23:36:50 +02:00
|
|
|
(*current_layer_) + keycode_,
|
2012-06-15 07:02:57 +02:00
|
|
|
current_layer_,
|
|
|
|
current_layers_ );
|
2012-06-04 08:46:21 +02:00
|
|
|
}
|
|
|
|
|
2012-06-15 01:01:34 +02:00
|
|
|
/*
|
2012-06-15 23:36:50 +02:00
|
|
|
* Decrease layer
|
2012-06-21 01:56:24 +02:00
|
|
|
* - Decrement the current layer by the value specified in the keymap (for all
|
|
|
|
* non-masked keys)
|
2012-06-15 01:01:34 +02:00
|
|
|
*/
|
bugfix (mostly): changed the way layers are handled
before, if you pressed a key, then shifted layers, then released it, the
first layer's press() would be called, and the 2nd layer's release()
would be called, causing keys to stick, and probably other errors. now,
the layer that the key was on when it was pressed is kept track of, and
the proper release() is called.
also, layers can be shifted per key now, instead of just for the whole
board at once
i also changed how keyboard-private includes are handled. "private"
stuff is now in its own file, instead of being nested in an extra
`#ifdef`.
and i think that's it. i'm pretty tired right now, so there may be
errors, but it seemed to work all right with cursory tests.
2012-06-11 12:27:34 +02:00
|
|
|
void kbfun_layer_dec( KBFUN_FUNCTION_ARGS ) {
|
2012-06-15 07:02:57 +02:00
|
|
|
_layer_set_current(
|
2012-06-15 23:36:50 +02:00
|
|
|
(*current_layer_) - keycode_,
|
2012-06-15 07:02:57 +02:00
|
|
|
current_layer_,
|
|
|
|
current_layers_ );
|
2012-06-04 08:46:21 +02:00
|
|
|
}
|
|
|
|
|
2012-06-22 05:42:56 +02:00
|
|
|
/*
|
|
|
|
* Increase layer, Execute key
|
|
|
|
* - Increment the current layer by the value specified in the keymap (for all
|
|
|
|
* non-masked keys), and execute (usually press|release) the key in the same
|
|
|
|
* position on that new layer
|
|
|
|
*
|
|
|
|
* Note
|
|
|
|
* - Meant to be paired with `kbfun_layer_dec_exec()`
|
|
|
|
*/
|
|
|
|
void kbfun_layer_inc_exec( KBFUN_FUNCTION_ARGS ) {
|
|
|
|
// switch layers
|
|
|
|
_layer_set_current(
|
|
|
|
(*current_layer_) + keycode_,
|
|
|
|
current_layer_,
|
|
|
|
current_layers_ );
|
|
|
|
|
|
|
|
// exececute second key (in the same position)
|
|
|
|
// - `layer_+keycode_` will be constant (under normal circumstances)
|
|
|
|
// between the press and release
|
|
|
|
_kbfun_exec_key(
|
|
|
|
pressed_, 0, layer_+keycode_,
|
|
|
|
row_, col_, current_layer_,
|
|
|
|
current_layers_, pressed_layers_ );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Decrease layer, Execute key
|
|
|
|
* - Decrement the current layer by the value specified in the keymap (for all
|
|
|
|
* non-masked keys), and execute (usually press|release) the key in the same
|
|
|
|
* position on that new layer
|
|
|
|
*
|
|
|
|
* Note
|
|
|
|
* - Meant to be paired with `kbfun_layer_inc_exec()`
|
|
|
|
*/
|
|
|
|
void kbfun_layer_dec_exec( KBFUN_FUNCTION_ARGS ) {
|
|
|
|
// switch layers
|
|
|
|
_layer_set_current(
|
|
|
|
(*current_layer_) - keycode_,
|
|
|
|
current_layer_,
|
|
|
|
current_layers_ );
|
|
|
|
|
|
|
|
// exececute second key (in the same position)
|
|
|
|
// - `layer_+keycode_` will be constant (under normal circumstances)
|
|
|
|
// between the press and release
|
|
|
|
_kbfun_exec_key(
|
|
|
|
pressed_, 0, layer_+keycode_,
|
|
|
|
row_, col_, current_layer_,
|
|
|
|
current_layers_, pressed_layers_ );
|
|
|
|
}
|
|
|
|
|
2012-06-15 01:01:34 +02:00
|
|
|
/*
|
2012-06-15 23:36:50 +02:00
|
|
|
* Two keys => capslock
|
|
|
|
* - 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
|
2012-06-21 01:56:24 +02:00
|
|
|
* the keys will make the second key toggle capslock
|
2012-06-15 23:36:50 +02:00
|
|
|
*
|
|
|
|
* 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
|
2012-06-15 01:01:34 +02:00
|
|
|
*/
|
|
|
|
void kbfun_2_keys_capslock_press_release( KBFUN_FUNCTION_ARGS ) {
|
2012-06-15 23:36:50 +02:00
|
|
|
static uint8_t keys_pressed;
|
|
|
|
static bool lshift_pressed;
|
|
|
|
static bool rshift_pressed;
|
2012-06-15 01:01:34 +02:00
|
|
|
|
|
|
|
if (!pressed_) keys_pressed--;
|
|
|
|
|
2012-06-15 23:36:50 +02:00
|
|
|
// take care of the key that was actually pressed
|
2012-06-21 01:56:24 +02:00
|
|
|
_press_release(pressed_, keycode_);
|
2012-06-15 23:36:50 +02:00
|
|
|
|
|
|
|
// take care of capslock (only on the press of the 2nd key)
|
|
|
|
if (keys_pressed == 1 && pressed_) {
|
|
|
|
// save the state of left and right shift
|
|
|
|
lshift_pressed = _is_pressed(KEY_LeftShift);
|
|
|
|
rshift_pressed = _is_pressed(KEY_RightShift);
|
|
|
|
// disable both
|
2012-06-21 01:56:24 +02:00
|
|
|
_press_release(false, KEY_LeftShift);
|
|
|
|
_press_release(false, KEY_RightShift);
|
2012-06-15 23:36:50 +02:00
|
|
|
|
|
|
|
// press capslock, then release it
|
2012-06-21 01:56:24 +02:00
|
|
|
_press_release(true, KEY_CapsLock);
|
2012-06-15 23:36:50 +02:00
|
|
|
usb_keyboard_send();
|
2012-06-21 01:56:24 +02:00
|
|
|
_press_release(false, KEY_CapsLock);
|
2012-06-15 23:36:50 +02:00
|
|
|
usb_keyboard_send();
|
|
|
|
|
|
|
|
// restore the state of left and right shift
|
|
|
|
if (lshift_pressed)
|
2012-06-21 01:56:24 +02:00
|
|
|
_press_release(true, KEY_LeftShift);
|
2012-06-15 23:36:50 +02:00
|
|
|
if (rshift_pressed)
|
2012-06-21 01:56:24 +02:00
|
|
|
_press_release(true, KEY_RightShift);
|
2012-06-15 23:36:50 +02:00
|
|
|
}
|
2012-06-15 01:01:34 +02:00
|
|
|
|
|
|
|
if (pressed_) keys_pressed++;
|
|
|
|
}
|
|
|
|
|
2012-07-09 02:54:23 +02:00
|
|
|
|
|
|
|
// TODO: maybe the numpad functions (and other logical sets of functions?) need
|
|
|
|
// to be in (a) seaparate file(s).
|
|
|
|
/* ----------------------------------------------------------------------------
|
|
|
|
* Numpad functions
|
|
|
|
* - Functions to implement an embedded numpad
|
2012-07-06 00:48:18 +02:00
|
|
|
*
|
2012-07-09 02:54:23 +02:00
|
|
|
* Notes
|
|
|
|
* - The numpad is toggled by shifting (without changing the overall current
|
|
|
|
* layer) the layer of the keys specified in this function to the value
|
|
|
|
* specified in the keymap
|
|
|
|
* - When the numpad is toggled, the numlock is set to on (for active) or off
|
|
|
|
* (for inactive) as well
|
|
|
|
* - All these functions cooperate, but if more than one layer mask of this
|
|
|
|
* type is used (by a different set of functions) at the same time, the
|
2012-07-06 00:48:18 +02:00
|
|
|
* second will override the first, and any keys covered by both will be reset
|
2012-07-09 02:54:23 +02:00
|
|
|
* to the overall current layer when either is released (even if the other is
|
|
|
|
* still pressed)
|
|
|
|
* ------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
// prefix function (undefined later)
|
|
|
|
// - to keep these names reasonable in this block, and obviously not global
|
|
|
|
// outside it
|
|
|
|
// - 'L' is for 'local'
|
|
|
|
#define L(name) _kbfun_layermask_numpad__##name
|
|
|
|
|
|
|
|
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
|
|
|
|
|
|
// vars
|
|
|
|
static bool L(numpad_activated) = false;
|
|
|
|
static bool L(layer_mask)[KB_ROWS][KB_COLUMNS] =
|
|
|
|
MATRIX_LAYER(
|
|
|
|
// unused
|
|
|
|
0,
|
|
|
|
|
|
|
|
// left hand
|
|
|
|
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,
|
|
|
|
0, 0,
|
|
|
|
0, 0, 0,
|
|
|
|
|
|
|
|
// right hand
|
|
|
|
0, 0, 1, 1, 1, 1, 0,
|
|
|
|
0, 0, 1, 1, 1, 1, 0,
|
|
|
|
0, 1, 1, 1, 1, 0,
|
|
|
|
0, 0, 1, 1, 1, 1, 0,
|
|
|
|
0, 0, 0, 0, 0,
|
|
|
|
0,
|
|
|
|
0, 0,
|
|
|
|
0, 0, 0 );
|
|
|
|
|
|
|
|
// functions
|
|
|
|
static inline void L(toggle_numlock)(void) {
|
|
|
|
_press_release(true, KEYPAD_NumLock_Clear);
|
|
|
|
usb_keyboard_send();
|
|
|
|
_press_release(false, KEYPAD_NumLock_Clear);
|
|
|
|
usb_keyboard_send();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void L(toggle_numpad)(
|
|
|
|
uint8_t numpad_layer,
|
|
|
|
uint8_t current_layer,
|
|
|
|
uint8_t (*current_layers)[KB_ROWS][KB_COLUMNS] ) {
|
|
|
|
|
|
|
|
if (L(numpad_activated)) {
|
|
|
|
// deactivate numpad
|
|
|
|
_layer_set_mask(current_layer, L(layer_mask), current_layers);
|
|
|
|
L(numpad_activated) = false;
|
|
|
|
|
|
|
|
// if: numlock on
|
|
|
|
if (keyboard_leds & (1<<0))
|
|
|
|
L(toggle_numlock)();
|
|
|
|
} else {
|
|
|
|
// activate numpad
|
|
|
|
_layer_set_mask(numpad_layer, L(layer_mask), current_layers);
|
|
|
|
L(numpad_activated) = true;
|
|
|
|
|
|
|
|
// if: numlock off
|
|
|
|
if (!(keyboard_leds & (1<<0)))
|
|
|
|
L(toggle_numlock)();
|
2012-07-06 00:48:18 +02:00
|
|
|
}
|
2012-07-09 02:54:23 +02:00
|
|
|
}
|
2012-07-06 00:48:18 +02:00
|
|
|
|
2012-07-09 02:54:23 +02:00
|
|
|
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Numpad toggle
|
|
|
|
* - Toggles the numpad and sets numlock on (for active) or off (for inactive)
|
|
|
|
* with it, if it's not already in that state
|
|
|
|
*/
|
|
|
|
void kbfun_layermask_numpad_toggle( KBFUN_FUNCTION_ARGS ) {
|
|
|
|
L(toggle_numpad)(keycode_, *current_layer_, current_layers_);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Numpad on
|
|
|
|
* - Set the numpad on (along with numlock, if it's not already)
|
|
|
|
*/
|
|
|
|
void kbfun_layermask_numpad_on( KBFUN_FUNCTION_ARGS ) {
|
|
|
|
if (!L(numpad_activated))
|
|
|
|
L(toggle_numpad)(keycode_, *current_layer_, current_layers_);
|
2012-07-06 00:48:18 +02:00
|
|
|
}
|
|
|
|
|
2012-07-09 02:54:23 +02:00
|
|
|
/*
|
|
|
|
* Numpad off
|
|
|
|
* - Set the numpad off (along with numlock, if it's not already)
|
|
|
|
*/
|
|
|
|
void kbfun_layermask_numpad_off( KBFUN_FUNCTION_ARGS ) {
|
|
|
|
if (L(numpad_activated))
|
|
|
|
L(toggle_numpad)(keycode_, *current_layer_, current_layers_);
|
|
|
|
}
|
|
|
|
|
|
|
|
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
|
|
|
|
|
|
// prefix function (undefined here)
|
|
|
|
#undef L
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------------
|
|
|
|
* ------------------------------------------------------------------------- */
|
|
|
|
|
2012-07-06 02:10:18 +02:00
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// public functions (device specific)
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
void kbfun_jump_to_bootloader( KBFUN_FUNCTION_ARGS ) {
|
|
|
|
|
|
|
|
// from PJRC (slightly modified)
|
|
|
|
// <http://www.pjrc.com/teensy/jump_to_bootloader.html>
|
|
|
|
#if MAKEFILE_BOARD == teensy-2-0
|
|
|
|
// --- for all Teensy boards
|
|
|
|
cli();
|
|
|
|
|
|
|
|
// disable watchdog, if enabled
|
|
|
|
// disable all peripherals
|
|
|
|
UDCON = 1;
|
|
|
|
USBCON = (1<<FRZCLK); // disable USB
|
|
|
|
UCSR1B = 0;
|
|
|
|
_delay_ms(5);
|
|
|
|
|
|
|
|
// --- Teensy 2.0 specific
|
|
|
|
EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
|
|
|
|
TIMSK0 = 0; TIMSK1 = 0; TIMSK3 = 0; TIMSK4 = 0; UCSR1B = 0; TWCR = 0;
|
|
|
|
DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; TWCR = 0;
|
|
|
|
PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
|
|
|
|
asm volatile("jmp 0x7E00");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// else, function does nothing
|
|
|
|
}
|
|
|
|
|