changed numpad functions; linked-lists, etc. in progress

- the numpad functions are reorganized, and there are more of them now,
  so the numpad can be treated either as something that's toggled or
  something that's locked
- the numpad functions may need to be split into a separate file, to
  keep things pretty.  i'll look into it later.
- the linked-list functions are being written so that hopefully i can
  change the concept of how layers (with transitions and masking) are
  handled.  they're incomplete in this check in because i took a break
  to fix the numpad functions for dox
partial-rewrite
Ben Blazak 2012-07-08 17:54:23 -07:00
parent b257e21a15
commit 018b763423
5 changed files with 272 additions and 243 deletions

View File

@ -26,7 +26,9 @@
#define f_l_iex &kbfun_layer_inc_exec
#define f_l_dex &kbfun_layer_dec_exec
#define f_2kcap &kbfun_2_keys_capslock_press_release
#define f_lm_nu &kbfun_layermask_numpad_press_release
#define f_np_to &kbfun_layermask_numpad_toggle
#define f_np_on &kbfun_layermask_numpad_on
#define f_np_of &kbfun_layermask_numpad_off
#define f_btldr &kbfun_jump_to_bootloader
@ -69,7 +71,7 @@ _ctrlR, _enter,
_end, _home, _altL,
// right hand
_F12, _F6, _F7, _F8, _F9, _F10, 0,
0, 0, _dash, _lt_kp, _gt_kp, _currencyUnit, 0,
2, 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,
@ -134,14 +136,14 @@ NULL,
f_btldr,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,
f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,
f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,
f_lm_nu,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, NULL,
f_np_on,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, NULL,
f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,
f_prrel,
f_prrel, f_prrel,
f_prrel,f_prrel,f_prrel,
// right hand
f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,
f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,
f_np_to,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,
f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,
NULL,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,
f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,
@ -205,14 +207,14 @@ NULL,
NULL,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,
f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,
f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,
f_lm_nu,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, NULL,
f_np_of,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, NULL,
f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,
f_prrel,
f_prrel, f_prrel,
f_prrel,f_prrel,f_prrel,
// right hand
f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,
f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,
NULL,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,
f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,
NULL,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,
f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,
@ -254,10 +256,10 @@ f_l_dec, NULL, NULL, NULL, NULL, NULL, NULL,
f_l_iex, NULL, NULL, NULL, NULL, NULL, NULL,
f_l_dex, NULL, NULL, NULL, NULL, NULL, NULL,
f_2kcap, NULL, NULL, NULL, NULL, NULL, NULL,
f_lm_nu, NULL, NULL, NULL, NULL, NULL, NULL,
f_btldr, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL )
f_np_to, NULL, NULL, NULL, NULL, NULL, NULL,
f_np_on, NULL, NULL, NULL, NULL, NULL, NULL,
f_np_of, NULL, NULL, NULL, NULL, NULL, NULL,
f_btldr, NULL, NULL, NULL, NULL, NULL )
// ----------------------------------------------------------------------------
};

View File

@ -39,63 +39,154 @@ _list_t * linked_list_new(void) {
list->head = NULL;
list->tail = NULL;
list->number_of_elements = 0;
list->length = 0;
return list;
}
/*
* add_head()
* insert()
*
* Arguments
* - index: the index of the position that the new node will occupy. if index
* is negative, we set index += length (as in Python). so:
* - 0 => the first node in the list
* - 1 => the second node in the list
* - -1 => the last node in the list
* - -2 => the second from the last node in the list
* - '0' is undefined (returns 'failure')
* - out of bounds positions wrap around, so:
* - [length] => 0 => the first node in the list
* - -[length+1] => -1 => the last node in the list
*
* Returns
* - success: the pointer to the list that was passed
* - failure: NULL
*/
_list_t * linked_list_add_head(_list_t * list, _data_t data) {
_list_t * linked_list_insert(_list_t * list, _data_t data, int index) {
_NEW_POINTER(_node_t, node);
if (!node) return NULL;
node->data = data;
node->next = list->head;
list->head = node;
if (list->number_of_elements == 0)
list->tail = node;
list->number_of_elements++;
return list;
}
/*
* add_tail()
*
* Returns
* - success: the pointer to the list that was passed
* - failure: NULL
*/
_list_t * linked_list_add_tail(_list_t * list, _data_t data) {
_NEW_POINTER(_node_t, node);
if (!node) return NULL;
node->data = data;
node->next = NULL;
if (list->number_of_elements == 0)
if (list->length == 0) {
// insert as only node (no others exist yet)
list->head = node;
else
list->tail->next = node;
list->tail = node;
list->tail = node;
node->next = NULL;
} else {
// find positive, in-bounds index
index = index % list->length;
if (index < 0)
index += list->length;
list->number_of_elements++;
if (index == 0) {
// insert as first node
node->next = list->head;
list->head = node;
} else if (index == list->length-1) {
// insert as last node
list->tail->next = node;
list->tail = node;
node->next = NULL;
} else {
// insert as other node
_node_t * previous = list->head;
for (int i=1; i<index; i++)
previous = previous->next;
node->next = previous->next;
previous->next = node;
}
}
list->length++;
return list;
}
/*
* peek()
*
* Arguments
* - index: [see 'insert()']
*
* Returns
* - success: the data field of the node at the given index
* - failure: (_data_t) 0
*/
_data_t linked_list_peek(_list_t * list, int index) {
// if: no nodes exist
if (list->length == 0)
return (_data_t) 0;
// find positive, in-bounds index
index = index % list->length;
if (index < 0)
index += list->length;
// if: last node
if (index == list->length-1)
return list->tail->data;
// else
_node_t * node = list->head;
for (int i=0; i<index; i++)
node = node->next;
return node->data;
}
/*
* pop()
*
* Arguments
* - index: [see 'insert()']
*
* Returns
* - success: the data field of the node at the given index
* - failure: (_data_t) 0
*/
// TODO
_data_t linked_list_pop(_list_t * list, int index) {
// if: no nodes exist
if (list->length == 0)
return (_data_t) 0;
// find positive, in-bounds index
index = index % list->length;
if (index < 0)
index += list->length;
// vars
_data_t data;
_node_t * node;
if (index == 0) {
// pop first node
data = list->head->data;
node = list->head;
list->head = node->next;
} else {
// find the index-1'th node, then pop the next one
_node_t * previous;
previous = list->head;
for (int i=1; i<index; i++)
previous = previous->next;
data = previous->next->data;
node = previous->next;
previous->next = node->next;
}
free(node);
return data;
}
/*
* pop_head()
*
* Returns
* - success: the data element of the first node of the list
* - success: the data field of the first node of the list
* - failure: (_data_t) 0
*/
_data_t linked_list_pop_head(_list_t * list) {
if (list->number_of_elements == 0)
if (list->length == 0)
return (_data_t) 0;
_node_t node = {
@ -105,14 +196,14 @@ _data_t linked_list_pop_head(_list_t * list) {
free(list->head);
if (list->number_of_elements == 1) {
if (list->length == 1) {
list->head = NULL;
list->tail = NULL;
} else {
list->head = node.next;
}
list->number_of_elements--;
list->length--;
return node.data;
}
@ -120,7 +211,7 @@ _data_t linked_list_pop_head(_list_t * list) {
* pop_tail()
*
* Returns
* - success: the data element of the last node of the list
* - success: the data field of the last node of the list
* - failure: (_data_t) 0
*
* Note
@ -130,7 +221,7 @@ _data_t linked_list_pop_head(_list_t * list) {
* used all that much. It's here for completeness.
*/
_data_t linked_list_pop_tail(_list_t * list) {
if (list->number_of_elements == 0)
if (list->length == 0)
return (_data_t) 0;
_node_t node = {
@ -140,66 +231,20 @@ _data_t linked_list_pop_tail(_list_t * list) {
free(list->tail);
if (list->number_of_elements == 1) {
if (list->length == 1) {
list->head = NULL;
list->tail = NULL;
} else {
list->tail = list->head;
for (uint8_t i=2; i<(list->number_of_elements); i++)
for (uint8_t i=2; i<(list->length); i++)
list->tail = list->tail->next;
list->tail->next = NULL;
}
list->number_of_elements--;
list->length--;
return node.data;
}
/*
* read()
*
* Returns
* - success: the data element at the given position
* - failure: (_data_t) 0
*/
_data_t linked_list_read(_list_t * list, uint8_t position) {
if (position < 1 || position > (list->number_of_elements))
return (_data_t) 0;
_node_t * node = list->head;
for (uint8_t i=1; i<position; i++)
node = node->next;
return node->data;
}
/*
* insert()
* - Insert a new node containing the given data such that it occupies the
* given position in the list.
*
* Returns
* - success: the pointer to the list that was passed
* - failure: NULL
*/
_list_t * linked_list_insert(_list_t * list, _data_t data, uint8_t position) {
if (position < 1 || position > (list->number_of_elements)+1)
return NULL;
_NEW_POINTER(_node_t, new);
if (!new) return NULL;
_node_t * prev = list->head;
for (uint8_t i=0; i<position; i++)
prev = prev->next;
new->data = data;
new->next = prev->next;
prev->next = new;
list->number_of_elements++;
return list;
}
/*
* copy()
*
@ -211,7 +256,7 @@ _list_t * linked_list_copy(_list_t * list) {
_NEW_POINTER(_list_t, copy);
if (!copy) return NULL;
for (uint8_t i=1; i<=(list->number_of_elements); i++)
for (uint8_t i=1; i<=(list->length); i++)
linked_list_add_tail(copy, linked_list_read(list, i));
return copy;
@ -228,87 +273,12 @@ _list_t * linked_list_copy(_list_t * list) {
* that often.
*/
void linked_list_free(_list_t * list) {
while ((list->number_of_elements) > 0)
while ((list->length) > 0)
linked_list_pop_head(list);
free(list);
}
/*
* slice_copy()
* - Return the (copied) sublist
*
* Arguments
* - start_position:
* - the position of the first element to include in the slice
* - or '0' for the beginning of the list
* - end_position:
* - the position of the last element to include in the slice
* - or '0' for the end of the list
*
* Returns
* - success: a copy of the portion of the list indicated
* - failure: NULL
*/
_list_t * linked_list_slice_copy (
_list_t * list,
uint8_t start_position,
uint8_t end_position ) {
if ( start_position > end_position ||
end_position > (list->number_of_elements) )
return NULL;
if (start_position == 0)
start_position = 1;
if (end_position == 0)
end_position = list->number_of_elements;
_NEW_POINTER(_list_t, shallow_slice);
if (!shallow_slice) return NULL;
shallow_slice->number_of_elements = end_position - start_position + 1;
shallow_slice->head = list->head;
for (uint8_t i=1; i<start_position; i++)
shallow_slice->head = shallow_slice->head->next;
shallow_slice->tail = shallow_slice->head;
for (uint8_t i=1; i<(shallow_slice->number_of_elements); i++)
shallow_slice->tail = shallow_slice->tail->next;
return linked_list_copy(shallow_slice);
}
/*
* slice()
*/
_list_t * linked_list_slice (
_list_t * list,
uint8_t start_position,
uint8_t end_position ) {
// TODO
}
/*
* remove()
*/
_list_t * linked_list_remove(_list_t * list, uint8_t position) {
// TODO
}
/*
* find_first()
*/
uint8_t linked_list_find_first(_list_t * list, _data_t data) {
// TODO
}
/*
* reverse()
*/
_list_t * linked_list_reverse(_list_t * list) {
// TODO
}
// local macros (undefined here)
#undef _NEW_POINTER

View File

@ -26,7 +26,7 @@
};
struct linked_list {
uint8_t number_of_elements;
uint8_t length;
struct linked_list_node * head;
struct linked_list_node * tail;
};
@ -38,27 +38,16 @@
// functions
#define _list_t linked_list_t
#define _data_t LINKED_LIST_DATA_TYPE
// TODO
_list_t * linked_list_new (void);
_list_t * linked_list_add_head (_list_t * list, _data_t data);
_list_t * linked_list_add_tail (_list_t * list, _data_t data);
_data_t linked_list_pop_head (_list_t * list);
_data_t linked_list_pop_tail (_list_t * list);
_data_t linked_list_read (_list_t * list, uint8_t position);
_list_t * linked_list_insert ( _list_t * list,
uint8_t position,
_data_t data );
_list_t * linked_list_copy (_list_t * list);
void linked_list_free (_list_t * list);
_list_t * linked_list_slice_copy ( _list_t * list,
uint8_t start_position,
uint8_t end_position );
_list_t * linked_list_slice ( _list_t * list,
uint8_t start_position,
uint8_t end_position );
_list_t * linked_list_remove (_list_t * list, uint8_t position);
uint8_t linked_list_find_first (_list_t * list, _data_t data);
_list_t * linked_list_reverse (_list_t * list);
// /TODO
#undef _list_t
#undef _data_t

View File

@ -353,64 +353,130 @@ void kbfun_2_keys_capslock_press_release( KBFUN_FUNCTION_ARGS ) {
if (pressed_) keys_pressed++;
}
/*
* Activate Numpad
* - Sets num-lock (on for press, off for release) and shifts (without changing
* the overall current layer) the layer of the keys specified in this
* function to the value specified in the keymap
// 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
*
* Note
* - If a more than one layer mask of this type is used at the same time, the
* 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
* second will override the first, and any keys covered by both will be reset
* to the overall current layer when the second is released (even if the
* first is still pressed)
*/
void kbfun_layermask_numpad_press_release( KBFUN_FUNCTION_ARGS ) {
// define layer mask
bool layer_mask[KB_ROWS][KB_COLUMNS] = MATRIX_LAYER(
// unused
0,
* to the overall current layer when either is released (even if the other is
* still pressed)
* ------------------------------------------------------------------------- */
// 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,
// 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
// 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 );
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
// set numlock
if ( // if pressed and numlock off
(pressed_ && !(keyboard_leds & (1<<0))) ||
// if released and numlock on
(!pressed_ && (keyboard_leds & (1<<0))) ) {
// vars
static bool L(numpad_activated) = false;
static bool L(layer_mask)[KB_ROWS][KB_COLUMNS] =
MATRIX_LAYER(
// unused
0,
// toggle numlock
_press_release(true, KEYPAD_NumLock_Clear);
usb_keyboard_send();
_press_release(false, KEYPAD_NumLock_Clear);
usb_keyboard_send();
}
// 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,
// set layer mask
if (pressed_)
_layer_set_mask(keycode_, layer_mask, current_layers_);
else
_layer_set_mask(*current_layer_, layer_mask, current_layers_);
// 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)();
}
}
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
/*
* 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_);
}
/*
* 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
/* ----------------------------------------------------------------------------
* ------------------------------------------------------------------------- */
// ----------------------------------------------------------------------------
// public functions (device specific)

View File

@ -48,15 +48,17 @@
void _kbfun_exec_key ( KBFUN_FUNCTION_ARGS );
void kbfun_press_release (KBFUN_FUNCTION_ARGS);
void kbfun_toggle (KBFUN_FUNCTION_ARGS);
void kbfun_layer_inc (KBFUN_FUNCTION_ARGS);
void kbfun_layer_dec (KBFUN_FUNCTION_ARGS);
void kbfun_layer_inc_exec (KBFUN_FUNCTION_ARGS);
void kbfun_layer_dec_exec (KBFUN_FUNCTION_ARGS);
void kbfun_2_keys_capslock_press_release (KBFUN_FUNCTION_ARGS);
void kbfun_layermask_numpad_press_release (KBFUN_FUNCTION_ARGS);
void kbfun_jump_to_bootloader (KBFUN_FUNCTION_ARGS);
void kbfun_press_release (KBFUN_FUNCTION_ARGS);
void kbfun_toggle (KBFUN_FUNCTION_ARGS);
void kbfun_layer_inc (KBFUN_FUNCTION_ARGS);
void kbfun_layer_dec (KBFUN_FUNCTION_ARGS);
void kbfun_layer_inc_exec (KBFUN_FUNCTION_ARGS);
void kbfun_layer_dec_exec (KBFUN_FUNCTION_ARGS);
void kbfun_2_keys_capslock_press_release (KBFUN_FUNCTION_ARGS);
void kbfun_layermask_numpad_toggle (KBFUN_FUNCTION_ARGS);
void kbfun_layermask_numpad_on (KBFUN_FUNCTION_ARGS);
void kbfun_layermask_numpad_off (KBFUN_FUNCTION_ARGS);
void kbfun_jump_to_bootloader (KBFUN_FUNCTION_ARGS);
#endif