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;
if (list->length == 0) {
// insert as only node (no others exist yet)
list->head = node;
list->tail = node;
node->next = NULL;
} else {
// find positive, in-bounds index
index = index % list->length;
if (index < 0)
index += list->length;
if (index == 0) {
// insert as first node
node->next = list->head;
list->head = node;
if (list->number_of_elements == 0)
} 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->number_of_elements++;
list->length++;
return list;
}
/*
* add_tail()
* peek()
*
* Arguments
* - index: [see 'insert()']
*
* Returns
* - success: the pointer to the list that was passed
* - failure: NULL
* - success: the data field of the node at the given index
* - failure: (_data_t) 0
*/
_list_t * linked_list_add_tail(_list_t * list, _data_t data) {
_NEW_POINTER(_node_t, node);
if (!node) return NULL;
_data_t linked_list_peek(_list_t * list, int index) {
// if: no nodes exist
if (list->length == 0)
return (_data_t) 0;
node->data = data;
node->next = NULL;
if (list->number_of_elements == 0)
list->head = node;
else
list->tail->next = node;
list->tail = node;
// find positive, in-bounds index
index = index % list->length;
if (index < 0)
index += list->length;
list->number_of_elements++;
return list;
// 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,21 +353,38 @@ 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(
* 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,
@ -391,25 +408,74 @@ void kbfun_layermask_numpad_press_release( KBFUN_FUNCTION_ARGS ) {
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))) ) {
// toggle numlock
// 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();
}
// set layer mask
if (pressed_)
_layer_set_mask(keycode_, layer_mask, current_layers_);
else
_layer_set_mask(*current_layer_, layer_mask, current_layers_);
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
/* ----------------------------------------------------------------------------
* ------------------------------------------------------------------------- */
// ----------------------------------------------------------------------------

View File

@ -55,7 +55,9 @@
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_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