Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+117 -151
+72 -49
apps/action.c
··· 34 34 #include "button.h" 35 35 #include "action.h" 36 36 #include "kernel.h" 37 + #include "core_alloc.h" 37 38 38 39 #include "splash.h" 39 40 #include "settings.h" ··· 70 71 .wait_for_release = false, 71 72 72 73 #ifndef DISABLE_ACTION_REMAP 73 - .core_keymap = NULL, 74 + .key_remap = 0, 74 75 #endif 75 76 76 77 #ifdef HAVE_TOUCHSCREEN ··· 601 602 #endif 602 603 603 604 #ifndef DISABLE_ACTION_REMAP 604 - bool check_remap = (last->core_keymap != NULL); 605 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 608 #if 0 /*Disable the REMOTE context for remap for now (BUTTON_REMOTE != 0)*/ 609 609 if ((cur->button & BUTTON_REMOTE) != 0) ··· 611 611 context |= CONTEXT_REMOTE; 612 612 } 613 613 #endif 614 - cur->items = last->core_keymap; 614 + cur->items = core_get_data(last->key_remap); 615 615 i = 0; 616 616 action = ACTION_UNKNOWN; 617 617 /* check the lut at the beginning for the desired context */ ··· 1193 1193 1194 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); 1196 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; 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 1216 #ifdef DISABLE_ACTION_REMAP 1198 - count = -1; 1217 + (void)core_keymap; 1218 + (void)count; 1219 + return -1; 1199 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; 1203 - struct button_mapping* entry = &core_keymap[count - 1]; 1204 - if (entry->action_code != (int) CONTEXT_STOPSEARCHING || 1205 - entry->button_code != BUTTON_NONE) /* check for sentinel at end*/ 1206 - { 1207 - count = -1; 1208 - } 1235 + /* missing sentinel entry */ 1236 + return -1; 1237 + } 1238 + 1239 + /* check the lut at the beginning for invalid offsets */ 1240 + for (int i = 0; i < count; ++i) 1241 + { 1242 + entry = &core_keymap[i]; 1243 + if (entry->action_code == (int)CONTEXT_STOPSEARCHING) 1244 + break; 1209 1245 1210 - while (count > 0 && /* check the lut at the beginning for invalid offsets */ 1211 - (entry = &core_keymap[i])->action_code != (int) CONTEXT_STOPSEARCHING) 1246 + if ((entry->action_code & CONTEXT_REMAPPED) == CONTEXT_REMAPPED) 1212 1247 { 1213 - 1214 - if ((entry->action_code & CONTEXT_REMAPPED) == CONTEXT_REMAPPED) 1215 - { 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 - 1225 - if (core_keymap[endpos].button_code != BUTTON_NONE) 1226 - { 1227 - /* stop sentinel is not at end of action lut*/ 1228 - count = -3; 1229 - } 1230 - } 1231 - else /* something other than a context remap in the lut */ 1248 + int firstbtn = entry->button_code; 1249 + int endpos = firstbtn + entry->pre_button_code; 1250 + if (firstbtn > count || firstbtn < i || endpos > count) 1232 1251 { 1233 - count = -4; 1234 - break; 1252 + /* offset out of bounds */ 1253 + return -2; 1235 1254 } 1236 1255 1237 - i++; 1238 - 1239 - if (i >= count) /* no sentinel in the lut */ 1256 + if (core_keymap[endpos].button_code != BUTTON_NONE) 1240 1257 { 1241 - count = -5; 1242 - break; 1258 + /* stop sentinel is not at end of action lut */ 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) 1247 - core_keymap = NULL; 1268 + if (i+1 >= count) 1269 + { 1270 + /* no sentinel in the lut */ 1271 + return -5; 1272 + } 1248 1273 } 1249 - else 1274 + 1275 + /* success */ 1276 + action_last.key_remap = handle; 1277 + return count; 1250 1278 #endif 1251 - { 1252 - core_keymap = NULL; 1253 - } 1254 - action_last.core_keymap = core_keymap; 1255 - return count; 1256 1279 } 1257 1280 1258 1281 int get_custom_action(int context,int timeout,
+4 -2
apps/action.h
··· 419 419 bool wait_for_release; 420 420 421 421 #ifndef DISABLE_ACTION_REMAP 422 - struct button_mapping* core_keymap; 422 + int key_remap; 423 423 #endif 424 424 425 425 #ifdef HAVE_TOUCHSCREEN ··· 449 449 const struct button_mapping* get_context_mapping(int context); 450 450 451 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 456 /* returns the status code variable from action.c for the button just pressed 455 457 If button != NULL it will be set to the actual button code */
+41 -93
apps/core_keymap.c
··· 27 27 #include "logf.h" 28 28 29 29 #if !defined(__PCTOOL__) || defined(CHECKWPS) 30 - static int keymap_handle = -1; 31 - 32 - static int core_alloc_keymap(size_t bufsz) 30 + int core_set_keyremap(struct button_mapping* core_keymap, int count) 33 31 { 34 - keymap_handle = core_alloc_ex("key remap", bufsz, &buflib_ops_locked); 35 - return keymap_handle; 32 + return action_set_keymap(core_keymap, count); 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); 41 - if (keymap_handle > 0) /* free old buffer */ 37 + int fd = open(filename, O_RDONLY); 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 48 47 - /* Allocates buffer from core and copies keymap into it */ 48 - int core_set_keyremap(struct button_mapping* core_keymap, int count) 49 - { 50 - 51 - core_free_keymap(); 52 - if (count > 0) 49 + struct button_mapping header; 50 + if(read(fd, &header, sizeof(header)) != (ssize_t)sizeof(header)) 53 51 { 54 - size_t bufsize = count * sizeof(struct button_mapping); 55 - if (core_keymap != NULL && core_alloc_keymap(bufsize) > 0) 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; 52 + logf("core_keyremap: read error"); 53 + goto error; 63 54 } 64 - return count; 65 - } 66 55 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 - 75 - if (filename != NULL) 76 - count = open_key_remap(filename, &fd, &fsize); 77 - while (count > 0) 56 + if (header.action_code != KEYREMAP_VERSION || 57 + header.button_code != KEYREMAP_HEADERID || 58 + header.pre_button_code != count) 78 59 { 79 - if (core_alloc_keymap(fsize) <= 0) 80 - { 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; 60 + logf("core_keyremap: bad header %d", count); 61 + goto error; 96 62 } 63 + 64 + *countp = count - 1; 65 + return fd; 66 + 67 + error: 97 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; 108 - *fd = open(filename, O_RDONLY); 109 - if (*fd) 110 - { 111 - *fsize = filesize(*fd); 83 + core_pin(handle); 84 + if (read(fd, core_get_data(handle), bufsize) == (ssize_t)bufsize) 85 + count = action_set_keymap_handle(handle, count); 112 86 113 - count = *fsize / sizeof(struct button_mapping); 87 + core_unpin(handle); 88 + } 114 89 115 - if (count * sizeof(struct button_mapping) != *fsize) 116 - { 117 - count = -10; 118 - logf("core_keymap: %d Size mismatch", count); 119 - break; 120 - } 121 - 122 - if (count > 1) 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 - } 90 + close(fd); 143 91 return count; 144 92 } 145 93
-7
apps/core_keymap.h
··· 34 34 /* Allocates core buffer, copies keymap to allow buttons for actions to be remapped*/ 35 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 37 /* load a remap file to allow buttons for actions to be remapped */ 45 38 int core_load_key_remap(const char *filename); 46 39