diff options
author | William Wilgus <wilgus.william@gmail.com> | 2021-04-02 21:34:29 -0400 |
---|---|---|
committer | William Wilgus <wilgus.william@gmail.com> | 2022-02-23 08:47:12 -0500 |
commit | f7bb9e21672566308ab837c370f27c10c154e6fc (patch) | |
tree | 688aa4e1a44572452ee192838b0af510b57ce770 /apps/action.c | |
parent | 7952687185aa27fcecc0924efa45c0e64e0ed4fe (diff) | |
download | rockbox-f7bb9e21672566308ab837c370f27c10c154e6fc.tar.gz rockbox-f7bb9e21672566308ab837c370f27c10c154e6fc.zip |
Add custom action mapping to core
results of an idea I discussed in IRC
changed the way the lookup in the remap file works..
entries consist of 3 int [action, button, prebtn]
context look up table is at the beginning
action_code contains the (context | CONTEXT_REMAPPED)
button_code contains the index of the first remapped action for the matched context
[0] CORE_CONTEXT_REMAP(ctx1) offset1=(3), count=(1)
[1] CORE_CONTEXT_REMAP(ctx2, offset2=(5), count=(1)
[2] sentinel, 0, 0
[3] act0, btn, 0
[4] sentinel 0, 0
[5] act1, btn, 0
[6] sentinel, 0, 0
Note:
last entry of each group is always the sentinel [CONTEXT_STOPSEARCHING, BUTTON_NONE, BUTTON_NONE]
contexts must match exactly -- re-mapped contexts run before the built in w/ fall through contexts
ie. you can't remap std_context and expect it to match std_context actions from the WPS context.
-- Done --
Code for reading core remap entries
-- Done --
import of core remap entires from disk
-- Done --
plugin to set new key mapping (the hard part)
The plugin is started and FULLY functional
you can add actions and contexts
you can change context, action, button, prebtn
delete keymap files
load keymapfiles
save user keymaps
test keymaps before applying them
loading keymaps to core still requires restart
-----------------------------------------------------------------------------------------------
Change-Id: Ib8b88c5ae91af4d540e1829de5db32669cd68203
Diffstat (limited to 'apps/action.c')
-rw-r--r-- | apps/action.c | 104 |
1 files changed, 102 insertions, 2 deletions
diff --git a/apps/action.c b/apps/action.c index b31c4fa927..3a4cc2ff64 100644 --- a/apps/action.c +++ b/apps/action.c | |||
@@ -69,6 +69,11 @@ static action_last_t action_last = | |||
69 | .tick = 0, | 69 | .tick = 0, |
70 | .wait_for_release = false, | 70 | .wait_for_release = false, |
71 | 71 | ||
72 | #ifndef DISABLE_ACTION_REMAP | ||
73 | .check_remap = false, | ||
74 | .core_keymap = NULL, | ||
75 | #endif | ||
76 | |||
72 | #ifdef HAVE_TOUCHSCREEN | 77 | #ifdef HAVE_TOUCHSCREEN |
73 | .ts_data = 0, | 78 | .ts_data = 0, |
74 | .ts_short_press = false, | 79 | .ts_short_press = false, |
@@ -499,7 +504,7 @@ static inline int action_code_worker(action_last_t *last, | |||
499 | int *end ) | 504 | int *end ) |
500 | { | 505 | { |
501 | int ret = ACTION_UNKNOWN; | 506 | int ret = ACTION_UNKNOWN; |
502 | int i = 0; | 507 | int i = *end; |
503 | unsigned int found = 0; | 508 | unsigned int found = 0; |
504 | while (cur->items[i].button_code != BUTTON_NONE) | 509 | while (cur->items[i].button_code != BUTTON_NONE) |
505 | { | 510 | { |
@@ -588,7 +593,9 @@ static inline void action_code_lookup(action_last_t *last, action_cur_t *cur) | |||
588 | int action = ACTION_NONE; | 593 | int action = ACTION_NONE; |
589 | int context = cur->context; | 594 | int context = cur->context; |
590 | int i = 0; | 595 | int i = 0; |
591 | 596 | #ifndef DISABLE_ACTION_REMAP | |
597 | last->check_remap = (last->core_keymap != NULL); | ||
598 | #endif | ||
592 | cur->is_prebutton = false; | 599 | cur->is_prebutton = false; |
593 | 600 | ||
594 | #ifdef HAVE_LOCKED_ACTIONS | 601 | #ifdef HAVE_LOCKED_ACTIONS |
@@ -609,9 +616,42 @@ static inline void action_code_lookup(action_last_t *last, action_cur_t *cur) | |||
609 | #endif | 616 | #endif |
610 | 617 | ||
611 | if ((context & CONTEXT_PLUGIN) && cur->get_context_map) | 618 | if ((context & CONTEXT_PLUGIN) && cur->get_context_map) |
619 | { | ||
612 | cur->items = cur->get_context_map(context); | 620 | cur->items = cur->get_context_map(context); |
621 | } | ||
622 | #ifndef DISABLE_ACTION_REMAP | ||
623 | else if(last->check_remap) /* attempt to look up the button in user supplied remap */ | ||
624 | { | ||
625 | cur->items = last->core_keymap; | ||
626 | i = 0; | ||
627 | action = ACTION_UNKNOWN; | ||
628 | /* check the lut at the beginning for the desired context */ | ||
629 | while (cur->items[i].action_code != (int) CONTEXT_STOPSEARCHING) | ||
630 | { | ||
631 | if (cur->items[i].action_code == CORE_CONTEXT_REMAP(context)) | ||
632 | { | ||
633 | i = cur->items[i].button_code; | ||
634 | action = action_code_worker(last, cur, &i); | ||
635 | break; | ||
636 | } | ||
637 | i++; | ||
638 | } | ||
639 | |||
640 | if (action != ACTION_UNKNOWN) | ||
641 | break; | ||
642 | else | ||
643 | { | ||
644 | /* Not found -- fall through to inbuilt keymaps */ | ||
645 | i = 0; | ||
646 | last->check_remap = false; | ||
647 | cur->items = get_context_mapping(context); | ||
648 | } | ||
649 | } | ||
650 | #endif | ||
613 | else | 651 | else |
652 | { | ||
614 | cur->items = get_context_mapping(context); | 653 | cur->items = get_context_mapping(context); |
654 | } | ||
615 | 655 | ||
616 | if (cur->items != NULL) | 656 | if (cur->items != NULL) |
617 | { | 657 | { |
@@ -1150,6 +1190,66 @@ int get_action(int context, int timeout) | |||
1150 | return action; | 1190 | return action; |
1151 | } | 1191 | } |
1152 | 1192 | ||
1193 | int action_set_keymap(struct button_mapping* core_keymap, int count) | ||
1194 | { | ||
1195 | |||
1196 | #ifdef DISABLE_ACTION_REMAP | ||
1197 | count = -1; | ||
1198 | #else | ||
1199 | if (count > 0 && core_keymap != NULL) /* saf-tey checks :) */ | ||
1200 | { | ||
1201 | int i = 0; | ||
1202 | if (core_keymap[count - 1].action_code != (int) CONTEXT_STOPSEARCHING || | ||
1203 | core_keymap[count - 1].button_code != BUTTON_NONE) /* check for sentinel at end*/ | ||
1204 | count = -1; | ||
1205 | |||
1206 | /* check the lut at the beginning for invalid offsets */ | ||
1207 | while (count > 0 && core_keymap[i].action_code != (int) CONTEXT_STOPSEARCHING) | ||
1208 | { | ||
1209 | if ((core_keymap[i].action_code & CONTEXT_REMAPPED) == CONTEXT_REMAPPED) | ||
1210 | { | ||
1211 | int firstbtn = core_keymap[i].button_code; | ||
1212 | int endpos = firstbtn + core_keymap[i].pre_button_code; | ||
1213 | if (firstbtn > count || firstbtn < i || endpos > count) | ||
1214 | { | ||
1215 | /* offset out of bounds */ | ||
1216 | count = -2; | ||
1217 | break; | ||
1218 | } | ||
1219 | |||
1220 | if (core_keymap[endpos].action_code != (int) CONTEXT_STOPSEARCHING) | ||
1221 | { | ||
1222 | /* stop sentinel is not at end of action lut*/ | ||
1223 | count = -3; | ||
1224 | } | ||
1225 | } | ||
1226 | else /* something other than a context remap in the lut */ | ||
1227 | { | ||
1228 | count = -4; | ||
1229 | break; | ||
1230 | } | ||
1231 | |||
1232 | i++; | ||
1233 | |||
1234 | if (i >= count) /* no sentinel in the lut */ | ||
1235 | { | ||
1236 | count = -5; | ||
1237 | break; | ||
1238 | } | ||
1239 | } | ||
1240 | |||
1241 | if (count <= 0) | ||
1242 | core_keymap = NULL; | ||
1243 | } | ||
1244 | else | ||
1245 | #endif | ||
1246 | { | ||
1247 | core_keymap = NULL; | ||
1248 | } | ||
1249 | action_last.core_keymap = core_keymap; | ||
1250 | return count; | ||
1251 | } | ||
1252 | |||
1153 | int get_custom_action(int context,int timeout, | 1253 | int get_custom_action(int context,int timeout, |
1154 | const struct button_mapping* (*get_context_map)(int)) | 1254 | const struct button_mapping* (*get_context_map)(int)) |
1155 | { | 1255 | { |