bug fixes, mostly; and other things

- addition to references.md

- keymap modification
  - now using 2 shifts => capslock
  - the previous capslock key -> tab
  - the previous tab key -> left bracket

- bug and omission fixes; notably:
  - _is_pressed() no longer changes the value of
    `keyboard_modifier_keys`, lol
  - kbfun_2_keys_capslock_press_release() now works.  (capslock doesn't
    register if left or right shift is pressed, so the shift state has
    to be stored, cleared, capslock pressed, and shift state restored)
  - main() no longer locally overwrites the value of `current_layer`
    before sending it to the kbfun.  (i didn't realize i was using the
    same variable name for two different things)

- improvements
  - kbfun_layer_inc() and ...dec() are now variable
partial-rewrite
Ben Blazak 2012-06-15 14:36:50 -07:00
parent d1f17133c9
commit 068a3546f6
6 changed files with 128 additions and 47 deletions

View File

@ -377,6 +377,17 @@
## Miscellaneous
### Keyboard Testing Tools
* [Understanding Rollover]
(http://gadzikowski.com/nkeyrollover.html)
Includes 3 different tests (2 of which are web based) to see which keys are
actually registering as pressed.
* mentioned on the [Default:NKey Rollover]
(http://geekhack.org/showwiki.php?title=NKey+Rollover+-+Overview+Testing+Methodology+and+Results)
page (on <http://geekhack.org/>)
### Typical Keyboard Information
* [Keyboard Scan Rates]

View File

@ -19,11 +19,14 @@
#include "../layout.h"
#include "../../../lib/key-functions.h"
// aliases
#define f_press &kbfun_press
#define f_relea &kbfun_release
#define f_l_set &kbfun_layer_set
#define f_l_inc &kbfun_layer_inc
#define f_l_dec &kbfun_layer_dec
#define f_2kcap &kbfun_2_keys_capslock_press_release
uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
@ -33,9 +36,9 @@ uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
0,
// left hand
_grave, _1, _2, _3, _4, _5, _equal,
_tab, _Q, _W, _E, _R, _T, _esc,
_capsLock, _A, _S, _D, _F, _G,
_shiftL, _Z, _X, _C, _V, _B, 0,
_bracketL, _Q, _W, _E, _R, _T, _esc,
_tab, _A, _S, _D, _F, _G,
_shiftL, _Z, _X, _C, _V, _B, 1,
_guiL, _arrowL, _arrowU, _arrowD, _arrowR,
_bs,
_del, _ctrlL,
@ -44,7 +47,7 @@ _guiL, _arrowL, _arrowU, _arrowD, _arrowR,
_backslash, _6, _7, _8, _9, _0, _dash,
_bracketL, _Y, _U, _I, _O, _P, _bracketR,
_H, _J, _K, _L, _semicolon, _quote,
0, _N, _M, _comma, _period, _slash, _shiftR,
1, _N, _M, _comma, _period, _slash, _shiftR,
_arrowL, _arrowD, _arrowU, _arrowR, _guiR,
_space,
_ctrlR, _enter,
@ -84,7 +87,7 @@ NULL,
f_press,f_press,f_press,f_press,f_press,f_press,f_press,
f_press,f_press,f_press,f_press,f_press,f_press,f_press,
f_press,f_press,f_press,f_press,f_press,f_press,
f_press,f_press,f_press,f_press,f_press,f_press,f_l_inc,
f_2kcap,f_press,f_press,f_press,f_press,f_press,f_l_inc,
f_press,f_press,f_press,f_press,f_press,
f_press,
f_press, f_press,
@ -93,7 +96,7 @@ f_press,f_press,f_press,f_press,f_press,
f_press,f_press,f_press,f_press,f_press,f_press,f_press,
f_press,f_press,f_press,f_press,f_press,f_press,f_press,
f_press,f_press,f_press,f_press,f_press,f_press,
f_l_inc,f_press,f_press,f_press,f_press,f_press,f_press,
f_l_inc,f_press,f_press,f_press,f_press,f_press,f_2kcap,
f_press,f_press,f_press,f_press,f_press,
f_press,
f_press, f_press,
@ -133,7 +136,7 @@ NULL,
f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,
f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,
f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,
f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_l_dec,
f_2kcap,f_relea,f_relea,f_relea,f_relea,f_relea,f_l_dec,
f_relea,f_relea,f_relea,f_relea,f_relea,
f_relea,
f_relea, f_relea,
@ -142,7 +145,7 @@ f_relea,f_relea,f_relea,f_relea,f_relea,
f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,
f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,
f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,
f_l_dec,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,
f_l_dec,f_relea,f_relea,f_relea,f_relea,f_relea,f_2kcap,
f_relea,f_relea,f_relea,f_relea,f_relea,
f_relea,
f_relea, f_relea,

View File

@ -17,7 +17,8 @@
void _layer_set_current(
uint8_t value,
uint8_t * current_layer,
uint8_t * current_layers_[KB_ROWS][KB_COLUMNS] );
uint8_t (*current_layers_)[KB_ROWS][KB_COLUMNS] );
bool _is_pressed(uint8_t keycode);
#endif

View File

@ -101,7 +101,7 @@ void _press_release(uint8_t keycode, bool pressed) {
* Arguments
* - value: the new layer value
* - current_layer: (a pointer to) the overall current layer (see main.c)
* - current_layers_: (a pointer to a matrix of) the current layer for each key
* - current_layers: (a pointer to a matrix of) the current layer for each key
* (see main.c and lib/key-functions.h)
*
* Note
@ -112,87 +112,151 @@ void _press_release(uint8_t keycode, bool pressed) {
void _layer_set_current(
uint8_t value,
uint8_t * current_layer,
uint8_t * current_layers_[KB_ROWS][KB_COLUMNS] ) {
uint8_t (*current_layers)[KB_ROWS][KB_COLUMNS] ) {
// don't switch to out-of-bounds layers
if (!( (0 <= *current_layer) && (*current_layer < KB_LAYERS) ))
if ( value < 0 || value >= KB_LAYERS )
return;
for (uint8_t row=0; row<KB_ROWS; row++)
for (uint8_t col=0; col<KB_COLUMNS; col++)
// only change layers that are currently current. if a
// key is set to a non-current layer, leave it alone
if ((*current_layers_)[row][col] == *current_layer)
(*current_layers_)[row][col] = value;
// if a key is set to a non-current layer, let it be
if ((*current_layers)[row][col] == *current_layer)
(*current_layers)[row][col] = value;
(*current_layer) = value;
}
/*
* 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;
}
// ----------------------------------------------------------------------------
// public functions
// ----------------------------------------------------------------------------
/*
* - press
* - generate a normal keypress
* Press
* - Generate a normal keypress
*/
void kbfun_press( KBFUN_FUNCTION_ARGS ) {
_press_release(keycode_, true);
}
/*
* - release
* - generate a normal keyrelease
* Release
* - Generate a normal keyrelease
*/
void kbfun_release( KBFUN_FUNCTION_ARGS ) {
_press_release(keycode_, false);
}
/*
* - set layer
* - set layer to the value specified in the keymap (as a number instead of a
* keycode)
* Set layer
* - Set layer to the value specified in the keymap (using the value as a
* number instead of a keycode)
*/
void kbfun_layer_set( KBFUN_FUNCTION_ARGS ) {
_layer_set_current( keycode_, current_layer_, current_layers_ );
}
/*
* - next layer
* - layer increment (for all non-masked keys)
* Increase layer
* - Increment layer by the value specified in the keymap (for all non-masked
* keys)
*/
void kbfun_layer_inc( KBFUN_FUNCTION_ARGS ) {
_layer_set_current(
(*current_layer_)+1,
(*current_layer_) + keycode_,
current_layer_,
current_layers_ );
}
/*
* - previous layer
* - layer decrement (for all keys)
* Decrease layer
* - Decrement layer by the value specified in the keymap (for all non-masked
* keys)
*/
void kbfun_layer_dec( KBFUN_FUNCTION_ARGS ) {
_layer_set_current(
(*current_layer_)-1,
(*current_layer_) - keycode_,
current_layer_,
current_layers_ );
}
/*
* - two keys => capslock
* - when assigned to two keys (e.g. the physical left and right shift keys),
* pressing and holding down one of them makes the second toggle capslock
* 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
* the keys will make the second 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
*/
#include "../lib/usb/usage-page/keyboard.h"
void kbfun_2_keys_capslock_press_release( KBFUN_FUNCTION_ARGS ) {
static uint8_t keys_pressed = 0;
static uint8_t keys_pressed;
static bool lshift_pressed;
static bool rshift_pressed;
if (!pressed_) keys_pressed--;
// take care of the key that was actually pressed
_press_release(keycode_, pressed_);
if (keys_pressed == 1)
_press_release(KEY_CapsLock, pressed_);
// 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
_press_release(KEY_LeftShift, false);
_press_release(KEY_RightShift, false);
// press capslock, then release it
_press_release(KEY_CapsLock, true);
usb_keyboard_send();
_press_release(KEY_CapsLock, false);
usb_keyboard_send();
// restore the state of left and right shift
if (lshift_pressed)
_press_release(KEY_LeftShift, true);
if (rshift_pressed)
_press_release(KEY_RightShift, true);
}
if (pressed_) keys_pressed++;
}

View File

@ -45,10 +45,12 @@
typedef void (*kbfun_funptr_t)( KBFUN_FUNCTION_ARGS );
void kbfun_press ( KBFUN_FUNCTION_ARGS );
void kbfun_release ( KBFUN_FUNCTION_ARGS );
void kbfun_layer_inc ( KBFUN_FUNCTION_ARGS );
void kbfun_layer_dec ( KBFUN_FUNCTION_ARGS );
void kbfun_press ( KBFUN_FUNCTION_ARGS );
void kbfun_release ( KBFUN_FUNCTION_ARGS );
void kbfun_layer_set ( KBFUN_FUNCTION_ARGS );
void kbfun_layer_inc ( KBFUN_FUNCTION_ARGS );
void kbfun_layer_dec ( KBFUN_FUNCTION_ARGS );
void kbfun_2_keys_capslock_press_release ( KBFUN_FUNCTION_ARGS );
#endif

View File

@ -28,7 +28,7 @@ int main(void) {
for (;;) {
// the overall current layer
static uint8_t current layer;
static uint8_t current_layer;
// the current layer for each key
static uint8_t current_layers[KB_ROWS][KB_COLUMNS];
// the layer each key was on when it was last pressed
@ -59,25 +59,25 @@ int main(void) {
if (is_pressed != was_pressed) {
if (is_pressed) {
uint8_t current_layer = current_layers[row][col];
pressed_layers[row][col] = current_layer;
uint8_t layer = current_layers[row][col];
pressed_layers[row][col] = layer;
kbfun_funptr_t press_function =
kb_layout_press_get(current_layer, row, col);
kb_layout_press_get(layer, row, col);
if (press_function) {
(*press_function)(
kb_layout_get(current_layer, row, col),
kb_layout_get(layer, row, col),
true, &current_layer,
&current_layers, &pressed_layers,
&row, &col );
}
} else {
uint8_t pressed_layer = pressed_layers[row][col];
uint8_t layer = pressed_layers[row][col];
kbfun_funptr_t release_function =
kb_layout_release_get(pressed_layer, row, col);
kb_layout_release_get(layer, row, col);
if (release_function) {
(*release_function)(
kb_layout_get(pressed_layer, row, col),
kb_layout_get(layer, row, col),
false, &current_layer,
&current_layers, &pressed_layers,
&row, &col );