From 2816dc9c13f204234b613db5199d2c787a11f0d8 Mon Sep 17 00:00:00 2001 From: Jonathan Gordon Date: Tue, 27 Feb 2007 09:06:30 +0000 Subject: Convert the radio menus to the new system. Change the way the presets are done (in code). git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12500 a1c6a512-1295-4272-9138-f99709370657 --- apps/keymaps/keymap-ondio.c | 7 +- apps/lang/english.lang | 14 ++ apps/menu.c | 3 + apps/recorder/radio.c | 397 +++++++++++++++++--------------------------- apps/recorder/radio.h | 4 +- apps/settings_list.c | 10 +- 6 files changed, 182 insertions(+), 253 deletions(-) diff --git a/apps/keymaps/keymap-ondio.c b/apps/keymaps/keymap-ondio.c index 4274afc29e..401742b363 100644 --- a/apps/keymaps/keymap-ondio.c +++ b/apps/keymaps/keymap-ondio.c @@ -159,7 +159,7 @@ static const struct button_mapping button_context_keyboard[] = { LAST_ITEM_IN_LIST }; /* button_context_keyboard */ - +#if CONFIG_TUNER static const struct button_mapping button_context_radio[] = { { ACTION_FM_MENU, BUTTON_MENU | BUTTON_REPEAT, BUTTON_NONE }, { ACTION_FM_RECORD_DBLPRE, BUTTON_MENU, BUTTON_NONE}, @@ -176,7 +176,7 @@ static const struct button_mapping button_context_radio[] = { LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS) }; - +#endif const struct button_mapping* get_context_mapping( int context ) { switch( context ) @@ -207,9 +207,10 @@ const struct button_mapping* get_context_mapping( int context ) return button_context_recscreen; case CONTEXT_KEYBOARD: return button_context_keyboard; +#if CONFIG_TUNER case CONTEXT_FM: return button_context_radio; - +#endif case CONTEXT_LIST: case CONTEXT_MAINMENU: default: diff --git a/apps/lang/english.lang b/apps/lang/english.lang index d43317a0d4..c081e53ea7 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -10547,3 +10547,17 @@ *: "Cuesheet Support" + + id: LANG_FM_MENU + desc: fm menu title + user: + + *: "FM Radio Menu" + + + *: "FM Radio Menu" + + + *: "FM Radio Menu" + + diff --git a/apps/menu.c b/apps/menu.c index a66652b608..986c6b7034 100644 --- a/apps/menu.c +++ b/apps/menu.c @@ -314,6 +314,9 @@ static char * get_menu_item_name(int selected_item,void * data, char *buffer) /* only MT_MENU or MT_RETURN_ID is allowed in here */ if (type == MT_RETURN_ID) { + if (menu->flags&MENU_DYNAMIC_DESC) + return menu->menu_get_name_and_icon->list_get_name(selected_item, + menu->menu_get_name_and_icon->list_get_name_data, buffer); return (char*)menu->strings[selected_item]; } diff --git a/apps/recorder/radio.c b/apps/recorder/radio.c index 5ee5be14fd..555c3493a0 100644 --- a/apps/recorder/radio.c +++ b/apps/recorder/radio.c @@ -60,6 +60,8 @@ #include "tree.h" #include "dir.h" #include "action.h" +#include "list.h" +#include "menus/exported_menus.h" #if CONFIG_TUNER @@ -101,13 +103,13 @@ #endif static struct fm_region_setting fm_region[] = { /* Europe */ - { LANG_FM_EUROPE, 87500000, 108000000, 50000, DEEMPH_50 BAND_LIM_EU }, + { 87500000, 108000000, 50000, DEEMPH_50 BAND_LIM_EU }, /* US / Canada */ - { LANG_FM_US, 87900000, 107900000, 200000, DEEMPH_75 BAND_LIM_EU }, + { 87900000, 107900000, 200000, DEEMPH_75 BAND_LIM_EU }, /* Japan */ - { LANG_FM_JAPAN, 76000000, 90000000, 100000, DEEMPH_50 BAND_LIM_JP }, + { 76000000, 90000000, 100000, DEEMPH_50 BAND_LIM_JP }, /* Korea */ - { LANG_FM_KOREA, 87500000, 108000000, 100000, DEEMPH_50 BAND_LIM_EU }, + { 87500000, 108000000, 100000, DEEMPH_50 BAND_LIM_EU }, }; static int curr_preset = -1; @@ -123,19 +125,17 @@ static struct fmstation presets[MAX_PRESETS]; static char filepreset[MAX_PATH]; /* preset filename variable */ -static int preset_menu; /* The menu index of the preset list */ -static struct menu_item preset_menu_items[MAX_PRESETS]; static int num_presets = 0; /* The number of presets in the preset list */ static void radio_save_presets(void); -static bool handle_radio_presets(void); +static int handle_radio_presets(void); static bool radio_menu(void); -static bool radio_add_preset(void); -static bool save_preset_list(void); -static bool load_preset_list(void); -static bool clear_preset_list(void); +static int radio_add_preset(void); +static int save_preset_list(void); +static int load_preset_list(void); +static int clear_preset_list(void); -static bool scan_presets(void); +static int scan_presets(void); #ifdef SIMULATOR void radio_set(int setting, int value); @@ -1058,16 +1058,8 @@ void radio_load_presets(char *filename) presets_changed = false; } -static void rebuild_preset_menu(void) -{ - int i; - for(i = 0;i < num_presets;i++) - { - preset_menu_items[i].desc = presets[i].name; - } -} -static bool radio_add_preset(void) +static int radio_add_preset(void) { char buf[MAX_FMPRESET_LEN]; @@ -1083,9 +1075,6 @@ static bool radio_add_preset(void) #ifdef FM_PRESET_ADD /* only for archos */ menu_insert(preset_menu, -1, presets[num_presets].name, 0); - /* We must still rebuild the menu table, since the - item name pointers must be updated */ - rebuild_preset_menu(); #endif num_presets++; presets_changed = true; @@ -1100,52 +1089,32 @@ static bool radio_add_preset(void) return true; } -/* button preprocessor for preset option submenu */ -static int handle_radio_presets_menu_cb(int key, int m) -{ - (void)m; -#ifdef FM_PRESET_ACTION - switch(key) - { - case ACTION_F3: - key = ACTION_STD_CANCEL; /* Fake an exit */ - action_signalscreenchange(); - break; - } -#endif - return key; -} - -static bool radio_edit_preset(void) +/* needed to know which preset we are edit/delete-ing */ +static int selected_preset = 0; +static int radio_edit_preset(void) { - int pos = menu_cursor(preset_menu); char buf[MAX_FMPRESET_LEN]; - strncpy(buf, menu_description(preset_menu, pos), MAX_FMPRESET_LEN); + strncpy(buf, presets[selected_preset].name, MAX_FMPRESET_LEN); if (!kbd_input(buf, MAX_FMPRESET_LEN)) { buf[MAX_FMPRESET_LEN] = 0; - strcpy(presets[pos].name, buf); + strcpy(presets[selected_preset].name, buf); presets_changed = true; } return true; } -static bool radio_delete_preset(void) +static int radio_delete_preset(void) { - int pos = menu_cursor(preset_menu); + int pos = selected_preset; int i; for(i = pos;i < num_presets;i++) presets[i] = presets[i+1]; num_presets--; - - menu_delete(preset_menu, pos); - /* We must still rebuild the menu table, since the - item name pointers must be updated */ - rebuild_preset_menu(); - + /* Don't ask to save when all presets are deleted. */ if(num_presets > 0) presets_changed = true; @@ -1160,12 +1129,12 @@ static bool radio_delete_preset(void) return true; /* Make the menu return immediately */ } -static bool load_preset_list(void) +static int load_preset_list(void) { return !rockbox_browse(FMPRESET_PATH, SHOW_FMR); } -static bool save_preset_list(void) +static int save_preset_list(void) { if(num_presets != 0) { @@ -1218,7 +1187,7 @@ static bool save_preset_list(void) return true; } -static bool clear_preset_list(void) +static int clear_preset_list(void) { int i; @@ -1238,171 +1207,132 @@ static bool clear_preset_list(void) return true; } -/* little menu on what to do with a preset entry */ -static bool handle_radio_presets_menu(void) +MENUITEM_FUNCTION(radio_edit_preset_item, ID2P(LANG_FM_EDIT_PRESET), + radio_edit_preset, NULL, NOICON); +MENUITEM_FUNCTION(radio_delete_preset_item, ID2P(LANG_FM_DELETE_PRESET), + radio_delete_preset, NULL, NOICON); +MAKE_MENU(handle_radio_preset_menu, ID2P(LANG_FM_BUTTONBAR_PRESETS), + NULL, NOICON, &radio_edit_preset_item, &radio_delete_preset_item); +/* present a list of preset stations */ +char * presets_get_name(int selected_item, void * data, char *buffer) { - static const struct menu_item preset_menu_items[] = { - { ID2P(LANG_FM_EDIT_PRESET), radio_edit_preset }, - { ID2P(LANG_FM_DELETE_PRESET), radio_delete_preset }, - }; - int m; - - m = menu_init( preset_menu_items, - sizeof preset_menu_items / sizeof(struct menu_item), - handle_radio_presets_menu_cb, - NULL, NULL, str(LANG_FM_BUTTONBAR_EXIT)); - menu_run(m); - menu_exit(m); - return false; + (void)data; + (void)buffer; + return presets[selected_item].name; } -/* button preprocessor for list of preset stations menu */ -static int handle_radio_presets_cb(int key, int m) +static int handle_radio_presets(void) { - (void)m; - - switch(key) - { -#ifdef FM_PRESET_ADD - case ACTION_STD_MENU: - radio_add_preset(); - menu_draw(m); - key = BUTTON_NONE; - break; -#endif -#if (CONFIG_KEYPAD != IRIVER_H100_PAD) && (CONFIG_KEYPAD != IRIVER_H300_PAD) && (CONFIG_KEYPAD != IAUDIO_X5_PAD) -#ifdef FM_PRESET - case ACTION_STD_QUICKSCREEN: - menu_draw(m); - key = ACTION_STD_CANCEL; /* Fake an exit */ - break; -#endif + struct gui_synclist lists; + int result = 0; + int action = ACTION_NONE; +#ifdef HAS_BUTTONBAR + struct gui_buttonbar buttonbar; #endif - case ACTION_F3: - case ACTION_STD_CONTEXT: - { - bool ret; - ret = handle_radio_presets_menu(); - menu_draw(m); - if(ret) - key = SYS_USB_CONNECTED; - else - key = ACTION_NONE; - break; - } - } - return key; -} -/* present a list of preset stations */ -static bool handle_radio_presets(void) -{ - int result; - bool reload_dir = false; + if(presets_loaded == false) + return result; - if(presets_loaded) - { - rebuild_preset_menu(); - - /* DIY menu handling, since we want to exit after selection */ - preset_menu = menu_init( preset_menu_items, num_presets, - handle_radio_presets_cb, - str(LANG_FM_BUTTONBAR_ADD), +#ifdef HAS_BUTTONBAR + gui_buttonbar_init(&buttonbar); + gui_buttonbar_set_display(&buttonbar, &(screens[SCREEN_MAIN]) ); + gui_buttonbar_set(&buttonbar, str(LANG_FM_BUTTONBAR_ADD), str(LANG_FM_BUTTONBAR_EXIT), str(LANG_FM_BUTTONBAR_ACTION)); - if (curr_preset >= 0) - menu_set_cursor(preset_menu, curr_preset); - result = menu_show(preset_menu); - menu_exit(preset_menu); - if (result == MENU_SELECTED_EXIT) - return false; - else if (result == MENU_ATTACHED_USB) - reload_dir = true; - - if (result >= 0) /* A preset was selected */ + gui_buttonbar_draw(&buttonbar); +#endif + gui_synclist_init(&lists, presets_get_name, NULL, false, 1); + gui_synclist_set_title(&lists, str(LANG_FM_BUTTONBAR_PRESETS), NOICON); + gui_synclist_set_icon_callback(&lists, NULL); + gui_synclist_set_nb_items(&lists, num_presets); + gui_synclist_select_item(&lists, curr_preset<0 ? 0 : curr_preset); + + action_signalscreenchange(); + while (result == 0) + { + gui_synclist_draw(&lists); + gui_syncstatusbar_draw(&statusbars, true); + action = get_action(CONTEXT_STD, HZ); + + gui_synclist_do_button(&lists, action, LIST_WRAP_UNLESS_HELD); + switch (action) { - curr_preset = menu_cursor(preset_menu); - curr_freq = presets[curr_preset].frequency; - radio_set(RADIO_FREQUENCY, curr_freq); - remember_frequency(); + case ACTION_STD_MENU: + radio_add_preset(); + break; + case ACTION_STD_CANCEL: + result = 1; + break; + case ACTION_STD_OK: + curr_preset = gui_synclist_get_sel_pos(&lists); + curr_freq = presets[curr_preset].frequency; + radio_set(RADIO_FREQUENCY, curr_freq); + remember_frequency(); + result = 1; + break; + case ACTION_F3: + case ACTION_STD_CONTEXT: + selected_preset = gui_synclist_get_sel_pos(&lists); + do_menu(&handle_radio_preset_menu); + break; + default: + if(default_event_handler(action) == SYS_USB_CONNECTED) + result = 2; } } - - return reload_dir; -} - -static char monomode_menu_string[32]; - -static void create_monomode_menu(void) -{ - snprintf(monomode_menu_string, sizeof monomode_menu_string, - "%s: %s", str(LANG_FM_MONO_MODE), - global_settings.fm_force_mono? - str(LANG_SET_BOOL_YES):str(LANG_SET_BOOL_NO)); -} - -static bool toggle_mono_mode(void) -{ - global_settings.fm_force_mono = !global_settings.fm_force_mono; - radio_set(RADIO_FORCE_MONO, global_settings.fm_force_mono); - settings_save(); - create_monomode_menu(); - return false; + action_signalscreenchange(); + return result - 1; } -static char region_menu_string[32]; -static void create_region_menu(void) +void toggle_mono_mode(bool mono) { - snprintf(region_menu_string, sizeof(region_menu_string), - "%s: %s", str(LANG_FM_REGION), - str(fm_region[global_settings.fm_region].lang)); + radio_set(RADIO_FORCE_MONO, mono); } -static bool toggle_region_mode(void) +void set_radio_region(int region) { - global_settings.fm_region++; - if(global_settings.fm_region >= - (int)(sizeof(fm_region) / sizeof(struct fm_region_setting))) - global_settings.fm_region = 0; #if (CONFIG_TUNER & TEA5767) radio_set(RADIO_SET_DEEMPHASIS, - fm_region[global_settings.fm_region].deemphasis); - radio_set(RADIO_SET_BAND, fm_region[global_settings.fm_region].band); + fm_region[region].deemphasis); + radio_set(RADIO_SET_BAND, fm_region[region].band); #endif /* make sure the current frequency is in the region range */ - curr_freq -= (curr_freq - fm_region[global_settings.fm_region].freq_min) - % fm_region[global_settings.fm_region].freq_step; - if(curr_freq < fm_region[global_settings.fm_region].freq_min) - curr_freq = fm_region[global_settings.fm_region].freq_min; - if(curr_freq > fm_region[global_settings.fm_region].freq_max) - curr_freq = fm_region[global_settings.fm_region].freq_max; + curr_freq -= (curr_freq - fm_region[region].freq_min) + % fm_region[region].freq_step; + if(curr_freq < fm_region[region].freq_min) + curr_freq = fm_region[region].freq_min; + if(curr_freq > fm_region[region].freq_max) + curr_freq = fm_region[region].freq_max; radio_set(RADIO_FREQUENCY, curr_freq); remember_frequency(); - create_region_menu(); - return false; } -#ifndef FM_MODE -static char radiomode_menu_string[32]; +MENUITEM_SETTING(set_region, &global_settings.fm_region, NULL); +MENUITEM_SETTING(force_mono, &global_settings.fm_force_mono, NULL); -static void create_radiomode_menu(void) +#ifndef FM_MODE +char* get_mode_text(int selected_item, void * data, char *buffer) { - snprintf(radiomode_menu_string, 32, "%s %s", str(LANG_FM_TUNE_MODE), + (void)selected_item; + (void)data; + snprintf(buffer, MAX_PATH, "%s %s", str(LANG_FM_TUNE_MODE), radio_mode ? str(LANG_RADIO_PRESET_MODE) : str(LANG_RADIO_SCAN_MODE)); + return buffer; } - -static bool toggle_radio_mode(void) +static int toggle_radio_mode(void* param) { + (void)param; radio_mode = (radio_mode == RADIO_SCAN_MODE) ? RADIO_PRESET_MODE : RADIO_SCAN_MODE; - create_radiomode_menu(); - return false; + return 0; } +MENUITEM_FUNCTION_WPARAM_DYNTEXT(radio_mode_item, toggle_radio_mode, NULL, NULL, + get_mode_text, NULL, NOICON); #endif -static bool scan_presets(void) +static int scan_presets(void) { bool tuned = false, do_scan = true; char buf[MAX_FMPRESET_LEN]; @@ -1473,41 +1403,13 @@ static bool scan_presets(void) return true; } -/* button preprocessor for the main menu */ -static int radio_menu_cb(int key, int m) -{ - (void)m; -#if 0 /* this screen needs fixing! */ - switch(key) - { -#if (CONFIG_KEYPAD != IRIVER_H100_PAD) && (CONFIG_KEYPAD != IRIVER_H300_PAD) && (CONFIG_KEYPAD != IAUDIO_X5_PAD) -#ifdef MENU_ENTER2 - case MENU_ENTER2: -#endif -#endif - case MENU_ENTER: - key = BUTTON_NONE; /* eat the downpress, next menu reacts on release */ - break; - -#if (CONFIG_KEYPAD != IRIVER_H100_PAD) && (CONFIG_KEYPAD != IRIVER_H300_PAD) && (CONFIG_KEYPAD != IAUDIO_X5_PAD) -#ifdef MENU_ENTER2 - case MENU_ENTER2 | BUTTON_REL: -#endif -#endif - case MENU_ENTER | BUTTON_REL: - key = MENU_ENTER; /* fake downpress, next menu doesn't like release */ - break; - } -#endif - return key; -} #ifndef SIMULATOR #ifdef HAVE_RECORDING #if defined(HAVE_FMRADIO_IN) && CONFIG_CODEC == SWCODEC #define FM_RECORDING_SCREEN -static bool fm_recording_screen(void) +static int fm_recording_screen(void) { bool ret; @@ -1516,7 +1418,7 @@ static bool fm_recording_screen(void) global_settings.rec_source = AUDIO_SRC_FMRADIO; /* clearing queue seems to cure a spontaneous abort during record */ - while (button_get(false) != BUTTON_NONE); + action_signalscreenchange(); ret = recording_screen(true); @@ -1525,11 +1427,13 @@ static bool fm_recording_screen(void) return ret; } +MENUITEM_FUNCTION(recscreen_item, ID2P(LANG_RECORDING_MENU), + fm_recording_screen, NULL, NOICON); #endif /* defined(HAVE_FMRADIO_IN) && CONFIG_CODEC == SWCODEC */ #if defined(HAVE_FMRADIO_IN) || CONFIG_CODEC != SWCODEC #define FM_RECORDING_SETTINGS -static bool fm_recording_settings(void) +static int fm_recording_settings(void) { bool ret = recording_menu(true); @@ -1545,54 +1449,55 @@ static bool fm_recording_settings(void) return ret; } +MENUITEM_FUNCTION(recsettings_item, ID2P(LANG_RECORDING_SETTINGS), + fm_recording_settings, NULL, NOICON); #endif /* defined(HAVE_FMRADIO_IN) || CONFIG_CODEC != SWCODEC */ #endif /* HAVE_RECORDING */ #endif /* SIMULATOR */ +#ifndef FM_PRESET +MENUITEM_FUNCTION(radio_presets_item, ID2P(LANG_FM_BUTTONBAR_PRESETS), + handle_radio_presets, NULL, NOICON); +#endif +#ifndef FM_PRESET_ADD +MENUITEM_FUNCTION(radio_addpreset_item, ID2P(LANG_FM_ADD_PRESET), + radio_add_preset, NULL, NOICON); +#endif -/* main menu of the radio screen */ -static bool radio_menu(void) -{ - int m; - bool result; - - static const struct menu_item items[] = { -/* Add functions not accessible via buttons */ +MENUITEM_FUNCTION(presetload_item, ID2P(LANG_FM_PRESET_LOAD), + load_preset_list, NULL, NOICON); +MENUITEM_FUNCTION(presetsave_item, ID2P(LANG_FM_PRESET_SAVE), + save_preset_list, NULL, NOICON); +MENUITEM_FUNCTION(presetclear_item, ID2P(LANG_FM_PRESET_CLEAR), + clear_preset_list, NULL, NOICON); +MENUITEM_FUNCTION(scan_presets_item, ID2P(LANG_FM_SCAN_PRESETS), + scan_presets, NULL, NOICON); + +MAKE_MENU(radio_menu_items, ID2P(LANG_FM_MENU), NULL, + bitmap_icons_6x8[Icon_Radio_screen], #ifndef FM_PRESET - { ID2P(LANG_FM_BUTTONBAR_PRESETS), handle_radio_presets }, + &radio_presets_item, #endif #ifndef FM_PRESET_ADD - { ID2P(LANG_FM_ADD_PRESET) , radio_add_preset }, + &radio_addpreset_item, #endif - { ID2P(LANG_FM_PRESET_LOAD) , load_preset_list }, - { ID2P(LANG_FM_PRESET_SAVE) , save_preset_list }, - { ID2P(LANG_FM_PRESET_CLEAR) , clear_preset_list }, - - { monomode_menu_string , toggle_mono_mode }, + &presetload_item, &presetsave_item, &presetclear_item, + &force_mono, #ifndef FM_MODE - { radiomode_menu_string , toggle_radio_mode }, + &radio_mode_item, #endif - { region_menu_string , toggle_region_mode }, - { ID2P(LANG_SOUND_SETTINGS) , sound_menu }, + &set_region, &sound_settings, #ifdef FM_RECORDING_SCREEN - { ID2P(LANG_RECORDING_MENU) , fm_recording_screen }, + &LANG_RECORDING_MENU, #endif #ifdef FM_RECORDING_SETTINGS - { ID2P(LANG_RECORDING_SETTINGS) , fm_recording_settings }, -#endif - { ID2P(LANG_FM_SCAN_PRESETS) , scan_presets }, - }; - - create_monomode_menu(); - create_region_menu(); -#ifndef FM_MODE - create_radiomode_menu(); + &recsettings_item, #endif - m = menu_init(items, sizeof(items) / sizeof(*items), - radio_menu_cb, NULL, NULL, NULL); - result = menu_run(m); - menu_exit(m); - return result; + &scan_presets_item); +/* main menu of the radio screen */ +static bool radio_menu(void) +{ + return (bool)do_menu(&radio_menu_items); } #endif diff --git a/apps/recorder/radio.h b/apps/recorder/radio.h index bbc35b71aa..4647ae2756 100644 --- a/apps/recorder/radio.h +++ b/apps/recorder/radio.h @@ -32,6 +32,9 @@ void radio_pause(void); void radio_stop(void); bool radio_hardware_present(void); bool in_radio_screen(void); +/* callbacks for the radio settings */ +void set_radio_region(int region); +void toggle_mono_mode(bool mono); #define MAX_FMPRESET_LEN 27 @@ -43,7 +46,6 @@ struct fmstation struct fm_region_setting { - int lang; int freq_min; int freq_max; int freq_step; diff --git a/apps/settings_list.c b/apps/settings_list.c index 4442e3181f..b3a48553f1 100644 --- a/apps/settings_list.c +++ b/apps/settings_list.c @@ -43,6 +43,9 @@ #include "peakmeter.h" #endif #include "menus/eq_menu.h" +#if CONFIG_TUNER +#include "radio.h" +#endif /* some sets of values which are used more than once, to save memory */ static const char off_on[] = "off,on"; @@ -474,7 +477,7 @@ const struct settings_list settings[] = { /* tuner */ #if CONFIG_TUNER OFFON_SETTING(0,fm_force_mono, LANG_FM_MONO_MODE, - false,"force fm mono", NULL), + false, "force fm mono", toggle_mono_mode), SYSTEM_SETTING(NVRAM(4),last_frequency,0), #endif @@ -1046,8 +1049,9 @@ const struct settings_list settings[] = { "disable autoresume if phones not present",NULL), #endif #if CONFIG_TUNER - {F_T_INT,&global_settings.fm_region,LANG_FM_REGION,INT(0), - "fm_region","eu,us,jp,kr",UNUSED}, + CHOICE_SETTING(0, fm_region, LANG_FM_REGION, 0, + "fm_region", "eu,us,jp,kr", set_radio_region, 4, ID2P(LANG_FM_EUROPE), + ID2P(LANG_FM_US), ID2P(LANG_FM_JAPAN), ID2P(LANG_FM_KOREA)), #endif OFFON_SETTING(0,audioscrobbler,LANG_AUDIOSCROBBLER, -- cgit v1.2.3