diff --git a/src/keyboard/ergodox/layout/qwerty.c b/src/keyboard/ergodox/layout/qwerty.c index c77cdf8..1e5490d 100644 --- a/src/keyboard/ergodox/layout/qwerty.c +++ b/src/keyboard/ergodox/layout/qwerty.c @@ -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 ) // ---------------------------------------------------------------------------- }; diff --git a/src/lib/data-types/linked-list.c b/src/lib/data-types/linked-list.c index 9528132..20f7141 100644 --- a/src/lib/data-types/linked-list.c +++ b/src/lib/data-types/linked-list.c @@ -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; inext; + 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; inext; + 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; inext; + 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; inext; - - 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; inext; - - 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; ihead = 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 diff --git a/src/lib/data-types/linked-list.h b/src/lib/data-types/linked-list.h index 56bcb88..a73ea82 100644 --- a/src/lib/data-types/linked-list.h +++ b/src/lib/data-types/linked-list.h @@ -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 diff --git a/src/lib/key-functions.c b/src/lib/key-functions.c index 541c12a..c7f2e2c 100644 --- a/src/lib/key-functions.c +++ b/src/lib/key-functions.c @@ -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) diff --git a/src/lib/key-functions.h b/src/lib/key-functions.h index b0e1740..b6e87ce 100644 --- a/src/lib/key-functions.h +++ b/src/lib/key-functions.h @@ -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