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.
partial-rewrite
Ben Blazak 2012-06-11 03:27:34 -07:00
parent 5569cecd2b
commit 3322844ed0
15 changed files with 237 additions and 214 deletions

View File

@ -9,10 +9,9 @@
#include "lib/data-types.h"
#define KEYBOARD_INCLUDE_PRIVATE
#include "ergodox/matrix.h"
#include "ergodox/mcp23018.h"
#include "ergodox/teensy-2-0.h"
#include "ergodox/mcp23018--private.h"
#include "ergodox/teensy-2-0--private.h"
/* returns

View File

@ -16,7 +16,6 @@
#include "ergodox/layout.h" // number of layers, layout
#include "ergodox/led.h" // logical led controls
#include "ergodox/matrix.h" // kb dimensions, matrix status
#include "ergodox/mcp23018.h" // (nothing right now)
#include "ergodox/teensy-2-0.h" // LED controls

View File

@ -15,8 +15,7 @@
#include "lib/data-types.h"
#include "lib/key-functions.h" // for `kbfun_funptr_t`
#include "matrix.h" // for number of rows and columns, and layout
// to matrix macros
#include "matrix.h" // for number of rows and columns
// include the appropriate keyboard layout header
// for:

View File

@ -14,8 +14,8 @@
#include "lib/usb/usage-page/keyboard--short-names.h"
#include "lib/key-functions.h"
#define KEYBOARD_INCLUDE_PRIVATE
#include "../matrix.h"
#include "../matrix--private.h"
#include "../layout.h"
@ -26,12 +26,6 @@
#define f_l_dec &kbfun_layer_dec
// error check: everything below assumes these dimensions
#if KB_LAYERS != 2 || KB_ROWS != 12 || KB_COLUMNS != 7
#error "Expecting different keyboard dimensions"
#endif
uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
// ----------------------------------------------------------------------------
LAYER( // layer 0: default
@ -41,7 +35,7 @@ uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
_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/*inc*/,
_shiftL, _Z, _X, _C, _V, _B, 0,
_guiL, _arrowL, _arrowU, _arrowD, _arrowR,
_bs,
_del, _ctrlL,
@ -50,7 +44,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/*inc*/, _N, _M, _comma, _period, _slash, _shiftR,
0, _N, _M, _comma, _period, _slash, _shiftR,
_arrowL, _arrowD, _arrowU, _arrowR, _guiR,
_space,
_ctrlR, _enter,
@ -63,17 +57,17 @@ _altR, _pageU, _pageD ),
0, _F1, _F2, _F3, _F4, _F5, _F11,
0, _braceL_kp, _braceR_kp, _bracketL, _bracketR, 0, _esc,
0, _semicolon, _slash, _dash, 0, _colon_kp,
0, 0, 0, 0, 0, 0, 0/*dec*/,
0, 0, 0, 0, 0, 0, 0,
0, _arrowL, _arrowU, _arrowD, _arrowR,
_bs,
_del, _ctrlL,
_end, _home, _altL,
// right hand
_F12, _F6, _F7, _F8, _F9, _F10, 0,
0, 0, _dash, _lt_kp, _gt_kp, _currencyUnit, 0,
_backslash, 0, _parenL_kp, _parenR_kp, _equal, 0,
0/*dec*/, _mul_kp, 0, 0, 0, 0, 0,
_arrowL, _arrowD, _arrowU, _arrowR, 0,
_F12, _F6, _F7, _F8, _F9, _F10, 0,
0, 0, _dash, _lt_kp, _gt_kp, _currencyUnit, 0,
_backslash, 0, _parenL_kp, _parenR_kp, _equal, 0,
0, _mul_kp, 0, 0, 0, 0, 0,
_arrowL, _arrowD, _arrowU, _arrowR, 0,
_space,
_ctrlR, _enter,
_altR, _pageU, _pageD )
@ -139,28 +133,6 @@ 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, NULL,
f_relea,f_relea,f_relea,f_relea,f_relea,
f_relea,
f_relea, f_relea,
f_relea,f_relea,f_relea,
// right hand
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,
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 ),
// ----------------------------------------------------------------------------
LAYER( // layer 1: function and symbol keys
// unused
NULL,
// left hand
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_relea,f_relea,f_relea,f_relea,f_relea,
f_relea,
@ -174,6 +146,28 @@ 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 ),
// ----------------------------------------------------------------------------
LAYER( // layer 1: function and symbol keys
// unused
NULL,
// left hand
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, NULL,
f_relea,f_relea,f_relea,f_relea,f_relea,
f_relea,
f_relea, f_relea,
f_relea,f_relea,f_relea,
// right hand
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,
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 )
// ----------------------------------------------------------------------------
};

View File

@ -0,0 +1,96 @@
/* ----------------------------------------------------------------------------
* ergoDOX: keyboard matrix specific exports : private
* ----------------------------------------------------------------------------
* 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>
* ------------------------------------------------------------------------- */
#ifndef MATRIX_h_PRIVATE
#define MATRIX_h_PRIVATE
/* mapping from spatial position to matrix position
* - spatial position: where the key is spatially, relative to other
* keys both on the keyboard and in the layout
* - matrix position: the coordinate in the matrix to which a key is
* scanned by the update functions
*
* - location numbers are in the format `row##column`, where both 'row'
* and 'column' are single digit hex numbers corresponding to the
* matrix position (which also corresponds to the row and column pin
* labels used in the teensy and mcp23018 files)
* - coordinates not listed are unused
*
* --- other info -----------------------------------------------------
* rows x columns = positions; assigned, unassigned
* per hand: 6 x 7 = 42; 38, 4
* total: 12 x 7 = 84; 76, 8
*
* left hand : cols 0..6, rows 6..B
* right hand : cols 0..6, rows 0..5
* --------------------------------------------------------------------
*/
#define LAYER( \
/* for unused positions */ \
na, \
\
/* left hand, spatial positions */ \
kB6,kB5,kB4,kB3,kB2,kB1,kB0, \
kA6,kA5,kA4,kA3,kA2,kA1,kA0, \
k96,k95,k94,k93,k92,k91, \
k86,k85,k84,k83,k82,k81,k80, \
k76,k75,k74,k73,k72, \
k64, \
k63, k60, \
k65,k62,k61, \
\
/* right hand, spatial positions */ \
k50,k51,k52,k53,k54,k55,k56, \
k40,k41,k42,k43,k44,k45,k46, \
k31,k32,k33,k34,k35,k36, \
k20,k21,k22,k23,k24,k25,k26, \
k12,k13,k14,k15,k16, \
k04, \
k00, k03, \
k01,k02,k05 ) \
\
/* matrix positions */ \
{ { k00,k01,k02,k03,k04,k05, na,}, \
{ na, na,k12,k13,k14,k15,k16,}, \
{ k20,k21,k22,k23,k24,k25,k26,}, \
{ na,k31,k32,k33,k34,k35,k36,}, \
{ k40,k41,k42,k43,k44,k45,k46,}, \
{ k50,k51,k52,k53,k54,k55,k56,}, \
{ k60,k61,k62,k63,k64,k65, na,}, \
{ na, na,k72,k73,k74,k75,k76,}, \
{ k80,k81,k82,k83,k84,k85,k86,}, \
{ na,k91,k92,k93,k94,k95,k96,}, \
{ kA0,kA1,kA2,kA3,kA4,kA5,kA6,}, \
{ kB0,kB1,kB2,kB3,kB4,kB5,kB6 } }
#define LAYER_SET_ALL(na, kxx) \
LAYER( \
na, \
\
kxx,kxx,kxx,kxx,kxx,kxx,kxx, \
kxx,kxx,kxx,kxx,kxx,kxx,kxx, \
kxx,kxx,kxx,kxx,kxx,kxx, \
kxx,kxx,kxx,kxx,kxx,kxx,kxx, \
kxx,kxx,kxx,kxx,kxx, \
kxx, \
kxx, kxx, \
kxx,kxx,kxx, \
\
kxx,kxx,kxx,kxx,kxx,kxx,kxx, \
kxx,kxx,kxx,kxx,kxx,kxx,kxx, \
kxx,kxx,kxx,kxx,kxx,kxx, \
kxx,kxx,kxx,kxx,kxx,kxx,kxx, \
kxx,kxx,kxx,kxx,kxx, \
kxx, \
kxx, kxx, \
kxx,kxx,kxx )
#endif

View File

@ -10,6 +10,7 @@
#include "lib/data-types.h"
#include "matrix.h"
#include "matrix--private.h"
static bool _kb_is_pressed[KB_ROWS][KB_COLUMNS];

View File

@ -18,93 +18,5 @@
extern bool (*kb_is_pressed)[KB_ROWS][KB_COLUMNS];
extern bool (*kb_was_pressed)[KB_ROWS][KB_COLUMNS];
#ifdef KEYBOARD_INCLUDE_PRIVATE
/* mapping from spatial position to matrix position
* - spatial position: where the key is spatially, relative to
* other keys both on the keyboard and in the layout
* - matrix position: the coordinate in the matrix to which
* a key is scanned by the update functions
*
* - location numbers are in the format `row##column`, where
* both 'row' and 'column' are single digit hex numbers
* corresponding to the matrix position (which also
* corresponds to the row and column pin labels used in the
* teensy and mcp23018 files)
* - coordinates not listed are unused
*
* --- other info ---------------------------------------------
* rows x columns = positions; assigned, unassigned
* per hand: 6 x 7 = 42; 38, 4
* total: 12 x 7 = 84; 76, 8
*
* left hand : cols 0..6, rows 6..B
* right hand : cols 0..6, rows 0..5
* ------------------------------------------------------------
*/
#define LAYER( \
/* for unused positions */ \
na, \
\
/* left hand, spatial positions */ \
kB6,kB5,kB4,kB3,kB2,kB1,kB0, \
kA6,kA5,kA4,kA3,kA2,kA1,kA0, \
k96,k95,k94,k93,k92,k91, \
k86,k85,k84,k83,k82,k81,k80, \
k76,k75,k74,k73,k72, \
k64, \
k63, k60, \
k65,k62,k61, \
\
/* right hand, spatial positions */ \
k50,k51,k52,k53,k54,k55,k56, \
k40,k41,k42,k43,k44,k45,k46, \
k31,k32,k33,k34,k35,k36, \
k20,k21,k22,k23,k24,k25,k26, \
k12,k13,k14,k15,k16, \
k04, \
k00, k03, \
k01,k02,k05 ) \
\
/* matrix positions */ \
{ { k00,k01,k02,k03,k04,k05, na,}, \
{ na, na,k12,k13,k14,k15,k16,}, \
{ k20,k21,k22,k23,k24,k25,k26,}, \
{ na,k31,k32,k33,k34,k35,k36,}, \
{ k40,k41,k42,k43,k44,k45,k46,}, \
{ k50,k51,k52,k53,k54,k55,k56,}, \
{ k60,k61,k62,k63,k64,k65, na,}, \
{ na, na,k72,k73,k74,k75,k76,}, \
{ k80,k81,k82,k83,k84,k85,k86,}, \
{ na,k91,k92,k93,k94,k95,k96,}, \
{ kA0,kA1,kA2,kA3,kA4,kA5,kA6,}, \
{ kB0,kB1,kB2,kB3,kB4,kB5,kB6 } }
#define LAYER_SET_ALL(na, kxx) \
LAYER( \
na, \
\
kxx,kxx,kxx,kxx,kxx,kxx,kxx, \
kxx,kxx,kxx,kxx,kxx,kxx,kxx, \
kxx,kxx,kxx,kxx,kxx,kxx, \
kxx,kxx,kxx,kxx,kxx,kxx,kxx, \
kxx,kxx,kxx,kxx,kxx, \
kxx, \
kxx, kxx, \
kxx,kxx,kxx, \
\
kxx,kxx,kxx,kxx,kxx,kxx,kxx, \
kxx,kxx,kxx,kxx,kxx,kxx,kxx, \
kxx,kxx,kxx,kxx,kxx,kxx, \
kxx,kxx,kxx,kxx,kxx,kxx,kxx, \
kxx,kxx,kxx,kxx,kxx, \
kxx, \
kxx, kxx, \
kxx,kxx,kxx )
#endif
#endif

View File

@ -1,5 +1,5 @@
/* ----------------------------------------------------------------------------
* ergoDOX controller: MCP23018 specific exports
* ergoDOX controller: MCP23018 specific exports : private
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
@ -7,20 +7,16 @@
* ------------------------------------------------------------------------- */
#ifndef MCP23018_h
#define MCP23018_h
#ifndef MCP23018_h_PRIVATE
#define MCP23018_h_PRIVATE
#include "lib/data-types.h"
#include "matrix.h"
#ifdef KEYBOARD_INCLUDE_PRIVATE
#define MCP23018_TWI_ADDRESS 0b0100000
#define MCP23018_TWI_ADDRESS 0b0100000
uint8_t mcp23018_init(void);
uint8_t mcp23018_update_matrix(
bool matrix[KB_ROWS][KB_COLUMNS] );
#endif
uint8_t mcp23018_init(void);
uint8_t mcp23018_update_matrix( bool matrix[KB_ROWS][KB_COLUMNS] );
#endif

View File

@ -11,9 +11,8 @@
#include "lib/data-types.h"
#include "lib/twi.h" // `TWI_FREQ` defined in "teensy-2-0.c"
#define KEYBOARD_INCLUDE_PRIVATE
#include "matrix.h"
#include "mcp23018.h"
#include "mcp23018--private.h"
// register addresses (see "mcp23018.md")

View File

@ -0,0 +1,19 @@
/* ----------------------------------------------------------------------------
* ergoDOX controller: Teensy 2.0 specific exports : private
* ----------------------------------------------------------------------------
* 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>
* ------------------------------------------------------------------------- */
#ifndef TEENSY_2_0_h_PRIVATE
#define TEENSY_2_0_h_PRIVATE
#include "matrix.h"
uint8_t teensy_init(void);
uint8_t teensy_update_matrix( bool matrix[KB_ROWS][KB_COLUMNS] );
#endif

View File

@ -13,9 +13,9 @@
#define TWI_FREQ 400000
#include "lib/twi.h"
#define KEYBOARD_INCLUDE_PRIVATE
#include "matrix.h"
#include "teensy-2-0.h"
#include "teensy-2-0--private.h"
// processor frequency (from <http://www.pjrc.com/teensy/prescaler.html>)

View File

@ -13,8 +13,6 @@
#include <avr/io.h> // for the register macros
#include "lib/data-types.h"
#include "matrix.h"
// LED control
#define _led_1_on() (DDRB |= (1<<6))
@ -53,14 +51,5 @@
_led_3_set_percent(n); \
} while(0)
#ifdef KEYBOARD_INCLUDE_PRIVATE
uint8_t teensy_init(void);
uint8_t teensy_update_matrix(
bool matrix[KB_ROWS][KB_COLUMNS] );
#endif
#endif

View File

@ -19,16 +19,13 @@
#include "key-functions.h"
void kbfun_press(
uint8_t keycode, uint8_t * current_layer,
uint8_t * row, uint8_t * col ) {
void kbfun_press( KBFUN_FUNCTION_ARGS ) {
// no-op
if (keycode == 0)
if (keycode_ == 0)
return;
// modifier keys
switch (keycode) {
switch (keycode_) {
case KEY_LeftControl: keyboard_modifier_keys |= (1<<0);
return;
case KEY_LeftShift: keyboard_modifier_keys |= (1<<1);
@ -50,21 +47,18 @@ void kbfun_press(
// all others
for (uint8_t i=0; i<6; i++)
if (keyboard_keys[i] == 0) {
keyboard_keys[i] = keycode;
break;
keyboard_keys[i] = keycode_;
return;
}
}
void kbfun_release(
uint8_t keycode, uint8_t * current_layer,
uint8_t * row, uint8_t * col ) {
void kbfun_release( KBFUN_FUNCTION_ARGS ) {
// no-op
if (keycode == 0)
if (keycode_ == 0)
return;
// modifier keys
switch (keycode) {
switch (keycode_) {
case KEY_LeftControl: keyboard_modifier_keys &= ~(1<<0);
return;
case KEY_LeftShift: keyboard_modifier_keys &= ~(1<<1);
@ -85,37 +79,30 @@ void kbfun_release(
// all others
for (uint8_t i=0; i<6; i++)
if (keyboard_keys[i] == keycode) {
if (keyboard_keys[i] == keycode_) {
keyboard_keys[i] = 0;
break;
return;
}
}
// TODO:
// - allocate 10 layers, by default (overrideable in the map specific .h)
// - implement having different keys using different layers
// - implement two shifts => capslock
// - implement layer lock key combos (make a function to switch to a specific
// layer)
void kbfun_layer_inc(
uint8_t keycode, uint8_t * current_layer,
uint8_t * row, uint8_t * col ) {
if (*current_layer < (KB_LAYERS-1))
(*current_layer)++;
// else do nothing
void kbfun_layer_inc( KBFUN_FUNCTION_ARGS ) {
for (uint8_t row=0; row<KB_ROWS; row++)
for (uint8_t col=0; col<KB_COLUMNS; col++)
if ((*current_layers_)[row][col] < (KB_LAYERS-1))
((*current_layers_)[row][col])++;
// else do nothing
}
void kbfun_layer_dec(
uint8_t keycode, uint8_t * current_layer,
uint8_t * row, uint8_t * col ) {
if (*current_layer > 0)
(*current_layer)--;
// else do nothing
void kbfun_layer_dec( KBFUN_FUNCTION_ARGS ) {
for (uint8_t row=0; row<KB_ROWS; row++)
for (uint8_t col=0; col<KB_COLUMNS; col++)
if ((*current_layers_)[row][col] > 0)
((*current_layers_)[row][col])--;
// else do nothing
}
// ----------------------------------------------------------------------------

View File

@ -12,22 +12,40 @@
#include "lib/data-types.h"
typedef void (*kbfun_funptr_t)(
uint8_t, uint8_t *,
uint8_t *, uint8_t * );
// --------------------------------------------------------------------
// include the appropriate 'matrix.h'
// -------
// we're not simply including 'keyboard.h' here because this header is
// meant to be included by 'keyboard/layout/*.c', which is indirectly
// included by 'keyboard.h'; and that would lead to a circular include,
// which gcc might (depending on the order of include statements it
// encounters) deal with by processing this file before 'matrix.h',
// which would give us undefined macros here
#undef _str
#undef _expstr
#undef _inc
#define _str(s) #s // stringify
#define _expstr(s) _str(s) // expand -> stringify
#define _inc _expstr(keyboard/MAKEFILE_KEYBOARD/matrix.h) // inc(lude)
#include _inc
#undef _str
#undef _expstr
#undef _inc
// --------------------------------------------------------------------
void kbfun_press(
uint8_t keycode, uint8_t * current_layer,
uint8_t * row, uint8_t * col );
void kbfun_release(
uint8_t keycode, uint8_t * current_layer,
uint8_t * row, uint8_t * col );
void kbfun_layer_inc(
uint8_t keycode, uint8_t * current_layer,
uint8_t * row, uint8_t * col );
void kbfun_layer_dec(
uint8_t keycode, uint8_t * current_layer,
uint8_t * row, uint8_t * col );
#define KBFUN_FUNCTION_ARGS \
uint8_t keycode_, \
uint8_t (*current_layers_)[KB_ROWS][KB_COLUMNS], \
uint8_t (*pressed_layers_)[KB_ROWS][KB_COLUMNS], \
uint8_t * row_, uint8_t * col_
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 );
#endif

View File

@ -27,7 +27,10 @@ int main(void) {
kb_led_state_ready();
for (;;) {
static uint8_t current_layer = 0;
// 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
static uint8_t pressed_layers[KB_ROWS][KB_COLUMNS];
// swap `kb_is_pressed` and `kb_was_pressed`, then update
bool (*temp)[KB_ROWS][KB_COLUMNS] = kb_was_pressed;
@ -36,32 +39,44 @@ int main(void) {
kb_update_matrix(*kb_is_pressed);
// call the appropriate function for each key, then send the usb report
// if necessary
// call the appropriate function for each key(press|release), 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
// - anything passed to the key function by reference may be changed
// after the call
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) {
uint8_t current_layer = current_layers[row][col];
pressed_layers[row][col] = current_layer;
kbfun_funptr_t press_function =
kb_layout_press_get(current_layer, row, col);
kb_layout_press_get(current_layer, row, col);
if (press_function) {
(*press_function)(
kb_layout_get(current_layer, row, col),
&current_layer, &row, &col );
&current_layers, &pressed_layers,
&row, &col );
}
} else {
uint8_t pressed_layer = pressed_layers[row][col];
kbfun_funptr_t release_function =
kb_layout_release_get(current_layer, row, col);
kb_layout_release_get(pressed_layer, row, col);
if (release_function) {
(*release_function)(
kb_layout_get(current_layer, row, col),
&current_layer, &row, &col );
kb_layout_get(pressed_layer, row, col),
&current_layers, &pressed_layers,
&row, &col );
}
}