From 295ec3790d191c41006d04b41db878dc1091b117 Mon Sep 17 00:00:00 2001 From: William Wilgus Date: Wed, 23 Feb 2022 21:26:37 -0500 Subject: [PATCH] Core Keyremap Allow setting keymap from plugin Allow setting and removing keyremap on the fly It was pretty annoying trying to work out a keyremap with a restart required to set the remap and was quite annoying when I was no longer able to navigate to the plugin or filebrowser due to setting the wrong remap now you can try out a keymap and if it doesn't work a restart will sort things out Change-Id: I848fb3bd759f9684ac2497324a371f92b7464f7b --- apps/core_keymap.c | 49 +++++++++++++++++++++++++++++++++-------- apps/core_keymap.h | 4 ++++ apps/plugin.c | 2 ++ apps/plugin.h | 1 + apps/plugins/keyremap.c | 35 ++++++++++++++++++++++++++++- 5 files changed, 81 insertions(+), 10 deletions(-) diff --git a/apps/core_keymap.c b/apps/core_keymap.c index 0a7241a9e0..131c48f45d 100644 --- a/apps/core_keymap.c +++ b/apps/core_keymap.c @@ -24,25 +24,56 @@ #include "core_keymap.h" #if !defined(__PCTOOL__) || defined(CHECKWPS) +static int keymap_handle = -1; + +static int core_alloc_keymap(size_t bufsz) +{ + keymap_handle = core_alloc_ex("key remap", bufsz, &buflib_ops_locked); + return keymap_handle; +} + +static void core_free_keymap(void) +{ + action_set_keymap(NULL, -1); + if (keymap_handle > 0) /* free old buffer */ + { + keymap_handle = core_free(keymap_handle); + } +} + +/* Allocates buffer from core and copies keymap into it */ +int core_set_keyremap(struct button_mapping* core_keymap, int count) +{ + + core_free_keymap(); + if (count > 0) + { + size_t bufsize = count * sizeof(struct button_mapping); + if (core_keymap != NULL && core_alloc_keymap(bufsize) > 0) + { + char *buf = core_get_data(keymap_handle); + memcpy(buf, core_keymap, bufsize); + count = action_set_keymap((struct button_mapping *) buf, count); + } + else + count = -1; + } + return count; +} + int core_load_key_remap(const char *filename) { - static int keymap_handle = -1; char *buf; int fd = -1; int count = 0; size_t fsize = 0; - if (keymap_handle > 0) /* free old buffer */ - { - action_set_keymap(NULL, -1); - keymap_handle = core_free(keymap_handle); - } + core_free_keymap(); + if (filename != NULL) count = open_key_remap(filename, &fd, &fsize); while (count > 0) { - - keymap_handle = core_alloc_ex("key remap", fsize, &buflib_ops_locked); - if (keymap_handle <= 0) + if (core_alloc_keymap(fsize) <= 0) { count = -30; break; diff --git a/apps/core_keymap.h b/apps/core_keymap.h index 39d35e9cd9..dad9875364 100644 --- a/apps/core_keymap.h +++ b/apps/core_keymap.h @@ -24,12 +24,16 @@ #include #include #include "config.h" +#include "action.h" #define KEYREMAP_VERSION 1 #define KEYREMAP_HEADERID (LAST_ACTION_PLACEHOLDER | (TARGET_ID << 8)) /* If exists remap file will be loaded at startup */ #define CORE_KEYREMAP_FILE ROCKBOX_DIR "/keyremap.kmf" +/* Allocates core buffer, copies keymap to allow buttons for actions to be remapped*/ +int core_set_keyremap(struct button_mapping* core_keymap, int count); + /* open_key_remap(filename , *fd (you must close file_descriptor), *fsize) * checks/strips header and returns remaining count * fd is opened and set to first record diff --git a/apps/plugin.c b/apps/plugin.c index 8434fea07d..670770dfc6 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -46,6 +46,7 @@ #include "pathfuncs.h" #include "load_code.h" #include "file.h" +#include "core_keymap.h" #if CONFIG_CHARGING #include "power.h" @@ -807,6 +808,7 @@ static const struct plugin_api rockbox_api = { battery_current, onplay_show_playlist_menu, queue_remove_from_head, + core_set_keyremap, }; static int plugin_buffer_handle; diff --git a/apps/plugin.h b/apps/plugin.h index 8ade3a05ac..de1077c9b4 100644 --- a/apps/plugin.h +++ b/apps/plugin.h @@ -934,6 +934,7 @@ struct plugin_api { int (*battery_current)(void); void (*onplay_show_playlist_menu)(const char* path, void (*playlist_insert_cb)); void (*queue_remove_from_head)(struct event_queue *q, long id); + int (*core_set_keyremap)(struct button_mapping* core_keymap, int count); }; /* plugin header */ diff --git a/apps/plugins/keyremap.c b/apps/plugins/keyremap.c index acd23172f0..593dc5a3b0 100644 --- a/apps/plugins/keyremap.c +++ b/apps/plugins/keyremap.c @@ -105,7 +105,9 @@ enum { M_SAVEKEYS, M_LOADKEYS, M_DELKEYS, + M_TMPCORE, M_SETCORE, + M_DELCORE, M_EXIT, M_LAST_MAINITEM, //MAIN MENU ITEM COUNT /*Menus not directly accessible from main menu*/ @@ -126,7 +128,9 @@ MENU_ITEM(M_RESETKEYS, "Reset Keymap", 1), MENU_ITEM(M_SAVEKEYS, "Save Keymap", 1), MENU_ITEM(M_LOADKEYS, "Load Keymaps", 1), MENU_ITEM(M_DELKEYS, "Delete Keymaps", 1), +MENU_ITEM(M_TMPCORE, "Temp Core Remap", 1), MENU_ITEM(M_SETCORE, "Set Core Remap", 1), +MENU_ITEM(M_DELCORE, "Delete Core Remap", 1), MENU_ITEM(M_EXIT, ID2P(LANG_MENU_QUIT), 0), MENU_ITEM(M_ACTIONS, "Actions", LAST_ACTION_PLACEHOLDER), MENU_ITEM(M_BUTTONS, "Buttons", -1), /* Set at runtime in plugin_start: */ @@ -878,6 +882,17 @@ int menu_action_root(int *action, int selected_item, bool* exit, struct gui_sync { keyset.view_lastcol = -1; } + else if (cur->menuid == MENU_ID(M_TMPCORE)) + { + int entry_count;/* (ctx_count + ctx_count + act_count + 1) */ + struct button_mapping *keymap = keyremap_create_temp(&entry_count); + if (rb->core_set_keyremap(keymap, entry_count) >= 0) + rb->splash(HZ *2, "Keymap Applied"); + else + rb->splash(HZ *2, "Error Applying"); + + goto default_handler; + } else if (cur->menuid == MENU_ID(M_SETCORE)) { if (rb->file_exists(CORE_KEYREMAP_FILE) && 0 == core_savecount++) @@ -887,7 +902,25 @@ int menu_action_root(int *action, int selected_item, bool* exit, struct gui_sync if (keyremap_save_current(CORE_KEYREMAP_FILE) == 0) rb->splash(HZ *2, "Error Saving"); else - rb->splash(HZ *2, "Saved, Restart Device"); + { + rb->splash(HZ *2, "Saved"); + int entry_count;/* (ctx_count + ctx_count + act_count + 1) */ + struct button_mapping *keymap = keyremap_create_temp(&entry_count); + rb->core_set_keyremap(keymap, entry_count); + } + goto default_handler; + } + else if (cur->menuid == MENU_ID(M_DELCORE)) + { + rb->core_set_keyremap(NULL, -1); + if (rb->file_exists(CORE_KEYREMAP_FILE)) + { + rb->rename(CORE_KEYREMAP_FILE, KMFDIR "/core_deleted" KMFEXT2); + rb->splash(HZ *2, "Removed"); + } + else + rb->splash(HZ *2, "Error Removing"); + goto default_handler; } else if (cur->menuid == MENU_ID(M_SAVEKEYS))