diff --git a/apps/action.c b/apps/action.c index e8c3e8675e..4504b97ff2 100644 --- a/apps/action.c +++ b/apps/action.c @@ -605,12 +605,10 @@ static inline void action_code_lookup(action_last_t *last, action_cur_t *cur) /* attempt to look up the button in user supplied remap */ if(last->key_remap && (context & CONTEXT_PLUGIN) == 0) { -#if 0 /*Disable the REMOTE context for remap for now (BUTTON_REMOTE != 0)*/ if ((cur->button & BUTTON_REMOTE) != 0) { context |= CONTEXT_REMOTE; } -#endif cur->items = core_get_data(last->key_remap); i = 0; action = ACTION_UNKNOWN; diff --git a/apps/action.h b/apps/action.h index a3c21ec8a6..6e1278b33c 100644 --- a/apps/action.h +++ b/apps/action.h @@ -35,9 +35,8 @@ #define CONTEXT_PLUGIN 0x10000000 /* for plugins using get_custom_action */ #define CONTEXT_REMAPPED 0x08000000 /* marker for key remap context table */ #define CORE_CONTEXT_REMAP(context) (CONTEXT_REMAPPED | context) -#ifdef HAVE_LOCKED_ACTIONS #define CONTEXT_LOCKED 0x04000000 /* flag to use alternate keymap when screen is locked */ -#endif + #define LAST_ITEM_IN_LIST { CONTEXT_STOPSEARCHING, BUTTON_NONE, BUTTON_NONE } #define LAST_ITEM_IN_LIST__NEXTLIST(a) { a, BUTTON_NONE, BUTTON_NONE } diff --git a/apps/keymaps/keymap-clip.c b/apps/keymaps/keymap-clip.c index de5c88a80f..cf1f283d24 100644 --- a/apps/keymaps/keymap-clip.c +++ b/apps/keymaps/keymap-clip.c @@ -401,9 +401,11 @@ const struct button_mapping* get_context_mapping(int context) { switch (context) { + case CONTEXT_STD | CONTEXT_LOCKED: case CONTEXT_STD: return button_context_standard; + case CONTEXT_WPS | CONTEXT_LOCKED: case CONTEXT_WPS: return button_context_wps; @@ -414,6 +416,7 @@ const struct button_mapping* get_context_mapping(int context) return button_context_listtree_scroll_without_combo; else return button_context_listtree_scroll_with_combo; + case CONTEXT_MAINMENU | CONTEXT_LOCKED: case CONTEXT_MAINMENU: return button_context_mainmenu; case CONTEXT_CUSTOM|CONTEXT_TREE: 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 @@ #define KMFUSER "user_keyremap" #define MAX_BUTTON_COMBO 5 #define MAX_BUTTON_NAME 32 +#define MAX_MENU_NAME 64 #define TEST_COUNTDOWN_MS 1590 +struct context_flags { + char * name; + int flag; +}; + +/* flags added to context_name[] */ +static struct context_flags context_flags[] = { + {"UNKNOWN", 0},/* index 0 is an Error */ +#ifdef HAVE_LOCKED_ACTIONS + {"LOCKED", CONTEXT_LOCKED}, +#endif + /*{"PLUGIN", CONTEXT_PLUGIN}, need a custom action list and a way to supply */ +#if BUTTON_REMOTE != 0 + {"REMOTE", CONTEXT_REMOTE}, +#ifdef HAVE_LOCKED_ACTIONS + {"REMOTE_LOCKED", CONTEXT_REMOTE | CONTEXT_LOCKED}, +#endif +#endif /* BUTTON_REMOTE != 0 */ +}; + static struct keyremap_buffer_t { char * buffer; size_t buf_size; @@ -138,7 +159,7 @@ MENU_ITEM(M_DELCORE, "Remove 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: */ -MENU_ITEM(M_CONTEXTS, "Contexts", LAST_CONTEXT_PLACEHOLDER ), +MENU_ITEM(M_CONTEXTS, "Contexts", LAST_CONTEXT_PLACEHOLDER * ARRAYLEN(context_flags)), MENU_ITEM(M_CONTEXT_EDIT, "", 5), #undef MENU_ITEM }; @@ -200,6 +221,47 @@ static void synclist_set_update(int id, int selected_item, int items, int sel_si synclist_set(id, selected_item, items, sel_size); } +/* returns the actual context & index of the flag is passed in *flagidx */ +static int ctx_strip_flagidx(int ctx, int *flagidx) +{ + int ctx_out = ctx % (LAST_CONTEXT_PLACEHOLDER); + *flagidx = 0; + if (ctx_out != ctx) + { + while (ctx >= LAST_CONTEXT_PLACEHOLDER) + { + (*flagidx)++; + ctx -= LAST_CONTEXT_PLACEHOLDER; + } + if (*flagidx >= (int)ARRAYLEN(context_flags)) + *flagidx = 0; /* unknown flag */ + + logf("%s ctx: (%d) %s flag idx: (%d) %s\n", __func__, + ctx, context_name(ctx), *flagidx, context_flags[*flagidx].name); + } + return ctx_out; +} + +/* combines context name and flag name using '_' to join them */ +static char *ctx_name_and_flag(int index) +{ + static char ctx_namebuf[MAX_MENU_NAME]; + char *ctx_name = "?"; + int flagidx; + int ctx = ctx_strip_flagidx(index, &flagidx); + if (flagidx == 0) + { + ctx_name = context_name(ctx); + } + else if (flagidx >= 0 && flagidx < (int)ARRAYLEN(context_flags)) + { + rb->snprintf(ctx_namebuf, sizeof(ctx_namebuf), "%s_%s", + context_name(ctx), context_flags[flagidx].name); + ctx_name = ctx_namebuf; + } + return ctx_name; +} + static int btnval_to_index(unsigned int btnvalue) { int index = -1; @@ -361,6 +423,7 @@ static int keyremap_map_is_valid(struct action_mapping_t *amap, int context) static struct button_mapping *keyremap_create_temp(int *entries) { + logf("%s()", __func__); struct button_mapping *tempkeymap; int action_offset = 1; /* start of action entries (ctx_count + 1)*/ int entry_count = 1;/* (ctx_count + ctx_count + act_count) */ @@ -390,7 +453,7 @@ static struct button_mapping *keyremap_create_temp(int *entries) } size_t keymap_bytes = (entry_count) * sizeof(struct button_mapping); *entries = entry_count; - logf("keyremap create temp entry count: %d", entry_count); + logf("%s() entry count: %d", __func__, entry_count); logf("keyremap bytes: %zu, avail: %zu", keymap_bytes, (keyremap_buffer.end - keyremap_buffer.front)); if (keyremap_buffer.front + keymap_bytes < keyremap_buffer.end) @@ -401,6 +464,7 @@ static struct button_mapping *keyremap_create_temp(int *entries) for (i = 0; i < ctx_data.ctx_count; i++) { int actions_this_ctx = 0; + int flagidx; int context = ctx_data.ctx_map[i].context; /* how many actions are contained in each context? */ for (j = 0; j < ctx_data.act_count; j++) @@ -413,6 +477,10 @@ static struct button_mapping *keyremap_create_temp(int *entries) /*Don't save contexts with no actions */ if (actions_this_ctx == 0){ continue; } + /* convert context x flag to context | flag */ + context = ctx_strip_flagidx(ctx_data.ctx_map[i].context, &flagidx); + context |= context_flags[flagidx].flag; + entry->action_code = CORE_CONTEXT_REMAP(context); entry->button_code = action_offset; /* offset of first action entry */ entry->pre_button_code = actions_this_ctx; /* entries (excluding sentinel) */ @@ -431,6 +499,7 @@ static struct button_mapping *keyremap_create_temp(int *entries) { int actions_this_ctx = 0; int context = ctx_data.ctx_map[i].context; + for (int j = 0; j < ctx_data.act_count; j++) { if (keyremap_map_is_valid(&ctx_data.act_map[j], context) > 0) @@ -473,7 +542,7 @@ static int keyremap_save_current(const char *filename) struct button_mapping *keymap = keyremap_create_temp(&entry_count); - if (keymap == NULL || entry_count <= 3) + if (keymap == NULL || entry_count <= 3) /* there should be atleast 4 entries */ return status; keyset.crc32 = rb->crc_32(keymap, entry_count * sizeof(struct button_mapping), 0xFFFFFFFF); @@ -505,6 +574,7 @@ static void keyremap_save_user_keys(bool notify) if (keyremap_save_current(buf) == 0) { + logf("Error Saving"); if(notify) rb->splash(HZ *2, "Error Saving"); } @@ -519,9 +589,9 @@ static int keyremap_export_current(char *filenamebuf, size_t bufsz) int ctx_count = 0; size_t entrylen; - int entry_count = ctx_data.ctx_count + ctx_data.act_count + 1;;/* (ctx_count + ctx_count + act_count + 1) */ + int entry_count = ctx_data.ctx_count + ctx_data.act_count + 1; - if (entry_count < 3) + if (entry_count < 3) /* the header is not counted should be at least 3 entries */ { logf("%s: Not enough entries", __func__); return 0; @@ -932,9 +1002,13 @@ next_line: { bufleft = bufsz - (pctx - filenamebuf); ctx = -1; - for (int i=0;i < LAST_CONTEXT_PLACEHOLDER;i++) + int ctx_x_flag_count = (LAST_CONTEXT_PLACEHOLDER + * ARRAYLEN(context_flags)); + + for (int i=0;i < ctx_x_flag_count ;i++) { - if (rb->strncasecmp(pctx, context_name(i), bufleft) == 0) + /* context x flag */ + if (rb->strncasecmp(pctx, ctx_name_and_flag(i), bufleft) == 0) { logf("ln: %d: Context Found: %s (%d)", line, pctx, i); if (keymap_add_context_entry(i) <= 0) @@ -1044,8 +1118,17 @@ static int keyremap_load_file(const char *filename) } if ((entry.action_code & CONTEXT_REMAPPED) == CONTEXT_REMAPPED) { - int context = (entry.action_code & ~CONTEXT_REMAPPED); + for (int i = ARRAYLEN(context_flags) - 1; i > 0; i--) /* don't check idx 0*/ + { + /* convert context | flag to context x flag */ + if ((context & context_flags[i].flag) == context_flags[i].flag) + { + logf("found ctx flag %s", context_flags[i].name); + context &= ~context_flags[i].flag; + context += i * LAST_CONTEXT_PLACEHOLDER; + } + } int offset = entry.button_code; int entries = entry.pre_button_code; if (offset == 0 || entries <= 0) @@ -1201,10 +1284,10 @@ static const char *menu_useract_items_cb(int selected_item, void* data, { if (ctx_data.act_count == 0) rb->snprintf(buf, buf_len, "%s$%s", - context_name(ctx_data.ctx_map[i].context), + ctx_name_and_flag(ctx_data.ctx_map[i].context), "Select$to add$actions"); else - rb->snprintf(buf, buf_len, ctxfmt, context_name(ctx_data.ctx_map[i].context)); + rb->snprintf(buf, buf_len, ctxfmt, ctx_name_and_flag(ctx_data.ctx_map[i].context)); return buf; } } @@ -1219,7 +1302,7 @@ static const char *menu_useract_items_cb(int selected_item, void* data, if (data != MENU_ID(M_EXPORTKEYS)) { pctxbuf = ctxbuf; - rb->snprintf(ctxbuf, sizeof(ctxbuf), ctxfmt, context_name(context)); + rb->snprintf(ctxbuf, sizeof(ctxbuf), ctxfmt, ctx_name_and_flag(context)); pctxbuf += szctx;//sizeof("CONTEXT") } 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, if (keytest.context >= 0) { if (selected_item == 0) - rb->snprintf(buf, buf_len, "< %s >", context_name(keytest.context)); + rb->snprintf(buf, buf_len, "< %s >", ctx_name_and_flag(keytest.context)); else if (selected_item == 1) { if (keytest.countdown >= 10) @@ -1304,7 +1387,7 @@ static const char* list_get_name_cb(int selected_item, void* data, } else if (data == MENU_ID(M_CONTEXTS)) { - return context_name(selected_item); + return ctx_name_and_flag(selected_item); } else if (data == MENU_ID(M_DELKEYS) || data == MENU_ID(M_LOADKEYS)) { @@ -1341,7 +1424,7 @@ static int list_voice_cb(int list_index, void* data) } else { - char buf[64]; + char buf[MAX_MENU_NAME]; const char* name = list_get_name_cb(list_index, data, buf, sizeof(buf)); long id = P2ID((const unsigned char *)name); if(id>=0) diff --git a/firmware/export/config/sansaclipplus.h b/firmware/export/config/sansaclipplus.h index e78063ef02..d7e18c4864 100644 --- a/firmware/export/config/sansaclipplus.h +++ b/firmware/export/config/sansaclipplus.h @@ -17,6 +17,7 @@ #define NUM_DRIVES 2 #ifndef BOOTLOADER +#define HAVE_LOCKED_ACTIONS #define HAVE_HOTSWAP #define HAVE_RDS_CAP #define CONFIG_RDS (RDS_CFG_POLL | RDS_CFG_PROCESS) diff --git a/firmware/export/config/sansaclipv2.h b/firmware/export/config/sansaclipv2.h index 6e369db681..f2b1115c81 100644 --- a/firmware/export/config/sansaclipv2.h +++ b/firmware/export/config/sansaclipv2.h @@ -69,6 +69,7 @@ #define HAVE_LCD_ENABLE #ifndef BOOTLOADER +#define HAVE_LOCKED_ACTIONS /* Define this if your LCD can be put to sleep. * HAVE_LCD_ENABLE should be defined as well. */ //#define HAVE_LCD_SLEEP diff --git a/firmware/export/config/sansaclipzip.h b/firmware/export/config/sansaclipzip.h index d8b18e1a18..86bc8fa4c2 100644 --- a/firmware/export/config/sansaclipzip.h +++ b/firmware/export/config/sansaclipzip.h @@ -71,6 +71,7 @@ #define HAVE_LCD_ENABLE #ifndef BOOTLOADER +#define HAVE_LOCKED_ACTIONS /* Define this if your LCD can be put to sleep. * HAVE_LCD_ENABLE should be defined as well. */ //#define HAVE_LCD_SLEEP