Skip to content

Commit

Permalink
feat: add tests for keyboard_get_keycodes consumer_press_release, add…
Browse files Browse the repository at this point in the history
… testing for errors in some tests, add consumer code functions to squirrel_quantum
  • Loading branch information
headblockhead committed Aug 20, 2024
1 parent ad246fc commit 97665a0
Show file tree
Hide file tree
Showing 11 changed files with 246 additions and 61 deletions.
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ elseif(CMAKE_BUILD_TYPE STREQUAL "Testing")
add_executable(quantum_passthrough_press_release tests/quantum_passthrough_press_release.c)
target_link_libraries(quantum_passthrough_press_release squirrel)
add_test(NAME quantum_passthrough_press_release COMMAND quantum_passthrough_press_release)

add_executable(keyboard_get_keycodes tests/keyboard_get_keycodes.c)
target_link_libraries(keyboard_get_keycodes squirrel)
add_test(NAME keyboard_get_keycodes COMMAND keyboard_get_keycodes)

add_executable(consumer_press_release tests/consumer_press_release.c)
target_link_libraries(consumer_press_release squirrel)
add_test(NAME consumer_press_release COMMAND consumer_press_release)
else()
add_compile_options(-Os) # Enable size optimizations
endif()
Expand Down
18 changes: 8 additions & 10 deletions include/squirrel_consumer.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@
// time.
extern uint16_t consumer_code;

// activate_consumer_code sets the provided consumer code as the active consumer
// code.
void activate_consumer_code(uint16_t consumer_code);

// deactivate_consumer_code sets the active consumer code to 0 if it is the
// provided consumer code.
void deactivate_consumer_code(uint16_t consumer_code);

// get_consumer_code returns the currently active consumer code.
uint16_t get_consumer_code();
// consumer_activate_consumer_code sets the provided consumer code as the active
// consumer code.
void consumer_activate_consumer_code(uint16_t consumer_code);
// consumer_deactivate_consumer_code sets the active consumer code to 0 if it is
// the provided consumer code.
void consumer_deactivate_consumer_code(uint16_t consumer_code);
// consumer_get_consumer_code returns the currently active consumer code.
uint16_t consumer_get_consumer_code();

#endif
13 changes: 7 additions & 6 deletions include/squirrel_keyboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,23 @@
#include <stdbool.h>
#include <stdint.h>

extern bool keycodes[256];
extern uint8_t modifiers;
extern bool keyboard_keycodes[256];
extern uint8_t keyboard_modifiers;

// keyboard_activate_keycode marks the provided keycode as active.
void keyboard_activate_keycode(uint8_t keycode);
// keyboard_deactivate_keycode marks the provided keycode as inactive.
void keyboard_deactivate_keycode(uint8_t keycode);
// get_active_keycodes populates the provided array with the active keycodes,
// and returns the number of active keycodes.
void keyboard_get_keycodes(uint8_t *active_keycodes);
// keyboard_get_keycodes populates the provided array with the first 6 active
// keycodes. 6 is the maximum number of keycodes that
// can be sent over USB HID.
void keyboard_get_keycodes(uint8_t (*active_keycodes)[6]);

// keyboard_activate_modifier marks the provided modifier as active.
void keyboard_activate_modifier(uint8_t modifier);
// keyboard_deactivate_modifier marks the provided modifier as inactive.
void keyboard_deactivate_modifier(uint8_t modifier);
// get_active_modifiers returns the active modifiers.
// keyboard_get_modifiers returns a bitfield of active modifiers.
uint8_t keyboard_get_modifiers();

#endif
10 changes: 10 additions & 0 deletions include/squirrel_quantum.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@ enum squirrel_error keyboard_modifier_release(struct key *key, uint8_t layer,
uint8_t key_index, int arg_count,
...);

// consumer_press expects a single uint16 consumer code. See
// https://www.freebsddiary.org/APC/usb_hid_usages for all defined codes.
enum squirrel_error consumer_press(struct key *key, uint8_t layer,
uint8_t key_index, int arg_count, ...);

// consumer_release expects a single uint16 consumer code. See
// https://www.freebsddiary.org/APC/usb_hid_usages for all defined codes.
enum squirrel_error consumer_release(struct key *key, uint8_t layer,
uint8_t key_index, int arg_count, ...);

// quantum_passthrough passes the press action to the highest active layer below
// the current one. It expectes no extra args.
enum squirrel_error quantum_passthrough_press(struct key *key, uint8_t layer,
Expand Down
8 changes: 3 additions & 5 deletions src/squirrel_consumer.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@

uint16_t consumer_code = 0;

void activate_consumer_code(uint16_t code) { consumer_code = code; }

void deactivate_consumer_code(uint16_t code) {
void consumer_activate_consumer_code(uint16_t code) { consumer_code = code; }
void consumer_deactivate_consumer_code(uint16_t code) {
if (consumer_code == code) {
consumer_code = 0;
}
}

uint16_t get_consumer_code() { return consumer_code; }
uint16_t consumer_get_consumer_code() { return consumer_code; }
30 changes: 19 additions & 11 deletions src/squirrel_keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,30 @@
#include <stdbool.h>
#include <stdint.h>

bool keycodes[256] = {false};
uint8_t modifiers = 0;
bool keyboard_keycodes[256] = {false};
uint8_t keyboard_modifiers = 0;

void keyboard_activate_keycode(uint8_t keycode) { keycodes[keycode] = true; }
void keyboard_deactivate_keycode(uint8_t keycode) { keycodes[keycode] = false; }
void keyboard_get_keycodes(uint8_t *active_keycodes) {
void keyboard_activate_keycode(uint8_t keycode) {
keyboard_keycodes[keycode] = true;
}
void keyboard_deactivate_keycode(uint8_t keycode) {
keyboard_keycodes[keycode] = false;
}
void keyboard_get_keycodes(uint8_t (*active_keycodes)[6]) {
uint8_t active_keycodes_index = 0;
for (uint8_t i = 0; i != 255; i++) {
if (!keycodes[i]) {
for (int i = 0; (i <= 0xFF) && active_keycodes_index < 6; i++) {
if (!keyboard_keycodes[i]) {
continue;
}
active_keycodes[active_keycodes_index] = i;
(*active_keycodes)[active_keycodes_index] = i;
active_keycodes_index++;
}
}

void keyboard_activate_modifier(uint8_t modifier) { modifiers |= modifier; }
void keyboard_deactivate_modifier(uint8_t modifier) { modifiers &= ~modifier; }
uint8_t keyboard_get_modifiers() { return modifiers; }
void keyboard_activate_modifier(uint8_t modifier) {
keyboard_modifiers |= modifier;
}
void keyboard_deactivate_modifier(uint8_t modifier) {
keyboard_modifiers &= ~modifier;
}
uint8_t keyboard_get_modifiers() { return keyboard_modifiers; }
33 changes: 33 additions & 0 deletions src/squirrel_quantum.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "squirrel_quantum.h"
#include "squirrel.h"
#include "squirrel_consumer.h"
#include "squirrel_key.h"
#include "squirrel_keyboard.h"
#include <stdarg.h>
Expand Down Expand Up @@ -80,6 +81,38 @@ enum squirrel_error keyboard_modifier_release(struct key *key, uint8_t layer,
return ERR_NONE;
}

enum squirrel_error consumer_press(struct key *key, uint8_t layer,
uint8_t key_index, int arg_count, ...) {
(void)layer;
(void)key_index;

va_list args;
va_start(args, arg_count);
if (arg_count != 1) {
return ERR_KEY_FUNC_WRONG_ARGUMENT_COUNT;
};
uint16_t consumer_code = va_arg(args, int);
consumer_activate_consumer_code(consumer_code); // squirrel_consumer
va_end(args);
return ERR_NONE;
}

enum squirrel_error consumer_release(struct key *key, uint8_t layer,
uint8_t key_index, int arg_count, ...) {
(void)layer;
(void)key_index;

va_list args;
va_start(args, arg_count);
if (arg_count != 1) {
return ERR_KEY_FUNC_WRONG_ARGUMENT_COUNT;
};
uint16_t consumer_code = va_arg(args, int);
consumer_deactivate_consumer_code(consumer_code); // squirrel_consumer
va_end(args);
return ERR_NONE;
}

// quantum_passthrough_press does not take extra arguments.
enum squirrel_error quantum_passthrough_press(struct key *key, uint8_t layer,
uint8_t key_index, int arg_count,
Expand Down
72 changes: 72 additions & 0 deletions tests/consumer_press_release.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include "squirrel.h"
#include "squirrel_consumer.h"
#include "squirrel_key.h"
#include "squirrel_quantum.h"

// test: consumer_press + consumer_release - in squirrel_quantum.c
int main() {
struct key test_key; // values unused
enum squirrel_error err;
for (uint16_t test_consumer_code = 0; test_consumer_code <= 65534;
test_consumer_code++) {
// consumer_press
// no code becomes a code
consumer_code = 0;
err = consumer_press(&test_key, 0, 0, 1, test_consumer_code);
if (err != ERR_NONE) {
return 1;
}
if (consumer_code != test_consumer_code) {
return 2;
}
// a code stays a code
err = consumer_press(&test_key, 0, 0, 1, test_consumer_code);
if (err != ERR_NONE) {
return 3;
}
if (consumer_code != test_consumer_code) {
return 4;
}
// another code becomes a code
consumer_code = 0xFFFF;
err = consumer_press(&test_key, 0, 0, 1, test_consumer_code);
if (err != ERR_NONE) {
return 5;
}
if (consumer_code != test_consumer_code) {
return 6;
}

// consumer_release
// a code becomes no code
consumer_code = test_consumer_code;
err = consumer_release(&test_key, 0, 0, 1, test_consumer_code);
if (err != ERR_NONE) {
return 7;
}
if (consumer_code != 0) {
return 8;
}
// another code stays another code
consumer_code = 0xFFFF;
err = consumer_release(&test_key, 0, 0, 1, test_consumer_code);
if (err != ERR_NONE) {
return 9;
}
if (consumer_code != 0xFFFF) {
return 10;
}
}

// Test expected errors
err = consumer_press(&test_key, 0, 0, 0, 0);
if (err != ERR_KEY_FUNC_WRONG_ARGUMENT_COUNT) {
return 11;
}
err = consumer_release(&test_key, 0, 0, 0, 0);
if (err != ERR_KEY_FUNC_WRONG_ARGUMENT_COUNT) {
return 12;
}

return 0;
};
32 changes: 32 additions & 0 deletions tests/keyboard_get_keycodes.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "squirrel.h"
#include "squirrel_key.h"
#include "squirrel_keyboard.h"
#include "squirrel_quantum.h"

// test: keyboard_get_keycodes - in squirrel_keyboard.c
int main() {
uint8_t active_keycodes[6] = {0, 0, 0, 0, 0, 0};
keyboard_get_keycodes(&active_keycodes);
for (uint8_t i = 0; i < 6; i++) {
if (active_keycodes[i] != 0) {
return 1;
}
}
for (int i = 0; i < 6; i++) {
keyboard_keycodes[i] = true;
}
keyboard_get_keycodes(&active_keycodes);
for (uint8_t i = 0; i < 6; i++) {
if (active_keycodes[i] != i) {
return 2;
}
}
keyboard_keycodes[7] = true;
keyboard_get_keycodes(&active_keycodes);
for (uint8_t i = 0; i < 6; i++) {
if (active_keycodes[i] != i) {
return 3;
}
}
return 0;
};
26 changes: 13 additions & 13 deletions tests/keyboard_modifier_press_release.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,26 @@ int main() {

// no modifiers adding no modifiers is no modifiers
uint8_t current_modifier = 0b00000000;
modifiers = 0;
keyboard_modifiers = 0;
enum squirrel_error err =
keyboard_modifier_press(&test_key, 0, 0, 1, current_modifier);
if (err != ERR_NONE) {
return 255;
}
if (modifiers != 0b00000000) {
if (keyboard_modifiers != 0b00000000) {
return 1;
}

// no modifiers adding a modifier is a modifier
current_modifier = 0b00000001;
for (uint8_t i = 0; i < 8; i++) {
modifiers = 0;
keyboard_modifiers = 0;
enum squirrel_error err =
keyboard_modifier_press(&test_key, 0, 0, 1, current_modifier);
if (err != ERR_NONE) {
return 255;
}
if (modifiers != current_modifier) {
if (keyboard_modifiers != current_modifier) {
return 2;
}
current_modifier = current_modifier << 1;
Expand All @@ -40,13 +40,13 @@ int main() {
current_modifier = 0b00000001;
for (uint8_t i = 0; i < 8; i++) {
// modifiers stack, ORd to become the same number
uint8_t old_modifiers = modifiers;
uint8_t old_modifiers = keyboard_modifiers;
enum squirrel_error err =
keyboard_modifier_press(&test_key, 0, 0, 1, current_modifier);
if (err != ERR_NONE) {
return 255;
}
if (modifiers != (old_modifiers | current_modifier)) {
if (keyboard_modifiers != (old_modifiers | current_modifier)) {
return 3;
}
current_modifier = current_modifier << 1;
Expand All @@ -67,42 +67,42 @@ int main() {

// no modifiers removing no modifiers is no modifiers
current_modifier = 0b00000000;
modifiers = 0;
keyboard_modifiers = 0;
err = keyboard_modifier_release(&test_key, 0, 0, 1, current_modifier);
if (err != ERR_NONE) {
return 255;
}
if (modifiers != 0b00000000) {
if (keyboard_modifiers != 0b00000000) {
return 4;
}

// a modifier removing a modifier is no modifiers
current_modifier = 0b00000001;
for (uint8_t i = 0; i < 8; i++) {
modifiers = current_modifier;
keyboard_modifiers = current_modifier;
enum squirrel_error err =
keyboard_modifier_release(&test_key, 0, 0, 1, current_modifier);
if (err != ERR_NONE) {
return 255;
}
if (modifiers != 0b000000000) {
if (keyboard_modifiers != 0b000000000) {
return 5;
}
current_modifier = current_modifier << 1;
}

// more than one modifier removing a modifier is less modifiers.
current_modifier = 0b00000001;
modifiers = 0b11111111;
keyboard_modifiers = 0b11111111;
for (uint8_t i = 0; i < 8; i++) {
// modifiers stack, ORd to become the same number
uint8_t old_modifiers = modifiers;
uint8_t old_modifiers = keyboard_modifiers;
enum squirrel_error err =
keyboard_modifier_release(&test_key, 0, 0, 1, current_modifier);
if (err != ERR_NONE) {
return 255;
}
if (modifiers != (old_modifiers & ~current_modifier)) {
if (keyboard_modifiers != (old_modifiers & ~current_modifier)) {
return 6;
}
current_modifier = current_modifier << 1;
Expand Down
Loading

0 comments on commit 97665a0

Please sign in to comment.