Skip to content

Commit ce45e34

Browse files
committed
feat(endpoints): add concept of no endpoint
This adds ZMK_TRANSPORT_NONE, which can be set as the preferred endpoint transport if you wish to prevent the keyboard from sending any output. More usefully, it also is used to indicate that the preferred endpoint is not available and it could not fall back to an available one. To go along with this, many endpoint functions are renamed for consistency, and a few new functions are added: - zmk_endpoint_get_preferred_transport() returns the value that was set with zmk_endpoint_set_preferred_transport(). - zmk_endpoint_get_preferred() returns the endpoint that will be used if it is available. This endpoint always has the same transport as zmk_endpoint_get_preferred_transport(). - zmk_endpoint_is_connected() is a shortcut to check if the keyboard is actually connected to an endpoint. This change is based on #2572 but without the option to disable endpoint fallback. It does refactor code to allow adding that feature later.
1 parent fed2cf6 commit ce45e34

File tree

13 files changed

+168
-75
lines changed

13 files changed

+168
-75
lines changed

app/boards/lowprokb/corneish_zen/widgets/output_status.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ struct output_status_state {
4545

4646
static struct output_status_state get_state(const zmk_event_t *_eh) {
4747
return (struct output_status_state){
48-
.selected_endpoint = zmk_endpoints_selected(),
48+
.selected_endpoint = zmk_endpoint_get_selected(),
4949
.active_profile_connected = zmk_ble_active_profile_is_connected(),
5050
.active_profile_bonded = !zmk_ble_active_profile_is_open(),
5151
};

app/boards/shields/nice_view/widgets/status.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ static void output_status_update_cb(struct output_status_state state) {
261261

262262
static struct output_status_state output_status_get_state(const zmk_event_t *_eh) {
263263
struct output_status_state state = {
264-
.selected_endpoint = zmk_endpoints_selected(),
264+
.selected_endpoint = zmk_endpoint_get_selected(),
265265
.active_profile_index = zmk_ble_active_profile_index(),
266266
.active_profile_connected = zmk_ble_active_profile_is_connected(),
267267
.active_profile_bonded = !zmk_ble_active_profile_is_open(),

app/include/zmk/endpoints.h

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
*/
1515
#define ZMK_ENDPOINT_STR_LEN 10
1616

17+
#define ZMK_ENDPOINT_NONE_COUNT 1
18+
1719
#ifdef CONFIG_ZMK_USB
1820
#define ZMK_ENDPOINT_USB_COUNT 1
1921
#else
@@ -33,7 +35,8 @@
3335
* Note that this value may change between firmware versions, so it should not
3436
* be used in any persistent storage.
3537
*/
36-
#define ZMK_ENDPOINT_COUNT (ZMK_ENDPOINT_USB_COUNT + ZMK_ENDPOINT_BLE_COUNT)
38+
#define ZMK_ENDPOINT_COUNT \
39+
(ZMK_ENDPOINT_NONE_COUNT + ZMK_ENDPOINT_USB_COUNT + ZMK_ENDPOINT_BLE_COUNT)
3740

3841
bool zmk_endpoint_instance_eq(struct zmk_endpoint_instance a, struct zmk_endpoint_instance b);
3942

@@ -57,21 +60,53 @@ int zmk_endpoint_instance_to_str(struct zmk_endpoint_instance endpoint, char *st
5760
int zmk_endpoint_instance_to_index(struct zmk_endpoint_instance endpoint);
5861

5962
/**
60-
* Sets the preferred endpoint transport to use. (If the preferred endpoint is
61-
* not available, a different one may automatically be selected.)
63+
* Sets the preferred endpoint transport to use.
64+
*
65+
* If the preferred endpoint is not available, zmk_endpoint_get_selected() may
66+
* automatically fall back to another transport.
67+
*/
68+
int zmk_endpoint_set_preferred_transport(enum zmk_transport transport);
69+
70+
enum zmk_transport zmk_endpoint_get_preferred_transport(void);
71+
72+
/**
73+
* If the preferred endpoint transport is USB, sets it to BLE, else sets it to USB.
74+
*/
75+
int zmk_endpoint_toggle_preferred_transport(void);
76+
77+
/**
78+
* Gets the endpoint instance that will be preferred if it is connected.
79+
*/
80+
struct zmk_endpoint_instance zmk_endpoint_get_preferred(void);
81+
82+
/**
83+
* Gets the endpoint instance that is currently in use.
84+
*
85+
* This may differ from zmk_endpoint_get_preferred(), for example if the preferred
86+
* endpoint is not connected, then this will return an instance for ZMK_TRANSPORT_NONE.
6287
*/
63-
int zmk_endpoints_select_transport(enum zmk_transport transport);
64-
int zmk_endpoints_toggle_transport(void);
88+
struct zmk_endpoint_instance zmk_endpoint_get_selected(void);
6589

6690
/**
67-
* Gets the currently-selected endpoint.
91+
* Returns whether the keyboard is connected to an endpoint.
92+
*
93+
* This is equivalent to zmk_endpoint_get_selected().transport != ZMK_TRANSPORT_NONE
6894
*/
69-
struct zmk_endpoint_instance zmk_endpoints_selected(void);
95+
bool zmk_endpoint_is_connected(void);
7096

71-
int zmk_endpoints_send_report(uint16_t usage_page);
97+
/**
98+
* Sends the HID report for the given usage page to the selected endpoint.
99+
*/
100+
int zmk_endpoint_send_report(uint16_t usage_page);
72101

73102
#if IS_ENABLED(CONFIG_ZMK_POINTING)
74-
int zmk_endpoints_send_mouse_report();
103+
/**
104+
* Sends the HID mouse report to the selected endpoint.
105+
*/
106+
int zmk_endpoint_send_mouse_report();
75107
#endif // IS_ENABLED(CONFIG_ZMK_POINTING)
76108

77-
void zmk_endpoints_clear_current(void);
109+
/**
110+
* Clears all HID reports for the selected endpoint.
111+
*/
112+
void zmk_endpoint_clear_reports(void);

app/include/zmk/endpoints_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
* The method by which data is sent.
1111
*/
1212
enum zmk_transport {
13+
ZMK_TRANSPORT_NONE,
1314
ZMK_TRANSPORT_USB,
1415
ZMK_TRANSPORT_BLE,
1516
};

app/src/behaviors/behavior_outputs.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,11 @@ static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
6060
struct zmk_behavior_binding_event event) {
6161
switch (binding->param1) {
6262
case OUT_TOG:
63-
return zmk_endpoints_toggle_transport();
63+
return zmk_endpoint_toggle_preferred_transport();
6464
case OUT_USB:
65-
return zmk_endpoints_select_transport(ZMK_TRANSPORT_USB);
65+
return zmk_endpoint_set_preferred_transport(ZMK_TRANSPORT_USB);
6666
case OUT_BLE:
67-
return zmk_endpoints_select_transport(ZMK_TRANSPORT_BLE);
67+
return zmk_endpoint_set_preferred_transport(ZMK_TRANSPORT_BLE);
6868
default:
6969
LOG_ERR("Unknown output command: %d", binding->param1);
7070
}

app/src/display/widgets/output_status.c

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,25 +22,43 @@ static sys_slist_t widgets = SYS_SLIST_STATIC_INIT(&widgets);
2222

2323
struct output_status_state {
2424
struct zmk_endpoint_instance selected_endpoint;
25+
enum zmk_transport preferred_transport;
2526
bool active_profile_connected;
2627
bool active_profile_bonded;
2728
};
2829

2930
static struct output_status_state get_state(const zmk_event_t *_eh) {
30-
return (struct output_status_state){.selected_endpoint = zmk_endpoints_selected(),
31-
.active_profile_connected =
32-
zmk_ble_active_profile_is_connected(),
33-
.active_profile_bonded = !zmk_ble_active_profile_is_open()};
34-
;
31+
return (struct output_status_state){
32+
.selected_endpoint = zmk_endpoint_get_selected(),
33+
.preferred_transport = zmk_endpoint_get_preferred_transport(),
34+
.active_profile_connected = zmk_ble_active_profile_is_connected(),
35+
.active_profile_bonded = !zmk_ble_active_profile_is_open(),
36+
};
3537
}
3638

3739
static void set_status_symbol(lv_obj_t *label, struct output_status_state state) {
3840
char text[20] = {};
3941

40-
switch (state.selected_endpoint.transport) {
42+
enum zmk_transport transport = state.selected_endpoint.transport;
43+
bool connected = transport != ZMK_TRANSPORT_NONE;
44+
45+
// If we aren't connected, show what we're *trying* to connect to.
46+
if (!connected) {
47+
transport = state.preferred_transport;
48+
}
49+
50+
switch (transport) {
51+
case ZMK_TRANSPORT_NONE:
52+
strcat(text, LV_SYMBOL_CLOSE);
53+
break;
54+
4155
case ZMK_TRANSPORT_USB:
4256
strcat(text, LV_SYMBOL_USB);
57+
if (!connected) {
58+
strcat(text, " " LV_SYMBOL_CLOSE);
59+
}
4360
break;
61+
4462
case ZMK_TRANSPORT_BLE:
4563
if (state.active_profile_bonded) {
4664
if (state.active_profile_connected) {

0 commit comments

Comments
 (0)