Index: apps/action.h =================================================================== --- apps/action.h (revision 25329) +++ apps/action.h (working copy) @@ -126,7 +126,9 @@ ACTION_WPS_CONTEXT, ACTION_WPS_QUICKSCREEN,/* optional */ ACTION_WPS_MENU, /*this should be the same as ACTION_STD_MENU */ +#ifndef HOTKEY ACTION_WPS_VIEW_PLAYLIST, +#endif ACTION_WPS_REC, #if 0 ACTION_WPSAB_SINGLE, /* This needs to be #defined in @@ -195,8 +197,13 @@ ACTION_SETTINGS_DECBIGSTEP, ACTION_SETTINGS_RESET, + /* hotkey */ +#ifdef HOTKEY + ACTION_HOTKEY, +#else /* bookmark screen */ ACTION_BMS_DELETE, +#endif /* quickscreen */ ACTION_QS_LEFT, Index: apps/tree.c =================================================================== --- apps/tree.c (revision 25329) +++ apps/tree.c (working copy) @@ -757,12 +757,22 @@ #endif case ACTION_STD_CONTEXT: +#ifdef HOTKEY + case ACTION_HOTKEY: { + bool hotkey = button == ACTION_HOTKEY; +#else + { +#endif int onplay_result; int attr = 0; if(!numentries) - onplay_result = onplay(NULL, 0, curr_context); + onplay_result = onplay(NULL, 0, curr_context +#ifdef HOTKEY + , hotkey +#endif + ); else { #ifdef HAVE_TAGCACHE if (id3db) @@ -788,7 +798,11 @@ snprintf(buf, sizeof buf, "/%s", dircache[tc.selected_item].name); } - onplay_result = onplay(buf, attr, curr_context); + onplay_result = onplay(buf, attr, curr_context +#ifdef HOTKEY + , hotkey +#endif + ); } switch (onplay_result) { Index: apps/lang/english.lang =================================================================== --- apps/lang/english.lang (revision 25329) +++ apps/lang/english.lang (working copy) @@ -13394,3 +13394,88 @@ lineout_poweroff: "Line Out" + + id: LANG_SET_HOTKEY + desc: hotkey splash + user: core + + *: none + hotkey: "Set Hotkey: %s" + + + *: none + hotkey: "Set Hotkey: %s" + + + *: none + hotkey: "Set Hotkey: %s" + + + + id: LANG_HOTKEY_NOT_SET + desc: hotkey splash + user: core + + *: none + hotkey: "Hotkey Not Set" + + + *: none + hotkey: "Hotkey Not Set" + + + *: none + hotkey: "Hotkey Not Set" + + + + id: LANG_HOTKEY + desc: hotkey menu + user: core + + *: none + hotkey: "Hotkey" + + + *: none + hotkey: "Hotkey" + + + *: none + hotkey: "Hotkey" + + + + id: LANG_HOTKEY_PERSIST + desc: hotkey menu + user: core + + *: none + hotkey: "Hotkey Persistence" + + + *: none + hotkey: "Hotkey Persistence" + + + *: none + hotkey: "Hotkey Persistence" + + + + id: LANG_VIEW_HOTKEY + desc: hotkey menu + user: core + + *: none + hotkey: "View Hotkey Settings" + + + *: none + hotkey: "View Hotkey Settings" + + + *: none + hotkey: "View Hotkey Settings" + + Index: apps/onplay.c =================================================================== --- apps/onplay.c (revision 25329) +++ apps/onplay.c (working copy) @@ -64,6 +64,7 @@ #include "statusbar-skinned.h" #include "pitchscreen.h" #include "viewport.h" +#include "hotkey.h" static int context; static char* selected_file = NULL; @@ -578,6 +579,13 @@ return delete_handler(true); } +#ifdef HOTKEY +static bool delete_item(void) +{ + return delete_handler(selected_file_attr & ATTR_DIRECTORY); +} +#endif + static bool rename_file(void) { char newname[MAX_PATH]; @@ -1176,23 +1184,177 @@ break; case ACTION_EXIT_MENUITEM: return ACTION_EXIT_AFTER_THIS_MENUITEM; - break; } return action; } -int onplay(char* file, int attr, int from) + +#ifdef HOTKEY +extern const struct menu_item_ex *selected_menu_item; +extern bool hotkey_settable_menu; + +#define HOT_MASK 0x0FF +#define HOT_WPS 0x100 +#define HOT_TREE 0x200 + +struct hotkey_assignment { + int item; + struct menu_func func; + int return_code; + const struct menu_item_ex *menu_addr; +}; + +#define HOTKEY_FUNC(func, param) {{(void *)func}, param} + +/* Any desired hotkey functions go in this struct. + Also update the enum table in hotkey.h */ +static struct hotkey_assignment hotkey_items[] = { + { HOTKEY_VIEW_PLAYLIST | HOT_WPS , HOTKEY_FUNC(NULL, NULL), + ONPLAY_PLAYLIST, &view_cur_playlist }, +#ifdef HAVE_PITCHSCREEN + { HOTKEY_PITCHSCREEN | HOT_WPS , HOTKEY_FUNC(gui_syncpitchscreen_run, NULL), + ONPLAY_RELOAD_DIR, &pitch_screen_item }, +#endif + { HOTKEY_DELETE | HOT_WPS | HOT_TREE , HOTKEY_FUNC(delete_item, NULL), + ONPLAY_RELOAD_DIR, &delete_file_item }, + { HOTKEY_DELETE | HOT_TREE , HOTKEY_FUNC(delete_item, NULL), + ONPLAY_RELOAD_DIR, &delete_dir_item }, + { HOTKEY_INSERT | HOT_TREE , HOTKEY_FUNC(playlist_insert_func, (intptr_t*)PLAYLIST_INSERT), + ONPLAY_START_PLAY, &i_pl_item }, +}; + +static const int num_hotkey_items = sizeof(hotkey_items) / sizeof(hotkey_items[0]); + +/* reset hotkey settings to their defaults */ +void reset_hotkey_settings(bool show_splash) { + void *vars[] = { + &global_settings.hotkey_tree, + &global_settings.hotkey_tree_desc_id, + &global_settings.hotkey_wps, + &global_settings.hotkey_wps_desc_id, + }; + const int num_settings = sizeof(vars) / sizeof(vars[0]); + int i; + + for (i = 0; i < num_settings; i++) + { + const struct settings_list *setting = + find_setting(vars[i], NULL); + reset_setting(setting, setting->setting); + } + + settings_save(); + if (show_splash) + splash(HZ, str(LANG_RESET_DONE_CLEAR)); +} + +/* Execute the hotkey function, if listed for this screen */ +static int execute_hotkey(bool is_wps) +{ + int i; + struct hotkey_assignment *this_item; + const int context = is_wps ? HOT_WPS : HOT_TREE; + const int this_hotkey = (is_wps ? global_settings.hotkey_wps : + global_settings.hotkey_tree); + + /* search assignment struct for a match for the hotkey setting */ + for (i = 0; i < num_hotkey_items; i++) + { + this_item = &hotkey_items[i]; + if ((this_item->item & context) && + ((this_item->item & HOT_MASK) == this_hotkey)) + { + /* run the associated function (with optional param), if any */ + const struct menu_func func = this_item->func; + if (func.function != NULL) + { + if (func.param != NULL) + (*(func.function_w_param))(func.param); + else + (*(func.function))(); + } + /* return with the associated code */ + return this_item->return_code; + } + } + + /* no valid hotkey set */ + splash(HZ, ID2P(LANG_HOTKEY_NOT_SET)); + return ONPLAY_RELOAD_DIR; +} + +/* Set the hotkey to the current context menu function, if listed */ +static void set_hotkey(bool is_wps) +{ + int i; + struct hotkey_assignment *this_item; + const int context = is_wps ? HOT_WPS : HOT_TREE; + int this_hotkey; + int this_hotkey_desc_id; + bool hotkey_set = false; + + /* search assignment struct for a function that matches the current menu item */ + for (i = 0; i < num_hotkey_items; i++) + { + this_item = &hotkey_items[i]; + if ((this_item->item & context) && + (this_item->menu_addr == selected_menu_item)) + { + this_hotkey = this_item->item & HOT_MASK; + this_hotkey_desc_id = P2ID((selected_menu_item->callback_and_desc)->desc); + hotkey_set = true; + break; + } + } + + /* ignore the hotkey if no match found */ + if (!hotkey_set) return; + + /* store the hotkey settings */ + if (is_wps) + { + global_settings.hotkey_wps = this_hotkey; + global_settings.hotkey_wps_desc_id = this_hotkey_desc_id; + } + else + { + global_settings.hotkey_tree = this_hotkey; + global_settings.hotkey_tree_desc_id = this_hotkey_desc_id; + } + + settings_save(); + splashf(HZ*2, str(LANG_SET_HOTKEY), str(this_hotkey_desc_id)); +} +#endif + +int onplay(char* file, int attr, int from +#ifdef HOTKEY + , bool hotkey +#endif + ) +{ const struct menu_item_ex *menu; onplay_result = ONPLAY_OK; context = from; selected_file = file; selected_file_attr = attr; +#ifdef HOTKEY + if (hotkey) + return execute_hotkey(context == CONTEXT_WPS); + hotkey_settable_menu = true; +#endif if (context == CONTEXT_WPS) menu = &wps_onplay_menu; else menu = &tree_onplay_menu; switch (do_menu(menu, NULL, NULL, false)) { +#ifdef HOTKEY + hotkey_settable_menu = false; + case MENU_SELECTED_HOTKEY: + set_hotkey(context == CONTEXT_WPS); + return ONPLAY_RELOAD_DIR; +#endif case GO_TO_WPS: return ONPLAY_START_PLAY; case GO_TO_ROOT: Index: apps/gui/wps.c =================================================================== --- apps/gui/wps.c (revision 25329) +++ apps/gui/wps.c (working copy) @@ -888,10 +888,20 @@ switch(button) { case ACTION_WPS_CONTEXT: +#ifdef HOTKEY + case ACTION_HOTKEY: { + bool hotkey = button == ACTION_HOTKEY; +#else + { +#endif gwps_leave_wps(); int retval = onplay(wps_state.id3->path, - FILE_ATTR_AUDIO, CONTEXT_WPS); + FILE_ATTR_AUDIO, CONTEXT_WPS +#ifdef HOTKEY + , hotkey +#endif + ); /* if music is stopped in the context menu we want to exit the wps */ if (retval == ONPLAY_MAINMENU || !audio_status()) @@ -1182,10 +1192,12 @@ case SYS_POWEROFF: default_event_handler(SYS_POWEROFF); break; +#ifndef HOTKEY case ACTION_WPS_VIEW_PLAYLIST: gwps_leave_wps(); return GO_TO_PLAYLIST_VIEWER; break; +#endif default: if(default_event_handler(button) == SYS_USB_CONNECTED) { Index: apps/menu.c =================================================================== --- apps/menu.c (revision 25329) +++ apps/menu.c (working copy) @@ -61,6 +61,12 @@ #include "list.h" #include "buttonbar.h" +/* hotkey settings */ +#ifdef HOTKEY +const struct menu_item_ex *selected_menu_item; +bool hotkey_settable_menu = false; +#endif + #define MAX_MENUS 8 /* used to allow for dynamic menus */ #define MAX_MENU_SUBITEMS 64 @@ -426,6 +432,15 @@ done = true; } #endif +#ifdef HOTKEY + else if ((action == ACTION_HOTKEY) && hotkey_settable_menu) + { + ret = MENU_SELECTED_HOTKEY; + done = true; + selected = get_menu_selection(gui_synclist_get_sel_pos(&lists),menu); + selected_menu_item = menu->submenus[selected]; + } +#endif else if (action == ACTION_TREE_WPS) { ret = GO_TO_PREVIOUS_MUSIC; Index: apps/settings.h =================================================================== --- apps/settings.h (revision 25329) +++ apps/settings.h (working copy) @@ -816,6 +816,14 @@ bool morse_input; /* text input method setting */ #endif +#ifdef HOTKEY + bool hotkey_persist; + int hotkey_wps; + int hotkey_wps_desc_id; + int hotkey_tree; + int hotkey_tree_desc_id; +#endif + }; /** global variables **/ Index: apps/menus/settings_menu.c =================================================================== --- apps/menus/settings_menu.c (revision 25329) +++ apps/menus/settings_menu.c (working copy) @@ -47,6 +47,8 @@ #ifdef HAVE_DIRCACHE #include "dircache.h" #endif +#include "hotkey.h" +#include "list.h" /***********************************/ /* TAGCACHE MENU */ @@ -276,6 +278,32 @@ MENUITEM_SETTING(touchpad_sensitivity, &global_settings.touchpad_sensitivity, NULL); #endif +/* Hotkey menu */ +#ifdef HOTKEY +static void view_hotkey_info(void) +{ + struct simplelist_info info; + simplelist_info_init(&info, str(LANG_VIEW_HOTKEY), 0, NULL); + info.hide_selection = true; + simplelist_set_line_count(2); + simplelist_addline(0, "WPS: %s", + str(global_settings.hotkey_wps_desc_id)); + simplelist_addline(1, "Tree: %s", + str(global_settings.hotkey_tree_desc_id)); + simplelist_show_list(&info); +} + +MENUITEM_SETTING(hotkey_persist, &global_settings.hotkey_persist, NULL); +MENUITEM_FUNCTION(hotkey_view, 0, ID2P(LANG_VIEW_HOTKEY), + (int(*)(void))view_hotkey_info, NULL, + NULL, Icon_NOICON); +MENUITEM_FUNCTION(hotkey_reset, 0, ID2P(LANG_RESET), + (int(*)(void))reset_hotkey_settings, false, + NULL, Icon_NOICON); +MAKE_MENU(hotkey_menu, ID2P(LANG_HOTKEY), 0, Icon_NOICON, + &hotkey_persist, &hotkey_view, &hotkey_reset); +#endif + MAKE_MENU(system_menu, ID2P(LANG_SYSTEM), 0, Icon_System_menu, &start_screen, @@ -321,6 +349,9 @@ &usb_hid, &usb_keypad_mode, #endif +#ifdef HOTKEY + &hotkey_menu, +#endif ); /* SYSTEM MENU */ Index: apps/onplay.h =================================================================== --- apps/onplay.h (revision 25329) +++ apps/onplay.h (working copy) @@ -21,7 +21,11 @@ #ifndef _ONPLAY_H_ #define _ONPLAY_H_ -int onplay(char* file, int attr, int from_screen); +int onplay(char* file, int attr, int from_screen +#ifdef HOTKEY + , bool hotkey +#endif + ); enum { ONPLAY_MAINMENU = -1, Index: apps/settings_list.c =================================================================== --- apps/settings_list.c (revision 25329) +++ apps/settings_list.c (working copy) @@ -56,6 +56,7 @@ #include "touchscreen.h" #include "ctype.h" /* For isspace() */ #endif +#include "hotkey.h" #define NVRAM(bytes) (bytes< ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: hotkey.h 24791 2010-02-20 19:06:39Z kugel $ + * + * Copyright (C) 2002 Björn Stenberg + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef _HOTKEY_H_ +#define _HOTKEY_H_ + +#ifdef HOTKEY +void reset_hotkey_settings(bool show_splash); + +enum hotkey_settings { + HOTKEY_OFF, + HOTKEY_VIEW_PLAYLIST, +#ifdef HAVE_PITCHSCREEN + HOTKEY_PITCHSCREEN, +#endif + HOTKEY_DELETE, + HOTKEY_INSERT, +}; + +#define HOTKEY_WPS_DEFAULT HOTKEY_VIEW_PLAYLIST +#define HOTKEY_WPS_ID_DEFAULT LANG_VIEW_DYNAMIC_PLAYLIST +#define HOTKEY_TREE_DEFAULT HOTKEY_OFF +#define HOTKEY_TREE_ID_DEFAULT LANG_OFF + +#endif + +#endif Property changes on: apps/hotkey.h ___________________________________________________________________ Added: svn:executable + * Index: apps/features.txt =================================================================== --- apps/features.txt (revision 25329) +++ apps/features.txt (working copy) @@ -70,6 +70,10 @@ remote_button_hold #endif +#if defined(HOTKEY) +hotkey +#endif + #if defined(HAVE_LCD_BITMAP) lcd_bitmap #endif Index: apps/bookmark.c =================================================================== --- apps/bookmark.c (revision 25329) +++ apps/bookmark.c (working copy) @@ -728,7 +728,12 @@ ID2P(LANG_BOOKMARK_CONTEXT_DELETE)); static const int menu_actions[] = { - ACTION_STD_OK, ACTION_BMS_DELETE + ACTION_STD_OK, +#ifdef HOTKEY + ACTION_HOTKEY +#else + ACTION_BMS_DELETE +#endif }; int selection = do_menu(&menu_items, NULL, NULL, false); @@ -757,7 +762,11 @@ exit = true; break; +#ifdef HOTKEY + case ACTION_HOTKEY: +#else case ACTION_BMS_DELETE: +#endif if (item >= 0) { const char *lines[]={ Index: apps/root_menu.h =================================================================== --- apps/root_menu.h (revision 25329) +++ apps/root_menu.h (working copy) @@ -53,6 +53,9 @@ GO_TO_BROWSEPLUGINS, GO_TO_TIMESCREEN, GO_TO_PLAYLIST_VIEWER, +#ifdef HOTKEY + MENU_SELECTED_HOTKEY, +#endif }; extern const struct menu_item_ex root_menu_; Index: apps/main.c =================================================================== --- apps/main.c (revision 25329) +++ apps/main.c (working copy) @@ -75,6 +75,7 @@ #include "icon.h" #include "viewport.h" #include "statusbar-skinned.h" +#include "hotkey.h" #ifdef IPOD_ACCESSORY_PROTOCOL #include "iap.h" @@ -377,6 +378,10 @@ button_clear_queue(); /* Empty the keyboard buffer */ settings_apply_skins(); +#ifdef HOTKEY + if (!global_settings.hotkey_persist) + reset_hotkey_settings(false); +#endif } #else @@ -639,6 +644,10 @@ check_bootfile(false); /* remember write time and filesize */ #endif settings_apply_skins(); +#ifdef HOTKEY + if (!global_settings.hotkey_persist) + reset_hotkey_settings(false); +#endif } #ifdef CPU_PP Index: apps/keymaps/keymap-e200.c =================================================================== --- apps/keymaps/keymap-e200.c (revision 25329) +++ apps/keymaps/keymap-e200.c (working copy) @@ -80,11 +80,16 @@ { ACTION_WPS_QUICKSCREEN, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_DOWN }, { ACTION_WPS_MENU, BUTTON_DOWN|BUTTON_REL, BUTTON_DOWN }, +#ifndef HOTKEY { ACTION_WPS_VIEW_PLAYLIST, BUTTON_REC|BUTTON_REL, BUTTON_REC }, +#endif { ACTION_WPS_REC, BUTTON_REC|BUTTON_REPEAT, BUTTON_NONE }, { ACTION_WPS_PITCHSCREEN, BUTTON_SELECT|BUTTON_UP, BUTTON_SELECT }, { ACTION_WPS_ID3SCREEN, BUTTON_SELECT|BUTTON_DOWN, BUTTON_SELECT }, +#ifdef HOTKEY + { ACTION_HOTKEY, BUTTON_REC|BUTTON_REL, BUTTON_REC }, +#endif LAST_ITEM_IN_LIST }; /* button_context_wps */ @@ -108,6 +113,9 @@ static const struct button_mapping button_context_list[] = { { ACTION_LISTTREE_PGUP, BUTTON_REC|BUTTON_SCROLL_BACK, BUTTON_REC }, { ACTION_LISTTREE_PGDOWN, BUTTON_REC|BUTTON_SCROLL_FWD, BUTTON_REC }, +#ifdef HOTKEY + { ACTION_HOTKEY, BUTTON_REC|BUTTON_REL, BUTTON_REC }, +#endif LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) }; /* button_context_list */ @@ -272,11 +280,13 @@ LAST_ITEM_IN_LIST }; /* button_context_keyboard */ +#ifndef HOTKEY static const struct button_mapping button_context_bmark[] = { { ACTION_BMS_DELETE, BUTTON_REC, BUTTON_NONE }, LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST), }; /* button_context_bmark */ +#endif #ifdef USB_ENABLE_HID static const struct button_mapping button_context_usb_hid[] = { @@ -418,7 +428,11 @@ case CONTEXT_FM: return button_context_radio; case CONTEXT_BOOKMARKSCREEN: +#ifdef HOTKEY + return button_context_list; +#else return button_context_bmark; +#endif case CONTEXT_QUICKSCREEN: return button_context_quickscreen; case CONTEXT_PITCHSCREEN: Index: apps/playlist_catalog.c =================================================================== --- apps/playlist_catalog.c (revision 25329) +++ apps/playlist_catalog.c (working copy) @@ -280,8 +280,11 @@ snprintf(playlist, MAX_PATH, "%s/%s", playlist_dir, sel_file); - if (onplay(playlist, FILE_ATTR_M3U, - CONTEXT_TREE) != ONPLAY_OK) + if (onplay(playlist, FILE_ATTR_M3U, CONTEXT_TREE +#ifdef HOTKEY + , false +#endif + ) != ONPLAY_OK) { result = 0; exit = true; Index: firmware/export/config/sansae200.h =================================================================== --- firmware/export/config/sansae200.h (revision 25329) +++ firmware/export/config/sansae200.h (working copy) @@ -214,3 +214,5 @@ #define IRAMORIG 0x40004000 #endif +/* Define this if a programmable hotkey is available */ +#define HOTKEY