diff options
author | Aidan MacDonald <amachronic@protonmail.com> | 2022-04-03 13:48:52 +0100 |
---|---|---|
committer | Aidan MacDonald <amachronic@protonmail.com> | 2022-09-25 11:05:59 +0100 |
commit | e4aec7d648de2553653b378518b5e90f29aeeac3 (patch) | |
tree | 37c1f0f542742032573d1a99cc4b68c061fedb10 /apps | |
parent | f47aa584a8b447d8225fc5b09afb2d1fe6764c1d (diff) | |
download | rockbox-e4aec7d648de2553653b378518b5e90f29aeeac3.tar.gz rockbox-e4aec7d648de2553653b378518b5e90f29aeeac3.zip |
key remap: simplify and use movable allocations
Have action.c control the key remap buflib allocation so that it can
be made movable. With memory management offloaded, core_keymap.c only
needs to deal with loading keymap files. Simplify the code there and
use buflib pinning so the file can be loaded directly into the buffer.
Change-Id: Ia654cc05ce6b286f96c1031fa4f7d4b3859a2c1a
Diffstat (limited to 'apps')
-rw-r--r-- | apps/action.c | 121 | ||||
-rw-r--r-- | apps/action.h | 6 | ||||
-rw-r--r-- | apps/core_keymap.c | 134 | ||||
-rw-r--r-- | apps/core_keymap.h | 7 |
4 files changed, 117 insertions, 151 deletions
diff --git a/apps/action.c b/apps/action.c index 9ef10936f2..da08e29dbb 100644 --- a/apps/action.c +++ b/apps/action.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "button.h" | 34 | #include "button.h" |
35 | #include "action.h" | 35 | #include "action.h" |
36 | #include "kernel.h" | 36 | #include "kernel.h" |
37 | #include "core_alloc.h" | ||
37 | 38 | ||
38 | #include "splash.h" | 39 | #include "splash.h" |
39 | #include "settings.h" | 40 | #include "settings.h" |
@@ -70,7 +71,7 @@ static action_last_t action_last = | |||
70 | .wait_for_release = false, | 71 | .wait_for_release = false, |
71 | 72 | ||
72 | #ifndef DISABLE_ACTION_REMAP | 73 | #ifndef DISABLE_ACTION_REMAP |
73 | .core_keymap = NULL, | 74 | .key_remap = 0, |
74 | #endif | 75 | #endif |
75 | 76 | ||
76 | #ifdef HAVE_TOUCHSCREEN | 77 | #ifdef HAVE_TOUCHSCREEN |
@@ -601,9 +602,8 @@ static inline void action_code_lookup(action_last_t *last, action_cur_t *cur) | |||
601 | #endif | 602 | #endif |
602 | 603 | ||
603 | #ifndef DISABLE_ACTION_REMAP | 604 | #ifndef DISABLE_ACTION_REMAP |
604 | bool check_remap = (last->core_keymap != NULL); | ||
605 | /* attempt to look up the button in user supplied remap */ | 605 | /* attempt to look up the button in user supplied remap */ |
606 | if(check_remap && (context & CONTEXT_PLUGIN) == 0) | 606 | if(last->key_remap && (context & CONTEXT_PLUGIN) == 0) |
607 | { | 607 | { |
608 | #if 0 /*Disable the REMOTE context for remap for now (BUTTON_REMOTE != 0)*/ | 608 | #if 0 /*Disable the REMOTE context for remap for now (BUTTON_REMOTE != 0)*/ |
609 | if ((cur->button & BUTTON_REMOTE) != 0) | 609 | if ((cur->button & BUTTON_REMOTE) != 0) |
@@ -611,7 +611,7 @@ static inline void action_code_lookup(action_last_t *last, action_cur_t *cur) | |||
611 | context |= CONTEXT_REMOTE; | 611 | context |= CONTEXT_REMOTE; |
612 | } | 612 | } |
613 | #endif | 613 | #endif |
614 | cur->items = last->core_keymap; | 614 | cur->items = core_get_data(last->key_remap); |
615 | i = 0; | 615 | i = 0; |
616 | action = ACTION_UNKNOWN; | 616 | action = ACTION_UNKNOWN; |
617 | /* check the lut at the beginning for the desired context */ | 617 | /* check the lut at the beginning for the desired context */ |
@@ -1193,66 +1193,89 @@ int get_action(int context, int timeout) | |||
1193 | 1193 | ||
1194 | int action_set_keymap(struct button_mapping* core_keymap, int count) | 1194 | int action_set_keymap(struct button_mapping* core_keymap, int count) |
1195 | { | 1195 | { |
1196 | #ifdef DISABLE_ACTION_REMAP | ||
1197 | (void)core_keymap; | ||
1198 | (void)count; | ||
1199 | return -1; | ||
1200 | #else | ||
1201 | if (count <= 0 || core_keymap == NULL) | ||
1202 | return action_set_keymap_handle(0, 0); | ||
1203 | |||
1204 | size_t keyremap_buf_size = count * sizeof(struct button_mapping); | ||
1205 | int handle = core_alloc("keyremap", keyremap_buf_size); | ||
1206 | if (handle < 0) | ||
1207 | return -6; | ||
1196 | 1208 | ||
1209 | memcpy(core_get_data(handle), core_keymap, keyremap_buf_size); | ||
1210 | return action_set_keymap_handle(handle, count); | ||
1211 | #endif | ||
1212 | } | ||
1213 | |||
1214 | int action_set_keymap_handle(int handle, int count) | ||
1215 | { | ||
1197 | #ifdef DISABLE_ACTION_REMAP | 1216 | #ifdef DISABLE_ACTION_REMAP |
1198 | count = -1; | 1217 | (void)core_keymap; |
1218 | (void)count; | ||
1219 | return -1; | ||
1199 | #else | 1220 | #else |
1200 | if (count > 0 && core_keymap != NULL) /* saf-tey checks :) */ | 1221 | /* free an existing remap */ |
1222 | if (action_last.key_remap > 0) | ||
1223 | action_last.key_remap = core_free(action_last.key_remap); | ||
1224 | |||
1225 | /* if clearing the remap, we're done */ | ||
1226 | if (count <= 0 || handle <= 0) | ||
1227 | return 0; | ||
1228 | |||
1229 | /* validate the keymap */ | ||
1230 | struct button_mapping* core_keymap = core_get_data(handle); | ||
1231 | struct button_mapping* entry = &core_keymap[count - 1]; | ||
1232 | if (entry->action_code != (int) CONTEXT_STOPSEARCHING || | ||
1233 | entry->button_code != BUTTON_NONE) /* check for sentinel at end*/ | ||
1201 | { | 1234 | { |
1202 | int i = 0; | 1235 | /* missing sentinel entry */ |
1203 | struct button_mapping* entry = &core_keymap[count - 1]; | 1236 | return -1; |
1204 | if (entry->action_code != (int) CONTEXT_STOPSEARCHING || | 1237 | } |
1205 | entry->button_code != BUTTON_NONE) /* check for sentinel at end*/ | ||
1206 | { | ||
1207 | count = -1; | ||
1208 | } | ||
1209 | 1238 | ||
1210 | while (count > 0 && /* check the lut at the beginning for invalid offsets */ | 1239 | /* check the lut at the beginning for invalid offsets */ |
1211 | (entry = &core_keymap[i])->action_code != (int) CONTEXT_STOPSEARCHING) | 1240 | for (int i = 0; i < count; ++i) |
1212 | { | 1241 | { |
1213 | 1242 | entry = &core_keymap[i]; | |
1214 | if ((entry->action_code & CONTEXT_REMAPPED) == CONTEXT_REMAPPED) | 1243 | if (entry->action_code == (int)CONTEXT_STOPSEARCHING) |
1215 | { | 1244 | break; |
1216 | int firstbtn = entry->button_code; | ||
1217 | int endpos = firstbtn + entry->pre_button_code; | ||
1218 | if (firstbtn > count || firstbtn < i || endpos > count) | ||
1219 | { | ||
1220 | /* offset out of bounds */ | ||
1221 | count = -2; | ||
1222 | break; | ||
1223 | } | ||
1224 | 1245 | ||
1225 | if (core_keymap[endpos].button_code != BUTTON_NONE) | 1246 | if ((entry->action_code & CONTEXT_REMAPPED) == CONTEXT_REMAPPED) |
1226 | { | 1247 | { |
1227 | /* stop sentinel is not at end of action lut*/ | 1248 | int firstbtn = entry->button_code; |
1228 | count = -3; | 1249 | int endpos = firstbtn + entry->pre_button_code; |
1229 | } | 1250 | if (firstbtn > count || firstbtn < i || endpos > count) |
1230 | } | ||
1231 | else /* something other than a context remap in the lut */ | ||
1232 | { | 1251 | { |
1233 | count = -4; | 1252 | /* offset out of bounds */ |
1234 | break; | 1253 | return -2; |
1235 | } | 1254 | } |
1236 | 1255 | ||
1237 | i++; | 1256 | if (core_keymap[endpos].button_code != BUTTON_NONE) |
1238 | |||
1239 | if (i >= count) /* no sentinel in the lut */ | ||
1240 | { | 1257 | { |
1241 | count = -5; | 1258 | /* stop sentinel is not at end of action lut */ |
1242 | break; | 1259 | return -3; |
1243 | } | 1260 | } |
1244 | } | 1261 | } |
1262 | else | ||
1263 | { | ||
1264 | /* something other than a context remap in the lut */ | ||
1265 | return -4; | ||
1266 | } | ||
1245 | 1267 | ||
1246 | if (count <= 0) | 1268 | if (i+1 >= count) |
1247 | core_keymap = NULL; | 1269 | { |
1248 | } | 1270 | /* no sentinel in the lut */ |
1249 | else | 1271 | return -5; |
1250 | #endif | 1272 | } |
1251 | { | ||
1252 | core_keymap = NULL; | ||
1253 | } | 1273 | } |
1254 | action_last.core_keymap = core_keymap; | 1274 | |
1275 | /* success */ | ||
1276 | action_last.key_remap = handle; | ||
1255 | return count; | 1277 | return count; |
1278 | #endif | ||
1256 | } | 1279 | } |
1257 | 1280 | ||
1258 | int get_custom_action(int context,int timeout, | 1281 | int get_custom_action(int context,int timeout, |
diff --git a/apps/action.h b/apps/action.h index 35f08a3dbd..444437edf8 100644 --- a/apps/action.h +++ b/apps/action.h | |||
@@ -419,7 +419,7 @@ typedef struct | |||
419 | bool wait_for_release; | 419 | bool wait_for_release; |
420 | 420 | ||
421 | #ifndef DISABLE_ACTION_REMAP | 421 | #ifndef DISABLE_ACTION_REMAP |
422 | struct button_mapping* core_keymap; | 422 | int key_remap; |
423 | #endif | 423 | #endif |
424 | 424 | ||
425 | #ifdef HAVE_TOUCHSCREEN | 425 | #ifdef HAVE_TOUCHSCREEN |
@@ -449,7 +449,9 @@ bool action_userabort(int timeout); | |||
449 | const struct button_mapping* get_context_mapping(int context); | 449 | const struct button_mapping* get_context_mapping(int context); |
450 | 450 | ||
451 | /* load a key map to allow buttons for actions to be remapped see: core_keymap */ | 451 | /* load a key map to allow buttons for actions to be remapped see: core_keymap */ |
452 | int action_set_keymap(struct button_mapping* core_button_map, int count); | 452 | int action_set_keymap(struct button_mapping* core_keymap, int count); |
453 | /* load keymap in a handle: takes ownership of the handle on success */ | ||
454 | int action_set_keymap_handle(int handle, int count); | ||
453 | 455 | ||
454 | /* returns the status code variable from action.c for the button just pressed | 456 | /* returns the status code variable from action.c for the button just pressed |
455 | If button != NULL it will be set to the actual button code */ | 457 | If button != NULL it will be set to the actual button code */ |
diff --git a/apps/core_keymap.c b/apps/core_keymap.c index dbe7ae0072..9d54fcffac 100644 --- a/apps/core_keymap.c +++ b/apps/core_keymap.c | |||
@@ -27,119 +27,67 @@ | |||
27 | #include "logf.h" | 27 | #include "logf.h" |
28 | 28 | ||
29 | #if !defined(__PCTOOL__) || defined(CHECKWPS) | 29 | #if !defined(__PCTOOL__) || defined(CHECKWPS) |
30 | static int keymap_handle = -1; | 30 | int core_set_keyremap(struct button_mapping* core_keymap, int count) |
31 | |||
32 | static int core_alloc_keymap(size_t bufsz) | ||
33 | { | 31 | { |
34 | keymap_handle = core_alloc_ex("key remap", bufsz, &buflib_ops_locked); | 32 | return action_set_keymap(core_keymap, count); |
35 | return keymap_handle; | ||
36 | } | 33 | } |
37 | 34 | ||
38 | static void core_free_keymap(void) | 35 | static int open_key_remap(const char *filename, int *countp) |
39 | { | 36 | { |
40 | action_set_keymap(NULL, -1); | 37 | int fd = open(filename, O_RDONLY); |
41 | if (keymap_handle > 0) /* free old buffer */ | 38 | if (fd < 0) |
39 | return fd; | ||
40 | |||
41 | size_t fsize = filesize(fd); | ||
42 | int count = fsize / sizeof(struct button_mapping); | ||
43 | if (count == 0 || (size_t)(count * sizeof(struct button_mapping)) != fsize) | ||
42 | { | 44 | { |
43 | keymap_handle = core_free(keymap_handle); | 45 | logf("core_keyremap: bad filesize %d / %lu", count, (unsigned long)fsize); |
46 | goto error; | ||
44 | } | 47 | } |
45 | } | ||
46 | |||
47 | /* Allocates buffer from core and copies keymap into it */ | ||
48 | int core_set_keyremap(struct button_mapping* core_keymap, int count) | ||
49 | { | ||
50 | 48 | ||
51 | core_free_keymap(); | 49 | struct button_mapping header; |
52 | if (count > 0) | 50 | if(read(fd, &header, sizeof(header)) != (ssize_t)sizeof(header)) |
53 | { | 51 | { |
54 | size_t bufsize = count * sizeof(struct button_mapping); | 52 | logf("core_keyremap: read error"); |
55 | if (core_keymap != NULL && core_alloc_keymap(bufsize) > 0) | 53 | goto error; |
56 | { | ||
57 | char *buf = core_get_data(keymap_handle); | ||
58 | memcpy(buf, core_keymap, bufsize); | ||
59 | count = action_set_keymap((struct button_mapping *) buf, count); | ||
60 | } | ||
61 | else | ||
62 | count = -1; | ||
63 | } | 54 | } |
64 | return count; | ||
65 | } | ||
66 | |||
67 | int core_load_key_remap(const char *filename) | ||
68 | { | ||
69 | char *buf; | ||
70 | int fd = -1; | ||
71 | int count = 0; | ||
72 | size_t fsize = 0; | ||
73 | core_free_keymap(); | ||
74 | 55 | ||
75 | if (filename != NULL) | 56 | if (header.action_code != KEYREMAP_VERSION || |
76 | count = open_key_remap(filename, &fd, &fsize); | 57 | header.button_code != KEYREMAP_HEADERID || |
77 | while (count > 0) | 58 | header.pre_button_code != count) |
78 | { | 59 | { |
79 | if (core_alloc_keymap(fsize) <= 0) | 60 | logf("core_keyremap: bad header %d", count); |
80 | { | 61 | goto error; |
81 | count = -30; | ||
82 | logf("core_keymap: %d Failed to allocate buffer", count); | ||
83 | break; | ||
84 | } | ||
85 | buf = core_get_data(keymap_handle); | ||
86 | if (read(fd, buf, fsize) == (ssize_t) fsize) | ||
87 | { | ||
88 | count = action_set_keymap((struct button_mapping *) buf, count); | ||
89 | } | ||
90 | else | ||
91 | { | ||
92 | count = -40; | ||
93 | logf("core_keymap: %d Failed to read", count); | ||
94 | } | ||
95 | break; | ||
96 | } | 62 | } |
63 | |||
64 | *countp = count - 1; | ||
65 | return fd; | ||
66 | |||
67 | error: | ||
97 | close(fd); | 68 | close(fd); |
98 | return count; | 69 | return -1; |
99 | } | 70 | } |
100 | 71 | ||
101 | int open_key_remap(const char *filename, int *fd, size_t *fsize) | 72 | int core_load_key_remap(const char *filename) |
102 | { | 73 | { |
103 | int count = 0; | 74 | int count = 0; /* gcc falsely believes this may be used uninitialized */ |
75 | int fd = open_key_remap(filename, &count); | ||
76 | if (fd < 0) | ||
77 | return -1; | ||
104 | 78 | ||
105 | while (filename && fd && fsize) | 79 | size_t bufsize = count * sizeof(struct button_mapping); |
80 | int handle = core_alloc("keyremap", bufsize); | ||
81 | if (handle > 0) | ||
106 | { | 82 | { |
107 | *fsize = 0; | 83 | core_pin(handle); |
108 | *fd = open(filename, O_RDONLY); | 84 | if (read(fd, core_get_data(handle), bufsize) == (ssize_t)bufsize) |
109 | if (*fd) | 85 | count = action_set_keymap_handle(handle, count); |
110 | { | ||
111 | *fsize = filesize(*fd); | ||
112 | |||
113 | count = *fsize / sizeof(struct button_mapping); | ||
114 | |||
115 | if (count * sizeof(struct button_mapping) != *fsize) | ||
116 | { | ||
117 | count = -10; | ||
118 | logf("core_keymap: %d Size mismatch", count); | ||
119 | break; | ||
120 | } | ||
121 | 86 | ||
122 | if (count > 1) | 87 | core_unpin(handle); |
123 | { | ||
124 | struct button_mapping header = {0}; | ||
125 | read(*fd, &header, sizeof(struct button_mapping)); | ||
126 | if (KEYREMAP_VERSION == header.action_code && | ||
127 | KEYREMAP_HEADERID == header.button_code && | ||
128 | header.pre_button_code == count) | ||
129 | { | ||
130 | count--; | ||
131 | *fsize -= sizeof(struct button_mapping); | ||
132 | } | ||
133 | else /* Header mismatch */ | ||
134 | { | ||
135 | count = -20; | ||
136 | logf("core_keymap: %d Header mismatch", count); | ||
137 | break; | ||
138 | } | ||
139 | } | ||
140 | } | ||
141 | break; | ||
142 | } | 88 | } |
89 | |||
90 | close(fd); | ||
143 | return count; | 91 | return count; |
144 | } | 92 | } |
145 | 93 | ||
diff --git a/apps/core_keymap.h b/apps/core_keymap.h index dad9875364..2077daa685 100644 --- a/apps/core_keymap.h +++ b/apps/core_keymap.h | |||
@@ -34,13 +34,6 @@ | |||
34 | /* Allocates core buffer, copies keymap to allow buttons for actions to be remapped*/ | 34 | /* Allocates core buffer, copies keymap to allow buttons for actions to be remapped*/ |
35 | int core_set_keyremap(struct button_mapping* core_keymap, int count); | 35 | int core_set_keyremap(struct button_mapping* core_keymap, int count); |
36 | 36 | ||
37 | /* open_key_remap(filename , *fd (you must close file_descriptor), *fsize) | ||
38 | * checks/strips header and returns remaining count | ||
39 | * fd is opened and set to first record | ||
40 | * filesize contains the size of the remaining records | ||
41 | */ | ||
42 | int open_key_remap(const char *filename, int *fd, size_t *filesize); | ||
43 | |||
44 | /* load a remap file to allow buttons for actions to be remapped */ | 37 | /* load a remap file to allow buttons for actions to be remapped */ |
45 | int core_load_key_remap(const char *filename); | 38 | int core_load_key_remap(const char *filename); |
46 | 39 | ||