diff options
Diffstat (limited to 'apps/plugins')
-rw-r--r-- | apps/plugins/keyremap.c | 111 |
1 files changed, 97 insertions, 14 deletions
diff --git a/apps/plugins/keyremap.c b/apps/plugins/keyremap.c index ccf446d279..cb19fcf92c 100644 --- a/apps/plugins/keyremap.c +++ b/apps/plugins/keyremap.c | |||
@@ -42,8 +42,29 @@ | |||
42 | #define KMFUSER "user_keyremap" | 42 | #define KMFUSER "user_keyremap" |
43 | #define MAX_BUTTON_COMBO 5 | 43 | #define MAX_BUTTON_COMBO 5 |
44 | #define MAX_BUTTON_NAME 32 | 44 | #define MAX_BUTTON_NAME 32 |
45 | #define MAX_MENU_NAME 64 | ||
45 | #define TEST_COUNTDOWN_MS 1590 | 46 | #define TEST_COUNTDOWN_MS 1590 |
46 | 47 | ||
48 | struct context_flags { | ||
49 | char * name; | ||
50 | int flag; | ||
51 | }; | ||
52 | |||
53 | /* flags added to context_name[] */ | ||
54 | static struct context_flags context_flags[] = { | ||
55 | {"UNKNOWN", 0},/* index 0 is an Error */ | ||
56 | #ifdef HAVE_LOCKED_ACTIONS | ||
57 | {"LOCKED", CONTEXT_LOCKED}, | ||
58 | #endif | ||
59 | /*{"PLUGIN", CONTEXT_PLUGIN}, need a custom action list and a way to supply */ | ||
60 | #if BUTTON_REMOTE != 0 | ||
61 | {"REMOTE", CONTEXT_REMOTE}, | ||
62 | #ifdef HAVE_LOCKED_ACTIONS | ||
63 | {"REMOTE_LOCKED", CONTEXT_REMOTE | CONTEXT_LOCKED}, | ||
64 | #endif | ||
65 | #endif /* BUTTON_REMOTE != 0 */ | ||
66 | }; | ||
67 | |||
47 | static struct keyremap_buffer_t { | 68 | static struct keyremap_buffer_t { |
48 | char * buffer; | 69 | char * buffer; |
49 | size_t buf_size; | 70 | size_t buf_size; |
@@ -138,7 +159,7 @@ MENU_ITEM(M_DELCORE, "Remove Core Remap", 1), | |||
138 | MENU_ITEM(M_EXIT, ID2P(LANG_MENU_QUIT), 0), | 159 | MENU_ITEM(M_EXIT, ID2P(LANG_MENU_QUIT), 0), |
139 | MENU_ITEM(M_ACTIONS, "Actions", LAST_ACTION_PLACEHOLDER), | 160 | MENU_ITEM(M_ACTIONS, "Actions", LAST_ACTION_PLACEHOLDER), |
140 | MENU_ITEM(M_BUTTONS, "Buttons", -1), /* Set at runtime in plugin_start: */ | 161 | MENU_ITEM(M_BUTTONS, "Buttons", -1), /* Set at runtime in plugin_start: */ |
141 | MENU_ITEM(M_CONTEXTS, "Contexts", LAST_CONTEXT_PLACEHOLDER ), | 162 | MENU_ITEM(M_CONTEXTS, "Contexts", LAST_CONTEXT_PLACEHOLDER * ARRAYLEN(context_flags)), |
142 | MENU_ITEM(M_CONTEXT_EDIT, "", 5), | 163 | MENU_ITEM(M_CONTEXT_EDIT, "", 5), |
143 | #undef MENU_ITEM | 164 | #undef MENU_ITEM |
144 | }; | 165 | }; |
@@ -200,6 +221,47 @@ static void synclist_set_update(int id, int selected_item, int items, int sel_si | |||
200 | synclist_set(id, selected_item, items, sel_size); | 221 | synclist_set(id, selected_item, items, sel_size); |
201 | } | 222 | } |
202 | 223 | ||
224 | /* returns the actual context & index of the flag is passed in *flagidx */ | ||
225 | static int ctx_strip_flagidx(int ctx, int *flagidx) | ||
226 | { | ||
227 | int ctx_out = ctx % (LAST_CONTEXT_PLACEHOLDER); | ||
228 | *flagidx = 0; | ||
229 | if (ctx_out != ctx) | ||
230 | { | ||
231 | while (ctx >= LAST_CONTEXT_PLACEHOLDER) | ||
232 | { | ||
233 | (*flagidx)++; | ||
234 | ctx -= LAST_CONTEXT_PLACEHOLDER; | ||
235 | } | ||
236 | if (*flagidx >= (int)ARRAYLEN(context_flags)) | ||
237 | *flagidx = 0; /* unknown flag */ | ||
238 | |||
239 | logf("%s ctx: (%d) %s flag idx: (%d) %s\n", __func__, | ||
240 | ctx, context_name(ctx), *flagidx, context_flags[*flagidx].name); | ||
241 | } | ||
242 | return ctx_out; | ||
243 | } | ||
244 | |||
245 | /* combines context name and flag name using '_' to join them */ | ||
246 | static char *ctx_name_and_flag(int index) | ||
247 | { | ||
248 | static char ctx_namebuf[MAX_MENU_NAME]; | ||
249 | char *ctx_name = "?"; | ||
250 | int flagidx; | ||
251 | int ctx = ctx_strip_flagidx(index, &flagidx); | ||
252 | if (flagidx == 0) | ||
253 | { | ||
254 | ctx_name = context_name(ctx); | ||
255 | } | ||
256 | else if (flagidx >= 0 && flagidx < (int)ARRAYLEN(context_flags)) | ||
257 | { | ||
258 | rb->snprintf(ctx_namebuf, sizeof(ctx_namebuf), "%s_%s", | ||
259 | context_name(ctx), context_flags[flagidx].name); | ||
260 | ctx_name = ctx_namebuf; | ||
261 | } | ||
262 | return ctx_name; | ||
263 | } | ||
264 | |||
203 | static int btnval_to_index(unsigned int btnvalue) | 265 | static int btnval_to_index(unsigned int btnvalue) |
204 | { | 266 | { |
205 | int index = -1; | 267 | int index = -1; |
@@ -361,6 +423,7 @@ static int keyremap_map_is_valid(struct action_mapping_t *amap, int context) | |||
361 | 423 | ||
362 | static struct button_mapping *keyremap_create_temp(int *entries) | 424 | static struct button_mapping *keyremap_create_temp(int *entries) |
363 | { | 425 | { |
426 | logf("%s()", __func__); | ||
364 | struct button_mapping *tempkeymap; | 427 | struct button_mapping *tempkeymap; |
365 | int action_offset = 1; /* start of action entries (ctx_count + 1)*/ | 428 | int action_offset = 1; /* start of action entries (ctx_count + 1)*/ |
366 | int entry_count = 1;/* (ctx_count + ctx_count + act_count) */ | 429 | int entry_count = 1;/* (ctx_count + ctx_count + act_count) */ |
@@ -390,7 +453,7 @@ static struct button_mapping *keyremap_create_temp(int *entries) | |||
390 | } | 453 | } |
391 | size_t keymap_bytes = (entry_count) * sizeof(struct button_mapping); | 454 | size_t keymap_bytes = (entry_count) * sizeof(struct button_mapping); |
392 | *entries = entry_count; | 455 | *entries = entry_count; |
393 | logf("keyremap create temp entry count: %d", entry_count); | 456 | logf("%s() entry count: %d", __func__, entry_count); |
394 | logf("keyremap bytes: %zu, avail: %zu", keymap_bytes, | 457 | logf("keyremap bytes: %zu, avail: %zu", keymap_bytes, |
395 | (keyremap_buffer.end - keyremap_buffer.front)); | 458 | (keyremap_buffer.end - keyremap_buffer.front)); |
396 | if (keyremap_buffer.front + keymap_bytes < keyremap_buffer.end) | 459 | if (keyremap_buffer.front + keymap_bytes < keyremap_buffer.end) |
@@ -401,6 +464,7 @@ static struct button_mapping *keyremap_create_temp(int *entries) | |||
401 | for (i = 0; i < ctx_data.ctx_count; i++) | 464 | for (i = 0; i < ctx_data.ctx_count; i++) |
402 | { | 465 | { |
403 | int actions_this_ctx = 0; | 466 | int actions_this_ctx = 0; |
467 | int flagidx; | ||
404 | int context = ctx_data.ctx_map[i].context; | 468 | int context = ctx_data.ctx_map[i].context; |
405 | /* how many actions are contained in each context? */ | 469 | /* how many actions are contained in each context? */ |
406 | for (j = 0; j < ctx_data.act_count; j++) | 470 | for (j = 0; j < ctx_data.act_count; j++) |
@@ -413,6 +477,10 @@ static struct button_mapping *keyremap_create_temp(int *entries) | |||
413 | /*Don't save contexts with no actions */ | 477 | /*Don't save contexts with no actions */ |
414 | if (actions_this_ctx == 0){ continue; } | 478 | if (actions_this_ctx == 0){ continue; } |
415 | 479 | ||
480 | /* convert context x flag to context | flag */ | ||
481 | context = ctx_strip_flagidx(ctx_data.ctx_map[i].context, &flagidx); | ||
482 | context |= context_flags[flagidx].flag; | ||
483 | |||
416 | entry->action_code = CORE_CONTEXT_REMAP(context); | 484 | entry->action_code = CORE_CONTEXT_REMAP(context); |
417 | entry->button_code = action_offset; /* offset of first action entry */ | 485 | entry->button_code = action_offset; /* offset of first action entry */ |
418 | entry->pre_button_code = actions_this_ctx; /* entries (excluding sentinel) */ | 486 | entry->pre_button_code = actions_this_ctx; /* entries (excluding sentinel) */ |
@@ -431,6 +499,7 @@ static struct button_mapping *keyremap_create_temp(int *entries) | |||
431 | { | 499 | { |
432 | int actions_this_ctx = 0; | 500 | int actions_this_ctx = 0; |
433 | int context = ctx_data.ctx_map[i].context; | 501 | int context = ctx_data.ctx_map[i].context; |
502 | |||
434 | for (int j = 0; j < ctx_data.act_count; j++) | 503 | for (int j = 0; j < ctx_data.act_count; j++) |
435 | { | 504 | { |
436 | if (keyremap_map_is_valid(&ctx_data.act_map[j], context) > 0) | 505 | if (keyremap_map_is_valid(&ctx_data.act_map[j], context) > 0) |
@@ -473,7 +542,7 @@ static int keyremap_save_current(const char *filename) | |||
473 | 542 | ||
474 | struct button_mapping *keymap = keyremap_create_temp(&entry_count); | 543 | struct button_mapping *keymap = keyremap_create_temp(&entry_count); |
475 | 544 | ||
476 | if (keymap == NULL || entry_count <= 3) | 545 | if (keymap == NULL || entry_count <= 3) /* there should be atleast 4 entries */ |
477 | return status; | 546 | return status; |
478 | keyset.crc32 = | 547 | keyset.crc32 = |
479 | rb->crc_32(keymap, entry_count * sizeof(struct button_mapping), 0xFFFFFFFF); | 548 | rb->crc_32(keymap, entry_count * sizeof(struct button_mapping), 0xFFFFFFFF); |
@@ -505,6 +574,7 @@ static void keyremap_save_user_keys(bool notify) | |||
505 | 574 | ||
506 | if (keyremap_save_current(buf) == 0) | 575 | if (keyremap_save_current(buf) == 0) |
507 | { | 576 | { |
577 | logf("Error Saving"); | ||
508 | if(notify) | 578 | if(notify) |
509 | rb->splash(HZ *2, "Error Saving"); | 579 | rb->splash(HZ *2, "Error Saving"); |
510 | } | 580 | } |
@@ -519,9 +589,9 @@ static int keyremap_export_current(char *filenamebuf, size_t bufsz) | |||
519 | int ctx_count = 0; | 589 | int ctx_count = 0; |
520 | size_t entrylen; | 590 | size_t entrylen; |
521 | 591 | ||
522 | int entry_count = ctx_data.ctx_count + ctx_data.act_count + 1;;/* (ctx_count + ctx_count + act_count + 1) */ | 592 | int entry_count = ctx_data.ctx_count + ctx_data.act_count + 1; |
523 | 593 | ||
524 | if (entry_count < 3) | 594 | if (entry_count < 3) /* the header is not counted should be at least 3 entries */ |
525 | { | 595 | { |
526 | logf("%s: Not enough entries", __func__); | 596 | logf("%s: Not enough entries", __func__); |
527 | return 0; | 597 | return 0; |
@@ -932,9 +1002,13 @@ next_line: | |||
932 | { | 1002 | { |
933 | bufleft = bufsz - (pctx - filenamebuf); | 1003 | bufleft = bufsz - (pctx - filenamebuf); |
934 | ctx = -1; | 1004 | ctx = -1; |
935 | for (int i=0;i < LAST_CONTEXT_PLACEHOLDER;i++) | 1005 | int ctx_x_flag_count = (LAST_CONTEXT_PLACEHOLDER |
1006 | * ARRAYLEN(context_flags)); | ||
1007 | |||
1008 | for (int i=0;i < ctx_x_flag_count ;i++) | ||
936 | { | 1009 | { |
937 | if (rb->strncasecmp(pctx, context_name(i), bufleft) == 0) | 1010 | /* context x flag */ |
1011 | if (rb->strncasecmp(pctx, ctx_name_and_flag(i), bufleft) == 0) | ||
938 | { | 1012 | { |
939 | logf("ln: %d: Context Found: %s (%d)", line, pctx, i); | 1013 | logf("ln: %d: Context Found: %s (%d)", line, pctx, i); |
940 | if (keymap_add_context_entry(i) <= 0) | 1014 | if (keymap_add_context_entry(i) <= 0) |
@@ -1044,8 +1118,17 @@ static int keyremap_load_file(const char *filename) | |||
1044 | } | 1118 | } |
1045 | if ((entry.action_code & CONTEXT_REMAPPED) == CONTEXT_REMAPPED) | 1119 | if ((entry.action_code & CONTEXT_REMAPPED) == CONTEXT_REMAPPED) |
1046 | { | 1120 | { |
1047 | |||
1048 | int context = (entry.action_code & ~CONTEXT_REMAPPED); | 1121 | int context = (entry.action_code & ~CONTEXT_REMAPPED); |
1122 | for (int i = ARRAYLEN(context_flags) - 1; i > 0; i--) /* don't check idx 0*/ | ||
1123 | { | ||
1124 | /* convert context | flag to context x flag */ | ||
1125 | if ((context & context_flags[i].flag) == context_flags[i].flag) | ||
1126 | { | ||
1127 | logf("found ctx flag %s", context_flags[i].name); | ||
1128 | context &= ~context_flags[i].flag; | ||
1129 | context += i * LAST_CONTEXT_PLACEHOLDER; | ||
1130 | } | ||
1131 | } | ||
1049 | int offset = entry.button_code; | 1132 | int offset = entry.button_code; |
1050 | int entries = entry.pre_button_code; | 1133 | int entries = entry.pre_button_code; |
1051 | if (offset == 0 || entries <= 0) | 1134 | if (offset == 0 || entries <= 0) |
@@ -1201,10 +1284,10 @@ static const char *menu_useract_items_cb(int selected_item, void* data, | |||
1201 | { | 1284 | { |
1202 | if (ctx_data.act_count == 0) | 1285 | if (ctx_data.act_count == 0) |
1203 | rb->snprintf(buf, buf_len, "%s$%s", | 1286 | rb->snprintf(buf, buf_len, "%s$%s", |
1204 | context_name(ctx_data.ctx_map[i].context), | 1287 | ctx_name_and_flag(ctx_data.ctx_map[i].context), |
1205 | "Select$to add$actions"); | 1288 | "Select$to add$actions"); |
1206 | else | 1289 | else |
1207 | rb->snprintf(buf, buf_len, ctxfmt, context_name(ctx_data.ctx_map[i].context)); | 1290 | rb->snprintf(buf, buf_len, ctxfmt, ctx_name_and_flag(ctx_data.ctx_map[i].context)); |
1208 | return buf; | 1291 | return buf; |
1209 | } | 1292 | } |
1210 | } | 1293 | } |
@@ -1219,7 +1302,7 @@ static const char *menu_useract_items_cb(int selected_item, void* data, | |||
1219 | if (data != MENU_ID(M_EXPORTKEYS)) | 1302 | if (data != MENU_ID(M_EXPORTKEYS)) |
1220 | { | 1303 | { |
1221 | pctxbuf = ctxbuf; | 1304 | pctxbuf = ctxbuf; |
1222 | rb->snprintf(ctxbuf, sizeof(ctxbuf), ctxfmt, context_name(context)); | 1305 | rb->snprintf(ctxbuf, sizeof(ctxbuf), ctxfmt, ctx_name_and_flag(context)); |
1223 | pctxbuf += szctx;//sizeof("CONTEXT") | 1306 | pctxbuf += szctx;//sizeof("CONTEXT") |
1224 | } | 1307 | } |
1225 | struct button_mapping * bm = &ctx_data.act_map[i].map; | 1308 | struct button_mapping * bm = &ctx_data.act_map[i].map; |
@@ -1263,7 +1346,7 @@ static const char *test_keymap_name_cb(int selected_item, void* data, | |||
1263 | if (keytest.context >= 0) | 1346 | if (keytest.context >= 0) |
1264 | { | 1347 | { |
1265 | if (selected_item == 0) | 1348 | if (selected_item == 0) |
1266 | rb->snprintf(buf, buf_len, "< %s >", context_name(keytest.context)); | 1349 | rb->snprintf(buf, buf_len, "< %s >", ctx_name_and_flag(keytest.context)); |
1267 | else if (selected_item == 1) | 1350 | else if (selected_item == 1) |
1268 | { | 1351 | { |
1269 | if (keytest.countdown >= 10) | 1352 | if (keytest.countdown >= 10) |
@@ -1304,7 +1387,7 @@ static const char* list_get_name_cb(int selected_item, void* data, | |||
1304 | } | 1387 | } |
1305 | else if (data == MENU_ID(M_CONTEXTS)) | 1388 | else if (data == MENU_ID(M_CONTEXTS)) |
1306 | { | 1389 | { |
1307 | return context_name(selected_item); | 1390 | return ctx_name_and_flag(selected_item); |
1308 | } | 1391 | } |
1309 | else if (data == MENU_ID(M_DELKEYS) || data == MENU_ID(M_LOADKEYS)) | 1392 | else if (data == MENU_ID(M_DELKEYS) || data == MENU_ID(M_LOADKEYS)) |
1310 | { | 1393 | { |
@@ -1341,7 +1424,7 @@ static int list_voice_cb(int list_index, void* data) | |||
1341 | } | 1424 | } |
1342 | else | 1425 | else |
1343 | { | 1426 | { |
1344 | char buf[64]; | 1427 | char buf[MAX_MENU_NAME]; |
1345 | const char* name = list_get_name_cb(list_index, data, buf, sizeof(buf)); | 1428 | const char* name = list_get_name_cb(list_index, data, buf, sizeof(buf)); |
1346 | long id = P2ID((const unsigned char *)name); | 1429 | long id = P2ID((const unsigned char *)name); |
1347 | if(id>=0) | 1430 | if(id>=0) |