Skip to content

Commit

Permalink
feat: switch from stdarg to void**, add tests for squirrel_key
Browse files Browse the repository at this point in the history
  • Loading branch information
headblockhead committed Aug 20, 2024
1 parent 97665a0 commit 79a564b
Show file tree
Hide file tree
Showing 9 changed files with 184 additions and 91 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ elseif(CMAKE_BUILD_TYPE STREQUAL "Testing")
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)

add_executable(key tests/key.c)
target_link_libraries(key squirrel)
add_test(NAME key COMMAND key)
else()
add_compile_options(-Os) # Enable size optimizations
endif()
Expand Down
12 changes: 6 additions & 6 deletions include/squirrel_key.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
struct key {
enum squirrel_error (*pressed)(struct key *, uint8_t layer, uint8_t key_index,
int arg_count,
...); // called when the key is pressed
void *pressed_arguments; // arguments to pass to pressed
void **args); // called when the key is pressed
void **pressed_arguments; // arguments to pass to pressed
int pressed_argument_count; // the amount of arguments in pressed_arguments
enum squirrel_error (*released)(struct key *, uint8_t layer,
uint8_t key_index, int arg_count,
...); // called when the key is released
void *released_arguments; // arguments to pass to released
enum squirrel_error (*released)(
struct key *, uint8_t layer, uint8_t key_index, int arg_count,
void **args); // called when the key is released
void **released_arguments; // arguments to pass to released
int released_argument_count; // the amount of arguments in released_arguments
bool is_pressed; // true if the key is currently pressed
};
Expand Down
22 changes: 13 additions & 9 deletions include/squirrel_quantum.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,46 +17,50 @@ extern struct layer layers[17];

// key_nop does nothing (no operation)
enum squirrel_error key_nop(struct key *key, uint8_t layer, uint8_t key_index,
int arg_count, ...);
int arg_count, void **args);

// keyboard_press expects a single uint8 keycode
enum squirrel_error keyboard_press(struct key *key, uint8_t layer,
uint8_t key_index, int arg_count, ...);
uint8_t key_index, int arg_count,
void **args);

// keyboard_release expects a single uint8 keycode
enum squirrel_error keyboard_release(struct key *key, uint8_t layer,
uint8_t key_index, int arg_count, ...);
uint8_t key_index, int arg_count,
void **args);

// keyboard_modifier_press expects a single uint8 modifier
enum squirrel_error keyboard_modifier_press(struct key *key, uint8_t layer,
uint8_t key_index, int arg_count,
...);
void **args);

// keyboard_modifier_release expects a single uint8 modifier
enum squirrel_error keyboard_modifier_release(struct key *key, uint8_t layer,
uint8_t key_index, int arg_count,
...);
void **args);

// 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, ...);
uint8_t key_index, int arg_count,
void **args);

// 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, ...);
uint8_t key_index, int arg_count,
void **args);

// 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,
uint8_t key_index, int arg_count,
...);
void **args);

// quantum_passthrough_release passes the release action to the highest active
// layer below the current one. It expectes no extra args.
enum squirrel_error quantum_passthrough_release(struct key *key, uint8_t layer,
uint8_t key_index,
int arg_count, ...);
int arg_count, void **args);

#endif
67 changes: 21 additions & 46 deletions src/squirrel_quantum.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,120 +3,95 @@
#include "squirrel_consumer.h"
#include "squirrel_key.h"
#include "squirrel_keyboard.h"
#include <stdarg.h>
#include <stdint.h>

struct layer layers[17];

enum squirrel_error key_nop(struct key *key, uint8_t layer, uint8_t key_index,
int arg_count, ...) {
int arg_count, void **args) {
(void)key;
(void)arg_count;
(void)args;
return ERR_NONE;
}

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

va_list args;
va_start(args, arg_count);
if (arg_count != 1) {
return ERR_KEY_FUNC_WRONG_ARGUMENT_COUNT;
};
uint8_t keycode = va_arg(args, int);
keyboard_activate_keycode(keycode); // squirrel_keyboard
va_end(args);

keyboard_activate_keycode(*(uint8_t *)args[0]); // squirrel_keyboard
return ERR_NONE;
};

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

va_list args;
va_start(args, arg_count);
if (arg_count != 1) {
return ERR_KEY_FUNC_WRONG_ARGUMENT_COUNT;
};
uint8_t keycode = va_arg(args, int);
keyboard_deactivate_keycode(keycode); // squirrel_keyboard
va_end(args);
keyboard_deactivate_keycode(*(uint8_t *)args[0]); // squirrel_keyboard
return ERR_NONE;
}

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

va_list args;
va_start(args, arg_count);
if (arg_count != 1) {
return ERR_KEY_FUNC_WRONG_ARGUMENT_COUNT;
};
uint8_t modifier = va_arg(args, int);
keyboard_activate_modifier(modifier); // squirrel_keyboard
va_end(args);
keyboard_activate_modifier(*(uint8_t *)args[0]); // squirrel_keyboard
return ERR_NONE;
}

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

va_list args;
va_start(args, arg_count);
if (arg_count != 1) {
return ERR_KEY_FUNC_WRONG_ARGUMENT_COUNT;
};
uint8_t modifier = va_arg(args, int);
keyboard_deactivate_modifier(modifier); // squirrel_keyboard
va_end(args);
keyboard_deactivate_modifier(*(uint8_t *)args[0]); // squirrel_keyboard
return ERR_NONE;
}

enum squirrel_error consumer_press(struct key *key, uint8_t layer,
uint8_t key_index, int arg_count, ...) {
uint8_t key_index, int arg_count,
void **args) {
(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);
consumer_activate_consumer_code(*(uint16_t *)args[0]); // squirrel_consumer
return ERR_NONE;
}

enum squirrel_error consumer_release(struct key *key, uint8_t layer,
uint8_t key_index, int arg_count, ...) {
uint8_t key_index, int arg_count,
void **args) {
(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);
consumer_deactivate_consumer_code(*(uint16_t *)args[0]); // squirrel_consumer
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,
...) {
void **args) {
if (arg_count != 0) {
return ERR_KEY_FUNC_WRONG_ARGUMENT_COUNT;
};
Expand Down Expand Up @@ -145,7 +120,7 @@ enum squirrel_error quantum_passthrough_press(struct key *key, uint8_t layer,
// quantum_passthrough_release does not take extra arguments.
enum squirrel_error quantum_passthrough_release(struct key *key, uint8_t layer,
uint8_t key_index,
int arg_count, ...) {
int arg_count, void **args) {
if (arg_count != 0) {
return ERR_KEY_FUNC_WRONG_ARGUMENT_COUNT;
};
Expand Down
14 changes: 9 additions & 5 deletions tests/consumer_press_release.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,29 @@
#include "squirrel_consumer.h"
#include "squirrel_key.h"
#include "squirrel_quantum.h"
#include <stdint.h>
#include <stdlib.h>

// test: consumer_press + consumer_release - in squirrel_quantum.c
int main() {
struct key test_key; // values unused
enum squirrel_error err;
void **args = malloc(sizeof(void *));
for (uint16_t test_consumer_code = 0; test_consumer_code <= 65534;
test_consumer_code++) {
args[0] = &test_consumer_code;
// consumer_press
// no code becomes a code
consumer_code = 0;
err = consumer_press(&test_key, 0, 0, 1, test_consumer_code);
err = consumer_press(&test_key, 0, 0, 1, args);
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);
err = consumer_press(&test_key, 0, 0, 1, args);
if (err != ERR_NONE) {
return 3;
}
Expand All @@ -29,7 +33,7 @@ int main() {
}
// another code becomes a code
consumer_code = 0xFFFF;
err = consumer_press(&test_key, 0, 0, 1, test_consumer_code);
err = consumer_press(&test_key, 0, 0, 1, args);
if (err != ERR_NONE) {
return 5;
}
Expand All @@ -40,7 +44,7 @@ int main() {
// consumer_release
// a code becomes no code
consumer_code = test_consumer_code;
err = consumer_release(&test_key, 0, 0, 1, test_consumer_code);
err = consumer_release(&test_key, 0, 0, 1, args);
if (err != ERR_NONE) {
return 7;
}
Expand All @@ -49,7 +53,7 @@ int main() {
}
// another code stays another code
consumer_code = 0xFFFF;
err = consumer_release(&test_key, 0, 0, 1, test_consumer_code);
err = consumer_release(&test_key, 0, 0, 1, args);
if (err != ERR_NONE) {
return 9;
}
Expand Down
88 changes: 88 additions & 0 deletions tests/key.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include "squirrel.h"
#include "squirrel_init.h"
#include "squirrel_key.h"
#include "squirrel_quantum.h"
#include <stdarg.h>
#include <stdlib.h>

uint8_t test_result = 1;

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

if (arg_count != 2) {
return ERR_KEY_FUNC_WRONG_ARGUMENT_COUNT;
};
uint8_t code1 = *(uint8_t *)args[0];
uint8_t code2 = *(uint8_t *)args[1];
if (code1 == 0x0F && code2 == 0xF0) {
test_result = 0;
}
return ERR_NONE;
}

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

if (arg_count != 2) {
return ERR_KEY_FUNC_WRONG_ARGUMENT_COUNT;
};
uint8_t code1 = *(uint8_t *)args[0];
uint8_t code2 = *(uint8_t *)args[1];
if (code1 == 0xF0 && code2 == 0x0F) {
test_result = 0;
}
return ERR_NONE;
}

// test: press_key, release_key + check_key - in squirrel_key.c
int main() {
init_keyboard(1);

// press_key + release_key

uint8_t code1 = 0x0F;
uint8_t code2 = 0xF0;

struct key testkey;
testkey.pressed = test_press;
testkey.pressed_argument_count = 2;
testkey.pressed_arguments = malloc(2 * sizeof(void *));
testkey.pressed_arguments[0] = &code1;
testkey.pressed_arguments[1] = &code2;

testkey.released = test_release;
testkey.released_argument_count = 2;
testkey.released_arguments = malloc(2 * sizeof(void *));
testkey.released_arguments[0] = &code2;
testkey.released_arguments[1] = &code1;

layers[0].keys[0] = testkey;
layers[0].active = true;

enum squirrel_error err = press_key(0);
if (err != ERR_NONE) {
return 2;
}
if (test_result != 0) {
return 3;
}

test_result = 1;
err = release_key(0);
if (err != ERR_NONE) {
return 4;
}

free(testkey.pressed_arguments);
free(testkey.released_arguments);

// TODO: check_key

return test_result;
}
Loading

0 comments on commit 79a564b

Please sign in to comment.