mirror of https://github.com/zmkfirmware/zmk.git
Initial work to refactor persistence outside of just keymaps.
This commit is contained in:
parent
cd27866c95
commit
bd2fc145c7
|
|
@ -6,4 +6,4 @@
|
|||
|
||||
#include <zephyr/linker/linker-defs.h>
|
||||
|
||||
ITERABLE_SECTION_ROM(zmk_rpc_subsystem_settings_reset, 4)
|
||||
ITERABLE_SECTION_ROM(zmk_rpc_subsystem_persistence, 4)
|
||||
|
|
@ -73,10 +73,10 @@ int zmk_keymap_set_layer_name(zmk_keymap_layer_id_t id, const char *name, size_t
|
|||
/**
|
||||
* @brief Check if there are any unsaved keymap changes.
|
||||
*
|
||||
* @retval 0 if there are no changes.
|
||||
* @retval 1 if there are changes.
|
||||
* @retval true if there are no changes.
|
||||
* @retval false if there are changes.
|
||||
*/
|
||||
int zmk_keymap_check_unsaved_changes(void);
|
||||
bool zmk_keymap_check_unsaved_changes(void);
|
||||
|
||||
int zmk_keymap_save_changes(void);
|
||||
int zmk_keymap_discard_changes(void);
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ size_t zmk_physical_layouts_get_list(struct zmk_physical_layout const *const **p
|
|||
int zmk_physical_layouts_select(uint8_t index);
|
||||
int zmk_physical_layouts_get_selected(void);
|
||||
|
||||
int zmk_physical_layouts_check_unsaved_selection(void);
|
||||
bool zmk_physical_layouts_check_unsaved_selection(void);
|
||||
int zmk_physical_layouts_save_selected(void);
|
||||
int zmk_physical_layouts_revert_selected(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -56,10 +56,16 @@ struct zmk_rpc_subsystem_handler {
|
|||
enum zmk_studio_rpc_handler_security security;
|
||||
};
|
||||
|
||||
typedef int (*zmk_rpc_subsystem_settings_reset_func)(void);
|
||||
typedef int (*zmk_rpc_subsystem_reset_settings_func_t)(void);
|
||||
typedef int (*zmk_rpc_subsystem_discard_changes_func_t)(void);
|
||||
typedef bool (*zmk_rpc_subsystem_check_unsaved_changes_func_t)(void);
|
||||
typedef int (*zmk_rpc_subsystem_save_changes_func_t)(void);
|
||||
|
||||
struct zmk_rpc_subsystem_settings_reset {
|
||||
zmk_rpc_subsystem_settings_reset_func callback;
|
||||
struct zmk_rpc_subsystem_persistence {
|
||||
zmk_rpc_subsystem_reset_settings_func_t reset_settings;
|
||||
zmk_rpc_subsystem_check_unsaved_changes_func_t check_unsaved_changes;
|
||||
zmk_rpc_subsystem_save_changes_func_t save_changes;
|
||||
zmk_rpc_subsystem_discard_changes_func_t discard_changes;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -109,13 +115,12 @@ struct zmk_rpc_subsystem_settings_reset {
|
|||
.security = _security, \
|
||||
};
|
||||
|
||||
#define ZMK_RPC_SUBSYSTEM_SETTINGS_RESET(prefix, _callback) \
|
||||
STRUCT_SECTION_ITERABLE(zmk_rpc_subsystem_settings_reset, _##prefix##_settings_reset) = { \
|
||||
.callback = _callback, \
|
||||
};
|
||||
#define ZMK_RPC_SUBSYSTEM_PERSISTENCE(prefix, ...) \
|
||||
STRUCT_SECTION_ITERABLE(zmk_rpc_subsystem_persistence, \
|
||||
_##prefix##_settings_reset) = {__VA_ARGS__};
|
||||
|
||||
#define ZMK_RPC_SUBSYSTEM_SETTINGS_RESET_FOREACH(_var) \
|
||||
STRUCT_SECTION_FOREACH(zmk_rpc_subsystem_settings_reset, _var)
|
||||
#define ZMK_RPC_SUBSYSTEM_PERSISTENCE_FOREACH(_var) \
|
||||
STRUCT_SECTION_FOREACH(zmk_rpc_subsystem_persistence, _var)
|
||||
|
||||
/**
|
||||
* @brief Create a zmk_studio_Notification struct for the given subsystem and type, including
|
||||
|
|
|
|||
|
|
@ -472,23 +472,23 @@ struct zmk_behavior_binding_setting {
|
|||
uint32_t param2;
|
||||
} __packed;
|
||||
|
||||
int zmk_keymap_check_unsaved_changes(void) {
|
||||
bool zmk_keymap_check_unsaved_changes(void) {
|
||||
for (int l = 0; l < ZMK_KEYMAP_LAYERS_LEN; l++) {
|
||||
uint8_t *pending = zmk_keymap_layer_pending_changes[l];
|
||||
for (int kp = 0; kp < ZMK_KEYMAP_LEN; kp++) {
|
||||
if (pending[kp / 8] & BIT(kp % 8)) {
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_KEYMAP_LAYER_REORDERING)
|
||||
if (settings_layer_orders[l] != keymap_layer_orders[l]) {
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_KEYMAP_LAYER_REORDERING)
|
||||
}
|
||||
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
#define LAYER_ORDER_SETTINGS_KEY "keymap/layer_order"
|
||||
|
|
|
|||
|
|
@ -416,14 +416,12 @@ int zmk_physical_layouts_select_initial(void) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
int zmk_physical_layouts_check_unsaved_selection(void) {
|
||||
bool zmk_physical_layouts_check_unsaved_selection(void) {
|
||||
#if IS_ENABLED(CONFIG_SETTINGS)
|
||||
return saved_selected_index < 0 ||
|
||||
saved_selected_index == (uint8_t)zmk_physical_layouts_get_selected()
|
||||
? 0
|
||||
: 1;
|
||||
return !(saved_selected_index < 0 ||
|
||||
saved_selected_index == (uint8_t)zmk_physical_layouts_get_selected());
|
||||
#else
|
||||
return -ENOTSUP;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
zephyr_linker_sources(DATA_SECTIONS ../../include/linker/zmk-rpc-subsystems.ld)
|
||||
zephyr_linker_sources(SECTIONS ../../include/linker/zmk-rpc-subsystem-handlers.ld)
|
||||
zephyr_linker_sources(SECTIONS ../../include/linker/zmk-rpc-subsystem-settings-reset.ld)
|
||||
zephyr_linker_sources(SECTIONS ../../include/linker/zmk-rpc-subsystem-persistence.ld)
|
||||
zephyr_linker_sources(SECTIONS ../../include/linker/zmk-rpc-event-mappers.ld)
|
||||
zephyr_linker_sources(SECTIONS ../../include/linker/zmk-rpc-transport.ld)
|
||||
|
||||
|
|
|
|||
|
|
@ -65,8 +65,8 @@ zmk_studio_Response get_lock_state(const zmk_studio_Request *req) {
|
|||
|
||||
zmk_studio_Response reset_settings(const zmk_studio_Request *req) {
|
||||
LOG_DBG("");
|
||||
ZMK_RPC_SUBSYSTEM_SETTINGS_RESET_FOREACH(sub) {
|
||||
int ret = sub->callback();
|
||||
ZMK_RPC_SUBSYSTEM_PERSISTENCE_FOREACH(sub) {
|
||||
int ret = sub->reset_settings();
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to reset settings: %d", ret);
|
||||
return CORE_RESPONSE(reset_settings, false);
|
||||
|
|
@ -76,9 +76,68 @@ zmk_studio_Response reset_settings(const zmk_studio_Request *req) {
|
|||
return CORE_RESPONSE(reset_settings, true);
|
||||
}
|
||||
|
||||
static zmk_studio_Response check_unsaved_changes(const zmk_studio_Request *req) {
|
||||
LOG_DBG("");
|
||||
bool unsaved = false;
|
||||
ZMK_RPC_SUBSYSTEM_PERSISTENCE_FOREACH(p) {
|
||||
unsaved = p->check_unsaved_changes();
|
||||
if (unsaved) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return CORE_RESPONSE(check_unsaved_changes, unsaved);
|
||||
}
|
||||
|
||||
static zmk_studio_Response save_changes(const zmk_studio_Request *req) {
|
||||
LOG_DBG("");
|
||||
|
||||
zmk_core_SaveChangesResponse resp = zmk_core_SaveChangesResponse_init_zero;
|
||||
resp.which_result = zmk_core_SaveChangesResponse_ok_tag;
|
||||
resp.result.ok = true;
|
||||
|
||||
ZMK_RPC_SUBSYSTEM_PERSISTENCE_FOREACH(p) {
|
||||
int ret = p->save_changes();
|
||||
if (ret < 0) {
|
||||
resp.which_result = zmk_core_SaveChangesResponse_err_tag;
|
||||
switch (ret) {
|
||||
case -ENOTSUP:
|
||||
resp.result.err = zmk_core_SaveChangesErrorCode_SAVE_CHANGES_ERR_NOT_SUPPORTED;
|
||||
break;
|
||||
case -ENOSPC:
|
||||
resp.result.err = zmk_core_SaveChangesErrorCode_SAVE_CHANGES_ERR_NO_SPACE;
|
||||
break;
|
||||
default:
|
||||
resp.result.err = zmk_core_SaveChangesErrorCode_SAVE_CHANGES_ERR_GENERIC;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return CORE_RESPONSE(save_changes, resp);
|
||||
}
|
||||
|
||||
static zmk_studio_Response discard_changes(const zmk_studio_Request *req) {
|
||||
LOG_DBG("");
|
||||
int ret = 0;
|
||||
ZMK_RPC_SUBSYSTEM_PERSISTENCE_FOREACH(p) {
|
||||
ret = p->discard_changes();
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to discard changes for subsystem %p: %d", p, ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return CORE_RESPONSE(discard_changes, ret >= 0);
|
||||
}
|
||||
|
||||
ZMK_RPC_SUBSYSTEM_HANDLER(core, get_device_info, ZMK_STUDIO_RPC_HANDLER_UNSECURED);
|
||||
ZMK_RPC_SUBSYSTEM_HANDLER(core, get_lock_state, ZMK_STUDIO_RPC_HANDLER_UNSECURED);
|
||||
ZMK_RPC_SUBSYSTEM_HANDLER(core, reset_settings, ZMK_STUDIO_RPC_HANDLER_SECURED);
|
||||
ZMK_RPC_SUBSYSTEM_HANDLER(core, check_unsaved_changes, ZMK_STUDIO_RPC_HANDLER_SECURED);
|
||||
ZMK_RPC_SUBSYSTEM_HANDLER(core, save_changes, ZMK_STUDIO_RPC_HANDLER_SECURED);
|
||||
ZMK_RPC_SUBSYSTEM_HANDLER(core, discard_changes, ZMK_STUDIO_RPC_HANDLER_SECURED);
|
||||
|
||||
static int core_event_mapper(const zmk_event_t *eh, zmk_studio_Notification *n) {
|
||||
struct zmk_studio_core_lock_state_changed *lock_ev = as_zmk_studio_core_lock_state_changed(eh);
|
||||
|
|
|
|||
|
|
@ -172,12 +172,15 @@ zmk_studio_Response set_layer_binding(const zmk_studio_Request *req) {
|
|||
zmk_keymap_SetLayerBindingResponse_SET_LAYER_BINDING_RESP_OK);
|
||||
}
|
||||
|
||||
static bool keymap_check_unsaved_changes(void) {
|
||||
return zmk_physical_layouts_check_unsaved_selection() || zmk_keymap_check_unsaved_changes();
|
||||
}
|
||||
|
||||
zmk_studio_Response check_unsaved_changes(const zmk_studio_Request *req) {
|
||||
LOG_DBG("");
|
||||
int layout_changes = zmk_physical_layouts_check_unsaved_selection();
|
||||
int keymap_changes = zmk_keymap_check_unsaved_changes();
|
||||
bool unsaved = keymap_check_unsaved_changes();
|
||||
|
||||
return KEYMAP_RESPONSE(check_unsaved_changes, layout_changes > 0 || keymap_changes > 0);
|
||||
return KEYMAP_RESPONSE(check_unsaved_changes, unsaved);
|
||||
}
|
||||
|
||||
static void map_errno_to_save_resp(int err, zmk_keymap_SaveChangesResponse *resp) {
|
||||
|
|
@ -196,23 +199,32 @@ static void map_errno_to_save_resp(int err, zmk_keymap_SaveChangesResponse *resp
|
|||
}
|
||||
}
|
||||
|
||||
static int keymap_subsys_save_changes(void) {
|
||||
int ret = zmk_physical_layouts_save_selected();
|
||||
|
||||
if (ret < 0) {
|
||||
LOG_WRN("Failed to save selected physical layout (%d)", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = zmk_keymap_save_changes();
|
||||
if (ret < 0) {
|
||||
LOG_WRN("Failed to save keymap changes (%d)", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
zmk_studio_Response save_changes(const zmk_studio_Request *req) {
|
||||
zmk_keymap_SaveChangesResponse resp = zmk_keymap_SaveChangesResponse_init_zero;
|
||||
resp.which_result = zmk_keymap_SaveChangesResponse_ok_tag;
|
||||
resp.result.ok = true;
|
||||
|
||||
LOG_DBG("");
|
||||
int ret = zmk_physical_layouts_save_selected();
|
||||
int ret = keymap_subsys_save_changes();
|
||||
|
||||
if (ret < 0) {
|
||||
LOG_WRN("Failed to save selected physical layout (%d)", ret);
|
||||
map_errno_to_save_resp(ret, &resp);
|
||||
return KEYMAP_RESPONSE(save_changes, resp);
|
||||
}
|
||||
|
||||
ret = zmk_keymap_save_changes();
|
||||
if (ret < 0) {
|
||||
LOG_WRN("Failed to save keymap changes (%d)", ret);
|
||||
map_errno_to_save_resp(ret, &resp);
|
||||
return KEYMAP_RESPONSE(save_changes, resp);
|
||||
}
|
||||
|
|
@ -223,14 +235,25 @@ zmk_studio_Response save_changes(const zmk_studio_Request *req) {
|
|||
return KEYMAP_RESPONSE(save_changes, resp);
|
||||
}
|
||||
|
||||
zmk_studio_Response discard_changes(const zmk_studio_Request *req) {
|
||||
LOG_DBG("");
|
||||
static int keymap_subsys_discard_changes(void) {
|
||||
int ret = zmk_physical_layouts_revert_selected();
|
||||
if (ret < 0) {
|
||||
return ZMK_RPC_SIMPLE_ERR(GENERIC);
|
||||
LOG_ERR("Failed to discard physical layout changes (%d)", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = zmk_keymap_discard_changes();
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to discard keymap changes (%d)", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
zmk_studio_Response discard_changes(const zmk_studio_Request *req) {
|
||||
LOG_DBG("");
|
||||
int ret = keymap_subsys_discard_changes();
|
||||
if (ret < 0) {
|
||||
return ZMK_RPC_SIMPLE_ERR(GENERIC);
|
||||
}
|
||||
|
|
@ -243,7 +266,10 @@ zmk_studio_Response discard_changes(const zmk_studio_Request *req) {
|
|||
|
||||
static int keymap_settings_reset(void) { return zmk_keymap_reset_settings(); }
|
||||
|
||||
ZMK_RPC_SUBSYSTEM_SETTINGS_RESET(keymap, keymap_settings_reset);
|
||||
ZMK_RPC_SUBSYSTEM_PERSISTENCE(keymap, .reset_settings = keymap_settings_reset,
|
||||
.check_unsaved_changes = keymap_check_unsaved_changes,
|
||||
.save_changes = keymap_subsys_save_changes,
|
||||
.discard_changes = keymap_subsys_discard_changes, );
|
||||
|
||||
static bool encode_layout_name(pb_ostream_t *stream, const pb_field_t *field, void *const *arg) {
|
||||
struct zmk_physical_layout *layout = (struct zmk_physical_layout *)*arg;
|
||||
|
|
|
|||
Loading…
Reference in New Issue