Skip to content

Commit

Permalink
fix: most of squirrel
Browse files Browse the repository at this point in the history
  • Loading branch information
headblockhead committed Oct 9, 2024
1 parent 5e09b8f commit ffa32a8
Show file tree
Hide file tree
Showing 11 changed files with 97 additions and 49 deletions.
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.12)

project(squirrel VERSION 0.0.1 DESCRIPTION "Simplified, runtime-configurable QMK as a library")

add_compile_definitions(SQUIRREL_KEYCOUNT=1)

if (CMAKE_BUILD_TYPE STREQUAL "Debug")
message(STATUS "Debug/Development build enabled")
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Autocomplete support
Expand Down Expand Up @@ -61,6 +63,11 @@ elseif(CMAKE_BUILD_TYPE STREQUAL "Testing")
add_executable(keyboard_activate_deactivate_get_modifier tests/keyboard_activate_deactivate_get_modifier.c)
target_link_libraries(keyboard_activate_deactivate_get_modifier squirrel)
add_test(NAME keyboard_activate_deactivate_get_modifier COMMAND keyboard_activate_deactivate_get_modifier)

add_executable(keymap tests/keymap.c)
target_link_libraries(keymap squirrel)
target_compile_definitions(keymap PRIVATE SQUIRREL_KEYCOUNT=2)
add_test(NAME keymap COMMAND keymap)
else()
add_compile_options(-Os) # Enable size optimizations
endif()
Expand Down
22 changes: 15 additions & 7 deletions include/squirrel_key.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,25 @@
#include <stdbool.h>
#include <stdint.h>

#ifndef SQUIRREL_KEYCOUNT
#define SQUIRREL_KEYCOUNT 1
#endif
enum squirrel_keytype {
KEYTYPE_NOP,
KEYTYPE_KEYBOARD,
KEYTYPE_KEYBOARD_MODIFIER,
KEYTYPE_CONSUMER,
KEYTYPE_QUANTUM_PASSTHROUGH,
KEYTYPE_MOMENTARY,
KEYTYPE_TOGGLE,
KEYTYPE_SOLO,
};

typedef enum squirrel_error (*keyfunc)(uint8_t, uint8_t, void *);

struct key {
keyfunc pressed; // called when the key is pressed
keyfunc released; // called when the key is released
void *pressed_argument; // argument to pass to pressed
void *released_argument; // argument to pass to released
keyfunc pressed; // called when the key is pressed
keyfunc released; // called when the key is released
void *pressed_argument; // argument to pass to pressed
void *released_argument; // argument to pass to released
enum squirrel_keytype type; // the type of key
};

void copy_key(
Expand Down
5 changes: 3 additions & 2 deletions include/squirrel_keyboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ void keyboard_activate_keycode(uint8_t keycode);
void keyboard_deactivate_keycode(uint8_t keycode);
// 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]);
// can be sent over USB HID. If there are no keycodes, the function will return
// false.
bool keyboard_get_keycodes(uint8_t (*active_keycodes)[6]);

// keyboard_activate_modifier marks the provided modifier as active.
void keyboard_activate_modifier(uint8_t modifier);
Expand Down
4 changes: 0 additions & 4 deletions include/squirrel_quantum.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@
#include <stdarg.h>
#include <stdint.h>

#ifndef SQUIRREL_KEYCOUNT
#define SQUIRREL_KEYCOUNT 1
#endif

struct layer {
bool active; // true if this layer is currently active
struct key keys[SQUIRREL_KEYCOUNT];
Expand Down
6 changes: 1 addition & 5 deletions src/squirrel_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@
#include <stdlib.h>
#include <string.h>

#ifndef SQUIRREL_KEYCOUNT
#define SQUIRREL_KEYCOUNT 1
#endif

enum squirrel_error squirrel_init(void) {
struct key passthrough_key = (struct key){
.pressed = quantum_passthrough_press,
Expand All @@ -19,7 +15,7 @@ enum squirrel_error squirrel_init(void) {
for (int j = 16; j >= 0; j--) {
layers[j].active = false;
for (int i = 0; i < SQUIRREL_KEYCOUNT; i++) {
layers[j].keys[i] = passthrough_key;
copy_key(&passthrough_key, &layers[j].keys[i]);
}
}
layers[16].active = true;
Expand Down
12 changes: 4 additions & 8 deletions src/squirrel_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@
#include <stdio.h>
#include <stdlib.h>

#ifndef SQUIRREL_KEYCOUNT
#define SQUIRREL_KEYCOUNT 1
#endif

void copy_key(struct key *source, struct key *destination) {
*destination = *source;
}
Expand All @@ -25,9 +21,10 @@ enum squirrel_error press_key(uint8_t key_index) {
return err;
}
if (i == 16) {
continue;
break;
}
copy_key(&selected_key, &layers[16].keys[key_index]);
break;
}
return ERR_NONE;
}
Expand All @@ -44,20 +41,20 @@ enum squirrel_error release_key(uint8_t key_index) {
return err;
}
if (i != 16) {
continue;
break;
}
struct key passthrough_key;
passthrough_key.pressed = quantum_passthrough_press;
passthrough_key.released = quantum_passthrough_release;
copy_key(&passthrough_key, &layers[16].keys[key_index]);
break;
}
return ERR_NONE;
}

bool key_states[SQUIRREL_KEYCOUNT];

enum squirrel_error check_key(uint8_t key_index, bool is_pressed) {
enum squirrel_error err;
if (key_states[key_index] == is_pressed) {
return ERR_NONE;
}
Expand All @@ -67,5 +64,4 @@ enum squirrel_error check_key(uint8_t key_index, bool is_pressed) {
}
key_states[key_index] = false;
return release_key(key_index);
return ERR_NONE;
}
6 changes: 5 additions & 1 deletion src/squirrel_keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ void keyboard_activate_keycode(uint8_t keycode) {
void keyboard_deactivate_keycode(uint8_t keycode) {
keyboard_keycodes[keycode] = false;
}
void keyboard_get_keycodes(uint8_t (*active_keycodes)[6]) {
bool keyboard_get_keycodes(uint8_t (*active_keycodes)[6]) {
uint8_t active_keycodes_index = 0;
for (int i = 0; (i <= 0xFF) && active_keycodes_index < 6; i++) {
if (!keyboard_keycodes[i]) {
Expand All @@ -20,6 +20,10 @@ void keyboard_get_keycodes(uint8_t (*active_keycodes)[6]) {
(*active_keycodes)[active_keycodes_index] = i;
active_keycodes_index++;
}
if (active_keycodes_index == 0) {
return false;
}
return true;
}

void keyboard_activate_modifier(uint8_t modifier) {
Expand Down
43 changes: 31 additions & 12 deletions src/squirrel_keymap.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,62 +10,81 @@ struct key nop(void) {
}

struct key keyboard(uint8_t keycode) {
uint8_t *new_keycode = malloc(sizeof(uint8_t));
*new_keycode = keycode;
return (struct key){
.pressed = keyboard_press,
.released = keyboard_release,
.pressed_argument = &keycode,
.released_argument = &keycode,
.pressed_argument = new_keycode,
.released_argument = new_keycode,
.type = KEYTYPE_KEYBOARD,
};
}

struct key keyboard_modifier(uint8_t modifier) {
uint8_t *new_modifier = malloc(sizeof(uint8_t));
*new_modifier = modifier;
return (struct key){
.pressed = keyboard_modifier_press,
.released = keyboard_modifier_release,
.pressed_argument = &modifier,
.released_argument = &modifier,
.pressed_argument = new_modifier,
.released_argument = new_modifier,
.type = KEYTYPE_KEYBOARD_MODIFIER,
};
}

struct key consumer(uint16_t consumer) {
uint16_t *new_consumer = malloc(sizeof(uint16_t));
*new_consumer = consumer;
return (struct key){
.pressed = consumer_press,
.released = consumer_release,
.pressed_argument = &consumer,
.released_argument = &consumer,
.pressed_argument = new_consumer,
.released_argument = new_consumer,
.type = KEYTYPE_CONSUMER,
};
}

struct key passthrough(void) {
return (struct key){
.pressed = quantum_passthrough_press,
.released = quantum_passthrough_release,
.type = KEYTYPE_QUANTUM_PASSTHROUGH,
};
}

struct key layer_momentary(uint8_t layer) {
uint8_t *new_layer = malloc(sizeof(uint8_t));
*new_layer = layer;
return (struct key){
.pressed = layer_momentary_press,
.released = layer_momentary_release,
.pressed_argument = &layer,
.released_argument = &layer,
.pressed_argument = new_layer,
.released_argument = new_layer,
.type = KEYTYPE_MOMENTARY,
};
}

struct key layer_toggle(uint8_t layer) {
uint8_t *new_layer = malloc(sizeof(uint8_t));
*new_layer = layer;
return (struct key){
.pressed = layer_toggle_press,
.released = layer_toggle_release,
.pressed_argument = &layer,
.released_argument = &layer,
.pressed_argument = new_layer,
.released_argument = new_layer,
.type = KEYTYPE_TOGGLE,
};
}

struct key layer_solo(uint8_t layer) {
uint8_t *new_layer = malloc(sizeof(uint8_t));
*new_layer = layer;
return (struct key){
.pressed = layer_solo_press,
.released = layer_solo_release,
.pressed_argument = &layer,
.released_argument = &layer,
.pressed_argument = new_layer,
.released_argument = new_layer,
.type = KEYTYPE_SOLO,
};
}
6 changes: 4 additions & 2 deletions src/squirrel_quantum.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,10 @@ enum squirrel_error quantum_passthrough_press(uint8_t layer, uint8_t key_index,
return err;
}
if (i == 16) {
continue;
break;
}
copy_key(&selected_key, &layers[16].keys[key_index]);
break;
}
return ERR_NONE;
}
Expand All @@ -103,12 +104,13 @@ enum squirrel_error quantum_passthrough_release(uint8_t layer,
return err;
}
if (i != 16) {
continue;
break;
}
struct key passthrough_key;
passthrough_key.pressed = quantum_passthrough_press;
passthrough_key.released = quantum_passthrough_release;
copy_key(&passthrough_key, &layers[16].keys[key_index]);
break;
}
return ERR_NONE;
}
Expand Down
21 changes: 21 additions & 0 deletions tests/keymap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include "squirrel.h"
#include "squirrel_init.h"
#include "squirrel_key.h"
#include "squirrel_keymap.h"
#include "squirrel_quantum.h"
#include <stdarg.h>
#include <stdlib.h>

int main() {
squirrel_init();

layers[0].keys[0] = keyboard(0x00);
layers[0].keys[1] = keyboard(0x01);

if (*(uint8_t *)(layers[0].keys[0].pressed_argument) != 0x00) {
return 1;
}
if (*(uint8_t *)(layers[0].keys[1].pressed_argument) != 0x01) {
return 2;
}
}
14 changes: 6 additions & 8 deletions tests/quantum_passthrough_press_release.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,24 @@
uint8_t test_result = 1; // 0 = pass, 1 = fail
bool bad_test = false; // true = fail

enum squirrel_error test_press(struct key *key, uint8_t layer,
uint8_t key_index, void *arg) {
enum squirrel_error test_press(uint8_t layer, uint8_t key_index, void *arg) {
test_result = 0;
return ERR_NONE;
}

enum squirrel_error test_release(struct key *key, uint8_t layer,
uint8_t key_index, void *arg) {
enum squirrel_error test_release(uint8_t layer, uint8_t key_index, void *arg) {
test_result = 0;
return ERR_NONE;
}

enum squirrel_error bad_test_press(struct key *key, uint8_t layer,
uint8_t key_index, void *arg) {
enum squirrel_error bad_test_press(uint8_t layer, uint8_t key_index,
void *arg) {
bad_test = true;
return ERR_NONE;
}

enum squirrel_error bad_test_release(struct key *key, uint8_t layer,
uint8_t key_index, void *arg) {
enum squirrel_error bad_test_release(uint8_t layer, uint8_t key_index,
void *arg) {
bad_test = true;
return ERR_NONE;
}
Expand Down

0 comments on commit ffa32a8

Please sign in to comment.