Index: apps/screens.c
===================================================================
--- apps/screens.c	(revision 12296)
+++ apps/screens.c	(working copy)
@@ -655,9 +655,6 @@
         [SHOW_SUPPORTED]={ STR(LANG_SYSFONT_FILTER_SUPPORTED) },
         [SHOW_MUSIC]={ STR(LANG_SYSFONT_FILTER_MUSIC) },
         [SHOW_PLAYLIST]={ STR(LANG_SYSFONT_FILTER_PLAYLIST) },
-#ifdef HAVE_TAGCACHE
-        [SHOW_ID3DB]={ STR(LANG_SYSFONT_FILTER_ID3DB) }
-#endif
     };
     static const struct opt_items right_items[] = {
         [REPEAT_OFF]={ STR(LANG_SYSFONT_OFF) },
Index: apps/main_menu.c
===================================================================
--- apps/main_menu.c	(revision 12296)
+++ apps/main_menu.c	(working copy)
@@ -380,9 +380,6 @@
     if(inside_menu) return false;
     inside_menu = true;
 
-    items[i].desc = ID2P(LANG_BOOKMARK_MENU_RECENT_BOOKMARKS);
-    items[i++].function = bookmark_mrb_load;
-
     items[i].desc = ID2P(LANG_SOUND_SETTINGS);
     items[i++].function = sound_menu;
 
@@ -395,24 +392,9 @@
     items[i].desc = ID2P(LANG_CUSTOM_THEME);
     items[i++].function = custom_theme_browse;
 
-#ifdef CONFIG_TUNER
-    if(radio_hardware_present()) {
-        items[i].desc = ID2P(LANG_FM_RADIO);
-        items[i++].function = radio_screen;
-    }
-#endif
-
-#ifdef HAVE_RECORDING
-    items[i].desc = ID2P(LANG_RECORDING);
-    items[i++].function = rec_menu;
-#endif
-
     items[i].desc = ID2P(LANG_PLAYLIST_MENU);
     items[i++].function = playlist_menu;
 
-    items[i].desc = ID2P(LANG_PLUGINS);
-    items[i++].function = plugin_browse;
-
     items[i].desc = ID2P(LANG_INFO);
     items[i++].function = info_menu;
 
Index: apps/recorder/radio.c
===================================================================
--- apps/recorder/radio.c	(revision 12296)
+++ apps/recorder/radio.c	(working copy)
@@ -60,6 +60,7 @@
 #include "tree.h"
 #include "dir.h"
 #include "action.h"
+#include "root_menu.h"
 
 #ifdef CONFIG_TUNER
 
@@ -365,11 +366,12 @@
 }
 
 
-bool radio_screen(void)
+int radio_screen(void)
 {
     char buf[MAX_PATH];
     bool done = false;
     int button, lastbutton = BUTTON_NONE;
+    int ret_val = GO_TO_ROOT;
 #ifdef FM_RECORD_DBLPRE
     unsigned long rec_lastclick = 0;
 #endif
@@ -582,7 +584,7 @@
 #endif
                 keep_playing = true;
                 done = true;
-                
+                ret_val = GO_TO_ROOT;
                 if(presets_changed)
                 {
                     if(yesno_pop(str(LANG_FM_SAVE_CHANGES)))
@@ -596,7 +598,7 @@
                 
                 /* Clear the preset list on exit. */
                 clear_preset_list();
-                    
+                
                 break;
 
             case ACTION_STD_PREV:
Index: apps/recorder/radio.h
===================================================================
--- apps/recorder/radio.h	(revision 12296)
+++ apps/recorder/radio.h	(working copy)
@@ -26,7 +26,7 @@
 #ifdef CONFIG_TUNER
 void radio_load_presets(char *filename);
 void radio_init(void);
-bool radio_screen(void);
+int radio_screen(void);
 void radio_start(void);
 void radio_pause(void);
 void radio_stop(void);
Index: apps/tree.c
===================================================================
--- apps/tree.c	(revision 12296)
+++ apps/tree.c	(working copy)
@@ -79,6 +79,7 @@
 #include "textarea.h"
 #include "action.h"
 
+#include "root_menu.h"
 
 #if LCD_DEPTH > 1
 #include "backdrop.h"
@@ -158,7 +159,7 @@
 static bool reload_dir = false;
 
 static bool start_wps = false;
-static bool dirbrowse(void);
+static int dirbrowse(void);
 static int curr_context = false;/* id3db or tree*/
 
 /*
@@ -270,6 +271,8 @@
     gui_synclist_init(&tree_lists, &tree_get_filename, &tc, false, 1);
     gui_synclist_set_icon_callback(&tree_lists,
                   global_settings.show_icons?&tree_get_fileicon:NULL);
+    root_menu();
+    /*
 #ifndef SIMULATOR
     dirbrowse();
 #else
@@ -277,6 +280,7 @@
         DEBUGF("No filesystem found. Have you forgotten to create it?\n");
     }
 #endif
+*/
 }
 
 void tree_get_filetypes(const struct filetype** types, int* count)
@@ -603,7 +607,7 @@
 #endif
 
 /* main loop, handles key events */
-static bool dirbrowse(void)
+static int dirbrowse(void)
 {
     int numentries=0;
     char buf[MAX_PATH];
@@ -634,27 +638,6 @@
     lastfirstpos = 0;
 #endif
 
-    if (*tc.dirfilter < NUM_FILTER_MODES) {
-#ifdef HAVE_RECORDING
-#ifndef SIMULATOR
-        if (global_settings.rec_startup) {
-            /* We fake being in the menu structure by calling
-               the appropriate parent when we drop out of each screen */
-#if CONFIG_CODEC == SWCODEC
-            /* Put in a 1 sec pause to slow bootup or the recording codecs
-               won't initialize */
-            sleep(HZ);
-#endif
-            recording_screen(false);
-            rec_menu();
-            main_menu();
-        }
-        else
-#endif
-#endif
-        start_resume(true);
-
-    }
     /* If we don't need to show the wps, draw the dir */
     if (!start_wps) {
         numentries = update_dir();
@@ -770,37 +753,17 @@
                 /* don't enter menu from plugin browser */
                 if (*tc.dirfilter < NUM_FILTER_MODES)
                 {
-                    int i;
-                    FOR_NB_SCREENS(i)
-                        screens[i].stop_scroll();
-                    action_signalscreenchange();
-                    if (main_menu())
-                        reload_dir = true;
-                    restore = true;
-
-#ifdef HAVE_TAGCACHE
-                    id3db = check_changed_id3mode(id3db);
-                    if(id3db)
-                        reload_dir = true;
-#endif
+                    return GO_TO_ROOT;
                 }
                 else /* use it as a quick exit instead */
-                    exit_func = true;
+                    return GO_TO_PREVIOUS;
                 break;
 
             case ACTION_TREE_WPS:
                 /* don't enter wps from plugin browser etc */
                 if (*tc.dirfilter < NUM_FILTER_MODES)
                 {
-                    if (audio_status() & AUDIO_STATUS_PLAY)
-                    {
-                        start_wps=true;
-                    }
-                    else
-                    {
-                        start_resume(false);
-                        restore = true;
-                    }
+                    return GO_TO_WPS;
                 }
                 break;
 #ifdef HAVE_QUICKSCREEN
@@ -876,7 +839,7 @@
                         break;
 
                     case ONPLAY_START_PLAY:
-                        start_wps = true;
+                        return GO_TO_WPS;
                         break;
                 }
                 break;
@@ -950,38 +913,14 @@
                 }
                 break;
         }
-
+        if (start_wps)
+            return GO_TO_WPS;
         if ( button )
         {
             ata_spin();
         }
 
-        if (start_wps && audio_status() )
-        {
-            int i;
 
-            FOR_NB_SCREENS(i)
-                screens[i].stop_scroll();
-
-            if (gui_wps_show() == SYS_USB_CONNECTED)
-                reload_dir = true;
-#ifdef HAVE_HOTSWAP
-            else
-#ifdef HAVE_TAGCACHE
-                if (!id3db) /* Try reload to catch 'no longer valid' case. */
-#endif
-                    reload_dir = true;
-#endif
-#if LCD_DEPTH > 1
-            show_main_backdrop();
-#endif
-#ifdef HAVE_TAGCACHE
-            id3db = check_changed_id3mode(id3db);
-#endif
-            restore = true;
-            start_wps=false;
-        }
-
     check_rescan:
         /* do we need to rescan dir? */
         if (reload_dir || reload_root ||
@@ -1014,7 +953,7 @@
         }
 
         if (exit_func)
-            break;
+            return GO_TO_PREVIOUS;
 
         if (restore || reload_dir) {
             /* restore display */
@@ -1250,24 +1189,35 @@
     return true;
 }
 
-bool rockbox_browse(const char *root, int dirfilter)
+int rockbox_browse(const char *root, int dirfilter)
 {
-    static struct tree_context backup;
-    int last_context;
-    
-    backup = tc;
+    int ret_val = 0;
     reload_dir = true;
-    memcpy(tc.currdir, root, sizeof(tc.currdir));
-    start_wps = false;
-    tc.dirfilter = &dirfilter;
-    last_context = curr_context;
+    if (dirfilter >= NUM_FILTER_MODES)
+    {
+        static struct tree_context backup;
+        int last_context;
+        
+        backup = tc;
+        memcpy(tc.currdir, root, sizeof(tc.currdir));
+        start_wps = false;
+        tc.dirfilter = &dirfilter;
+        last_context = curr_context;
+        
+        ret_val = dirbrowse();
     
-    dirbrowse();
-
-    tc = backup;
-    curr_context = last_context;
-    
-    return false;
+        tc = backup;
+        curr_context = last_context;
+    }
+    else
+    {   
+        static char buf[MAX_PATH];
+        strcpy(buf,root);
+        *tc.dirfilter = dirfilter;
+        set_current_file(buf);
+        ret_val = dirbrowse();
+    }
+    return ret_val;
 }
 
 void tree_init(void)
Index: apps/lang/english.lang
===================================================================
--- apps/lang/english.lang	(revision 12296)
+++ apps/lang/english.lang	(working copy)
@@ -328,13 +328,13 @@
   desc: in the main menu
   user:
   <source>
-    *: "Browse Plugins"
+    *: "Plugins"
   </source>
   <dest>
-    *: "Browse Plugins"
+    *: "Plugins"
   </dest>
   <voice>
-    *: "Browse Plugins"
+    *: "Plugins"
   </voice>
 </phrase>
 <phrase>
@@ -10515,3 +10515,87 @@
     *: ""
   </voice>
 </phrase>
+<phrase>
+  id: LANG_DIR_BROWSER
+  desc: in root menu
+  user:
+  <source>
+    *: "Files"
+  </source>
+  <dest>
+    *: "Files"
+  </dest>
+  <voice>
+    *: "Files"
+  </voice>
+</phrase>
+<phrase>
+  id: LANG_SETTINGS_MENU
+  desc: in root menu
+  user:
+  <source>
+    *: "Settings"
+  </source>
+  <dest>
+    *: "Settings"
+  </dest>
+  <voice>
+    *: "Settings"
+  </voice>
+</phrase>
+<phrase>
+  id: LANG_NOW_PLAYING
+  desc: in root menu
+  user:
+  <source>
+    *: "Now Playing"
+  </source>
+  <dest>
+    *: "Now Playing"
+  </dest>
+  <voice>
+    *: "Now Playing"
+  </voice>
+</phrase>
+<phrase>
+  id: LANG_RESUME_PLAYBACK
+  desc: in root menu
+  user:
+  <source>
+    *: "Resume Playback"
+  </source>
+  <dest>
+    *: "Resume Playback"
+  </dest>
+  <voice>
+    *: "Resume Playback"
+  </voice>
+</phrase>
+<phrase>
+  id: LANG_START_SCREEN
+  desc: in root menu setting
+  user:
+  <source>
+    *: "Start Screen"
+  </source>
+  <dest>
+    *: "Start Screen"
+  </dest>
+  <voice>
+    *: "Start Screen"
+  </voice>
+</phrase>
+<phrase>
+  id: LANG_ROCKBOX_TITLE
+  desc: in root menu
+  user:
+  <source>
+    *: "Rockbox"
+  </source>
+  <dest>
+    *: "Rockbox"
+  </dest>
+  <voice>
+    *: "Rockbox"
+  </voice>
+</phrase>
Index: apps/gui/gwps.c
===================================================================
--- apps/gui/gwps.c	(revision 12296)
+++ apps/gui/gwps.c	(working copy)
@@ -58,6 +58,7 @@
 #include "backdrop.h"
 #endif
 #include "ata_idle_notify.h"
+#include "root_menu.h"
 
 #define WPS_DEFAULTCFG WPS_DIR "/rockbox_default.wps"
 #define RWPS_DEFAULTCFG WPS_DIR "/rockbox_default.rwps"
@@ -263,7 +264,7 @@
                     wps_state.current_track_path[0] != '\0')
                     set_current_file(wps_state.current_track_path);
                 action_signalscreenchange();
-                return 0;
+                return GO_TO_PREVIOUS_BROWSER;
                 break;
 
                 /* play/pause */
@@ -453,23 +454,7 @@
             case ACTION_WPS_MENU:
                 FOR_NB_SCREENS(i)
                     gui_wps[i].display->stop_scroll();
-
-#if LCD_DEPTH > 1
-                show_main_backdrop();
-#endif
-                action_signalscreenchange();
-                if (main_menu())
-                    return true;
-#if LCD_DEPTH > 1
-                show_wps_backdrop();
-#endif
-#ifdef HAVE_LCD_BITMAP
-                FOR_NB_SCREENS(i)
-                {
-                    gui_wps_set_margin(&gui_wps[i]);
-                }
-#endif
-                restore = true;
+                return GO_TO_ROOT;
                 break;
 
 
@@ -627,7 +612,7 @@
                 wps_state.current_track_path[0] != '\0')
                 set_current_file(wps_state.current_track_path);
 
-            return 0;
+            return GO_TO_ROOT;
         }
 
         if ( button )
@@ -646,7 +631,7 @@
                     wps_state.current_track_path[0] != '\0')
                     set_current_file(wps_state.current_track_path);
 
-                return 0;
+                return GO_TO_ROOT;
             }
 
             if (wps_state.id3){
@@ -655,7 +640,7 @@
             }
         }
     }
-    return 0; /* unreachable - just to reduce compiler warnings */
+    return GO_TO_ROOT; /* unreachable - just to reduce compiler warnings */
 }
 
 /* needs checking if needed end*/
Index: apps/menu.c
===================================================================
--- apps/menu.c	(revision 12296)
+++ apps/menu.c	(working copy)
@@ -44,6 +44,7 @@
 #include "action.h"
 #include "menus/exported_menus.h"
 #include "string.h"
+#include "root_menu.h"
 
 #ifdef HAVE_LCD_BITMAP
 #include "icons.h"
@@ -348,7 +349,14 @@
         return current_subitems[selected_item];
     return selected_item;
 }
-
+static int find_menu_selection(int selected)
+{
+    int i;
+    for (i=0; i< current_subitems_count; i++)
+        if (current_subitems[i] == selected)
+            return i;
+    return 0;
+}
 static char * get_menu_item_name(int selected_item,void * data, char *buffer)
 {
     const struct menu_item_ex *menu = (const struct menu_item_ex *)data;
@@ -405,7 +413,7 @@
     gui_synclist_set_icon_callback(lists,NULL);
     gui_synclist_set_nb_items(lists,current_subitems_count);
     gui_synclist_limit_scroll(lists,true);
-    gui_synclist_select_item(lists, selected);
+    gui_synclist_select_item(lists, find_menu_selection(selected));
     
     get_menu_callback(menu,&menu_callback);
     if (callback && menu_callback)
@@ -421,22 +429,22 @@
         int sel = get_menu_selection(gui_synclist_get_sel_pos(lists),menu);
         if ((menu->flags&MENU_TYPE_MASK) == MT_MENU)
         {
-           if ((menu->submenus[sel]->flags&MENU_TYPE_MASK) == MT_SETTING)
-               talk_setting(menu->submenus[sel]->variable);
-           else 
-           {
-               id = P2ID(menu->submenus[sel]->callback_and_desc->desc);
-               if (id != -1)
+            if ((menu->submenus[sel]->flags&MENU_TYPE_MASK) == MT_SETTING)
+                talk_setting(menu->submenus[sel]->variable);
+            else 
+            {
+                id = P2ID(menu->submenus[sel]->callback_and_desc->desc);
+                if (id != -1)
                    talk_id(id,false);
-           }
+            }
         }
     }
 }
 #define MAX_OPTIONS 32
-int do_menu(const struct menu_item_ex *start_menu)
+int do_menu(const struct menu_item_ex *start_menu, int *start_selected)
 {
+    int selected = start_selected? *start_selected : 0;
     int action;
-    int selected = 0;
     struct gui_synclist lists;
     const struct menu_item_ex *temp, *menu;
     int ret = 0;
@@ -481,7 +489,7 @@
         }
         else if (action == ACTION_MENU_WPS)
         {
-            ret = MENU_RETURN_TO_WPS;
+           return GO_TO_WPS;
         }
         else if ((action == ACTION_STD_CANCEL) ||
                  (action == ACTION_STD_MENU))
@@ -503,7 +511,7 @@
                                  menu_stack_selected_item[stack_top], false);
                 talk_menu_item(menu, &lists);
             }
-            else 
+            else if (menu != &root_menu_)
             {
                 break;
             }
@@ -530,8 +538,7 @@
                     if (stack_top < MAX_MENUS)
                     {
                         menu_stack[stack_top] = menu;
-                        menu_stack_selected_item[stack_top]
-                                = gui_synclist_get_sel_pos(&lists);
+                        menu_stack_selected_item[stack_top] = selected;
                         stack_top++;
                         init_menu_lists(temp, &lists, 0, true);
                         menu = temp;
@@ -664,6 +671,10 @@
                         in_stringlist = true;
                     }
                     break;
+                case MT_RETURN_VALUE:
+                    if (start_selected)
+                        *start_selected = selected;
+                    return temp->value;
             }
             get_menu_callback(temp,&menu_callback);
             if (type != MT_MENU && menu_callback)
@@ -675,10 +686,12 @@
         gui_synclist_draw(&lists);
     }
     action_signalscreenchange();
+    if (start_selected)
+        *start_selected = selected;
     return ret;
 }
 
 int main_menu(void)
 {
-    return do_menu(NULL);
+    return do_menu(NULL, 0);
 }
Index: apps/tree.h
===================================================================
--- apps/tree.h	(revision 12296)
+++ apps/tree.h	(working copy)
@@ -100,7 +100,7 @@
 void tree_init(void);
 void browse_root(void);
 void set_current_file(char *path);
-bool rockbox_browse(const char *root, int dirfilter);
+int rockbox_browse(const char *root, int dirfilter);
 bool create_playlist(void);
 void resume_directory(const char *dir);
 char *getcwd(char *buf, int size);
Index: apps/settings.h
===================================================================
--- apps/settings.h	(revision 12296)
+++ apps/settings.h	(working copy)
@@ -277,6 +277,7 @@
     int last_frequency;  /* Last frequency for resuming, in FREQ_STEP units,
                             relative to MIN_FREQ */
 #endif
+    char last_screen;
 };
 
 struct user_settings
@@ -683,6 +684,7 @@
 #endif
     /* Encoder Settings End */
 #endif /* CONFIG_CODEC == SWCODEC */
+    int start_in_screen;
 };
 
 /** global variables **/
Index: apps/menus/playlist_menu.c
===================================================================
--- apps/menus/playlist_menu.c	(revision 12296)
+++ apps/menus/playlist_menu.c	(working copy)
@@ -79,5 +79,5 @@
 
 bool playlist_menu(void)
 {
-    return do_menu(&playlist_menu_item);
+    return do_menu(&playlist_menu_item, NULL);
 }
Index: apps/menus/main_menu.c
===================================================================
--- apps/menus/main_menu.c	(revision 12296)
+++ apps/menus/main_menu.c	(working copy)
@@ -38,44 +38,23 @@
 #endif
 #include "bookmark.h"
 
-/* lazy coders can use this function if the needed callback 
-	is just to say if the item is shown or not */
-int dynamicitem_callback(int action,const struct menu_item_ex *this_item);
 
 /***********************************/
 /*    MAIN MENU                    */
 
-struct browse_folder_info {
-	const char* dir;
-	int show_options;
-};
-static struct browse_folder_info theme = {THEME_DIR, SHOW_CFG};
-static struct browse_folder_info rocks = {PLUGIN_DIR, SHOW_PLUGINS};
-static int browse_folder(void *param)
+static int themes_browse(void)
 {
-	const struct browse_folder_info *info =
-		(const struct browse_folder_info*)param;
-    return rockbox_browse(info->dir, info->show_options);
+	return rockbox_browse(THEME_DIR, SHOW_CFG);
 }
-MENUITEM_FUNCTION_WPARAM(browse_themes, ID2P(LANG_CUSTOM_THEME), 
-		browse_folder, (void*)&theme, NULL);
-MENUITEM_FUNCTION_WPARAM(browse_plugins, ID2P(LANG_PLUGINS),
-		browse_folder, (void*)&rocks, NULL);
+MENUITEM_FUNCTION(browse_themes, ID2P(LANG_CUSTOM_THEME), 
+		themes_browse, NULL);
 
-#ifdef CONFIG_TUNER
-MENUITEM_FUNCTION(load_radio_screen, ID2P(LANG_FM_RADIO),
-                   (menu_function)radio_screen, dynamicitem_callback);
-#endif
-
 #include "settings_menu.h"
 MENUITEM_FUNCTION(manage_settings_menu_item, ID2P(LANG_MANAGE_MENU),
                 (menu_function)manage_settings_menu, NULL);
 bool info_menu(void); /* from apps/main_menu.c TEMP*/
 MENUITEM_FUNCTION(info_menu_item, ID2P(LANG_INFO),
                 (menu_function)info_menu, NULL);
-MENUITEM_FUNCTION(mrb_bookmarks, ID2P(LANG_BOOKMARK_MENU_RECENT_BOOKMARKS),
-                   (menu_function)bookmark_mrb_load, NULL);
-
 #ifdef HAVE_LCD_CHARCELLS
 static int do_shutdown(void)
 {
@@ -88,38 +67,15 @@
 /* NOTE: This title will be translatable once we decide what to call this menu
          when the root menu comes in... hopefully in the next few days */
 MAKE_MENU(main_menu_, "Rockbox Main Menu", NULL,
-        &mrb_bookmarks, &sound_settings,
+        &sound_settings,
         &settings_menu_item, &manage_settings_menu_item, &browse_themes,
-#ifdef CONFIG_TUNER
-        &load_radio_screen,
-#endif
 #ifdef HAVE_RECORDING
         &recording_settings_menu,
 #endif
-        &playlist_menu_item, &browse_plugins, &info_menu_item
+        &playlist_menu_item, &info_menu_item
 #ifdef HAVE_LCD_CHARCELLS
         ,&do_shutdown_item
 #endif
         );
 /*    MAIN MENU                    */
 /***********************************/
-
-/* lazy coders can use this function if the needed 
-   callback is just to say if the item is shown or not */
-int dynamicitem_callback(int action,const struct menu_item_ex *this_item)
-{
-    if (action != ACTION_ENTER_MENUITEM)
-        return action;
-	
-#ifdef CONFIG_TUNER
-    if (this_item == &load_radio_screen)
-    {
-        if (radio_hardware_present() == 0)
-            return ACTION_EXIT_MENUITEM;
-    }
-#else
-    (void)this_item;
-#endif
-
-    return action;
-}
Index: apps/menus/sound_menu.c
===================================================================
--- apps/menus/sound_menu.c	(revision 12296)
+++ apps/menus/sound_menu.c	(working copy)
@@ -124,5 +124,5 @@
 
 bool sound_menu(void)
 {
-    return do_menu(&sound_settings);
+    return do_menu(&sound_settings, 0);
 }
Index: apps/menu.h
===================================================================
--- apps/menu.h	(revision 12296)
+++ apps/menu.h	(working copy)
@@ -60,6 +60,7 @@
     MT_FUNCTION_CALL, /* used when the standard code wont work */
     MT_FUNCTION_WITH_PARAM,
     MT_RETURN_ID, /* returns the position of the selected item (starting at 0)*/
+    MT_RETURN_VALUE, /* returns a value associated with an item */
 };
 
 typedef int (*menu_function)(void);
@@ -83,6 +84,7 @@
         const struct menu_func_with_param 
                                 *func_with_param; /* MT_FUNCTION_WITH_PARAM */
         const char **strings; /* used with MT_RETURN_ID */
+        int value; /* MT_RETURN_VALUE */
     };
     union {
         int (*menu_callback)(int action, const struct menu_item_ex *this_item);
@@ -96,7 +98,7 @@
 
 typedef int (*menu_callback_type)(int action,
                                   const struct menu_item_ex *this_item);
-int do_menu(const struct menu_item_ex *menu);
+int do_menu(const struct menu_item_ex *menu, int *start_selected);
 
 #define MENU_ITEM_COUNT(c) (c<<MENU_COUNT_SHIFT)
 /* In all the following macros the argument names are as follows:
@@ -125,6 +127,13 @@
          MENU_ITEM_COUNT(sizeof( name##_)/sizeof(*name##_)),            \
             { .submenus = name##_},{.callback_and_desc = & name##__}};
             
+/* returns a value associated with the item */
+#define MENUITEM_RETURNVALUE(name, str, val, cb)                      \
+     static const struct menu_callback_with_desc name##_ = {cb,str};     \
+     static const struct menu_item_ex name   =                                  \
+         { MT_RETURN_VALUE|MENU_HAS_DESC, { .value = val},             \
+         {.callback_and_desc = & name##_}};
+         
 /* This one should be static'ed also, 
    but cannot be done untill settings menu is done */
 /*  Use this to put a function call into the menu.
@@ -144,7 +153,7 @@
         { MT_FUNCTION_WITH_PARAM|MENU_HAS_DESC,                             \
             { .func_with_param = &name##__},                                \
             {.callback_and_desc = & name##_}};
-
+            
 /*  Use this to actually create a menu. the ... argument is a list of pointers 
     to any of the above macro'd variables. (It can also have other menus in the list. */
 #define MAKE_MENU( name, str, callback, ... )                           \
@@ -154,4 +163,5 @@
         {MT_MENU|MENU_HAS_DESC|                                         \
          MENU_ITEM_COUNT(sizeof( name##_)/sizeof(*name##_)),            \
             { (void*)name##_},{.callback_and_desc = & name##__}};
+            
 #endif /* End __MENU_H__ */
Index: apps/settings_menu.c
===================================================================
--- apps/settings_menu.c	(revision 12296)
+++ apps/settings_menu.c	(working copy)
@@ -905,6 +905,29 @@
     return false;
 }
 
+static bool start_screen(void)
+{
+    static const struct opt_items names[] = {
+        { STR(LANG_RESUME) },
+        { STR(LANG_START_SCREEN) },
+        { STR(LANG_DIR_BROWSER) },
+        { STR(LANG_TAGCACHE) },
+        { STR(LANG_RESUME_PLAYBACK) },
+        { STR(LANG_SETTINGS_MENU) },
+#ifdef HAVE_RECORDING
+        { STR(LANG_RECORDING_MENU) },
+#endif
+#ifdef CONFIG_TUNER
+        { STR(LANG_FM_RADIO) },
+#endif
+        { STR(LANG_BOOKMARK_MENU_RECENT_BOOKMARKS) }, 
+        { STR(LANG_PLUGINS) },
+    };
+    bool ret;
+    ret=set_option( str(LANG_START_SCREEN), &global_settings.start_in_screen,
+                    INT, names, sizeof(names)/sizeof(*names), NULL);
+    return ret;
+}
 
 #ifdef HAVE_REMOTE_LCD
 static bool remote_scroll_sets(void)
@@ -1097,6 +1120,7 @@
         { ID2P(LANG_PM_MENU),         peak_meter_menu },
 #endif
         { ID2P(LANG_DEFAULT_CODEPAGE),    codepage_setting },
+        { ID2P(LANG_START_SCREEN),     start_screen },
     };
 
     m=menu_init( items, sizeof(items) / sizeof(*items), NULL,
Index: apps/settings_list.c
===================================================================
--- apps/settings_list.c	(revision 12296)
+++ apps/settings_list.c	(working copy)
@@ -502,15 +502,8 @@
 #endif /* HAVE_MMC */
     /* browser */
     CHOICE_SETTING(0, dirfilter, LANG_FILTER, SHOW_SUPPORTED, "show files",
-#ifndef HAVE_TAGCACHE
         "all,supported,music,playlists", NULL, 4, ID2P(LANG_FILTER_ALL),
-        ID2P(LANG_FILTER_SUPPORTED), ID2P(LANG_FILTER_MUSIC), ID2P(LANG_FILTER_PLAYLIST)
-#else
-        "all,supported,music,playlists,id3 database", NULL, 5, ID2P(LANG_FILTER_ALL),
-        ID2P(LANG_FILTER_SUPPORTED), ID2P(LANG_FILTER_MUSIC),
-        ID2P(LANG_FILTER_PLAYLIST), ID2P(LANG_FILTER_ID3DB)
-#endif
-       ),
+        ID2P(LANG_FILTER_SUPPORTED), ID2P(LANG_FILTER_MUSIC), ID2P(LANG_FILTER_PLAYLIST)),
     OFFON_SETTING(0,sort_case,LANG_SORT_CASE,false,"sort case",NULL),
     OFFON_SETTING(0,browse_current,LANG_FOLLOW,false,"follow playlist",NULL),
     OFFON_SETTING(0,playlist_viewer_icons,LANG_SHOW_ICONS,true,
@@ -919,6 +912,16 @@
     OFFON_SETTING(0,usb_charging,LANG_USB_CHARGING,false,"usb charging",NULL),
 #endif
 #endif
+    {F_T_INT,&global_settings.start_in_screen,LANG_RECORD_TRIGGER_TYPE,
+        INT(1),"start in screen","previous,root,files,db,wps,menu,"
+#ifdef HAVE_RECORDING
+        ",recording"
+#endif
+#ifdef CONFIG_TUNER
+        ",radio"
+#endif
+        ,UNUSED},
+    SYSTEM_SETTING(NVRAM(1),last_screen,-1),
 };
 
 const int nb_settings = sizeof(settings)/sizeof(*settings);
Index: apps/tagcache.c
===================================================================
--- apps/tagcache.c	(revision 12296)
+++ apps/tagcache.c	(working copy)
@@ -3889,7 +3889,10 @@
 {
     return tc_stat.initialized;
 }
-    
+bool tagcache_is_usable(void)
+{
+    return tc_stat.initialized && tc_stat.ready;
+}
 int tagcache_get_commit_step(void)
 {
     return tc_stat.commit_step;
Index: apps/tagcache.h
===================================================================
--- apps/tagcache.h	(revision 12296)
+++ apps/tagcache.h	(working copy)
@@ -181,6 +181,7 @@
 #endif
 void tagcache_init(void);
 bool tagcache_is_initialized(void);
+bool tagcache_is_usable(void);
 void tagcache_start_scan(void);
 void tagcache_stop_scan(void);
 bool tagcache_update(void);
Index: apps/SOURCES
===================================================================
--- apps/SOURCES	(revision 12296)
+++ apps/SOURCES	(working copy)
@@ -26,6 +26,7 @@
 playlist_catalog.c
 playlist_viewer.c
 plugin.c
+root_menu.c
 screens.c
 settings.c
 settings_list.c
Index: apps/root_menu.c
===================================================================
--- apps/root_menu.c	(revision 0)
+++ apps/root_menu.c	(revision 0)
@@ -0,0 +1,304 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id: main.c 12101 2007-01-24 02:19:22Z jdgordon $
+ *
+ * Copyright (C) 2007 Jonathan Gordon
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include "config.h"
+#include "menu.h"
+#include "root_menu.h"
+#include "lang.h"
+#include "settings.h"
+#include "kernel.h"
+#include "debug.h"
+#include "misc.h"
+#include "rolo.h"
+#include "backdrop.h"
+#include "talk.h"
+
+/* gui api */
+#include "list.h"
+#include "statusbar.h"
+#include "splash.h"
+#include "buttonbar.h"
+#include "textarea.h"
+#include "action.h"
+#include "yesno.h"
+
+#include "main_menu.h"
+#include "tree.h"
+#include "radio.h"
+#include "recording.h"
+#include "gwps-common.h"
+#include "bookmark.h"
+
+struct root_items {
+    int (*function)(void* param);
+    void* param;
+};
+
+static int browser(void* param)
+{
+    static char folder[MAX_PATH] = "/";
+    static char database[MAX_PATH] = "/";
+    static int  dir_filter;
+    struct tree_context* tc = tree_get_context();
+    char browse_dir[MAX_PATH];
+    int last_dirfilter = *tc->dirfilter;
+    int ret_val;
+    switch ((int)param)
+    {
+        case GO_TO_FILEBROWSER:
+            snprintf(browse_dir, MAX_PATH, "%s/", folder);
+            dir_filter = last_dirfilter;
+        break;
+        case GO_TO_DBBROWSER:
+            snprintf(browse_dir, MAX_PATH, "%s/", database);
+            if (!tagcache_is_usable())
+            {
+                gui_syncsplash(HZ, true, str(LANG_TAGCACHE_BUSY));
+                return GO_TO_PREVIOUS;
+            }
+            dir_filter = SHOW_ID3DB;
+        break;
+        case GO_TO_BROWSEPLUGINS:
+            snprintf(browse_dir, MAX_PATH, "%s/", PLUGIN_DIR);
+            dir_filter = SHOW_PLUGINS;
+        break;
+    }
+    ret_val = rockbox_browse(browse_dir, dir_filter);
+    switch ((int)param)
+    {
+        case GO_TO_FILEBROWSER:
+            strcpy(folder, tc->currdir);
+        break;
+        case GO_TO_DBBROWSER:
+            strcpy(database, tc->currdir);
+            *tc->dirfilter = last_dirfilter;
+        break;
+    }
+    return ret_val;
+}  
+
+static int menu(void* param)
+{
+    (void)param;
+    main_menu();
+    return GO_TO_PREVIOUS;
+}
+#ifdef HAVE_RECORDING
+static int recscrn(void* param)
+{
+    (void)param;
+    recording_screen(false);
+    return GO_TO_ROOT;
+}
+#endif
+static int wpsscrn(void* param)
+{
+    int ret_val = GO_TO_PREVIOUS;
+    (void)param;
+    if (audio_status())
+    {
+        ret_val = gui_wps_show();
+    }
+    else if ( global_status.resume_index != -1 )
+    {
+        DEBUGF("Resume index %X offset %X\n",
+               global_status.resume_index,
+               global_status.resume_offset);
+
+#ifdef HAVE_ALARM_MOD
+        if ( rtc_check_alarm_started(true) ) {
+           rtc_enable_alarm(false);
+        }
+#endif
+
+        if (playlist_resume() != -1)
+        {
+            playlist_start(global_status.resume_index,
+                global_status.resume_offset);
+            ret_val = gui_wps_show();
+        }
+    }
+    else 
+    {
+        gui_syncsplash(HZ*2, true, str(LANG_NOTHING_TO_RESUME));
+    }
+#if LCD_DEPTH > 1
+    show_main_backdrop();
+#endif
+    return ret_val;
+}
+#ifdef CONFIG_TUNER
+static int radio(void* param)
+{
+    (void)param;
+    radio_screen();
+    return GO_TO_ROOT;
+}
+#endif
+
+static int load_bmarks(void* param)
+{
+    (void)param;
+    bookmark_mrb_load();
+    return GO_TO_PREVIOUS;
+}
+
+static const struct root_items items[] = {
+    [GO_TO_FILEBROWSER] =   { browser, (void*)GO_TO_FILEBROWSER },
+    [GO_TO_DBBROWSER] =     { browser, (void*)GO_TO_DBBROWSER },
+    [GO_TO_WPS] =           { wpsscrn, NULL },
+    [GO_TO_MAINMENU] =      { menu, NULL },
+    
+#ifdef HAVE_RECORDING
+    [GO_TO_RECSCREEN] =     {  recscrn, NULL },
+#endif
+    
+#ifdef CONFIG_TUNER
+    [GO_TO_FM] =            { radio, NULL },
+#endif
+    
+    [GO_TO_RECENTBMARKS] =  { load_bmarks, NULL }, 
+    [GO_TO_BROWSEPLUGINS] = { browser, (void*)GO_TO_BROWSEPLUGINS }, 
+    
+};
+static const int nb_items = sizeof(items)/sizeof(*items);
+
+#ifdef BOOTFILE
+extern bool boot_changed; /* from tree.c */
+static void check_boot(void)
+{
+    if (boot_changed) {
+        char *lines[]={str(LANG_BOOT_CHANGED), str(LANG_REBOOT_NOW)};
+        struct text_message message={lines, 2};
+        if(gui_syncyesno_run(&message, NULL, NULL)==YESNO_YES)
+            rolo_load("/" BOOTFILE);
+        boot_changed = false;
+    }
+}
+#else
+# define check_boot()
+#endif
+int item_callback(int action, const struct menu_item_ex *this_item) ;
+
+MENUITEM_RETURNVALUE(file_browser, ID2P(LANG_DIR_BROWSER), GO_TO_FILEBROWSER, NULL);
+MENUITEM_RETURNVALUE(db_browser, ID2P(LANG_TAGCACHE), GO_TO_DBBROWSER, NULL);
+MENUITEM_RETURNVALUE(rocks_browser, ID2P(LANG_PLUGINS), GO_TO_BROWSEPLUGINS, NULL);
+MENUITEM_RETURNVALUE(wps_np, ID2P(LANG_NOW_PLAYING), GO_TO_WPS, item_callback);
+MENUITEM_RETURNVALUE(wps_rp, ID2P(LANG_RESUME_PLAYBACK), GO_TO_WPS, item_callback);
+#ifdef HAVE_RECORDING
+MENUITEM_RETURNVALUE(rec, ID2P(LANG_RECORDING_MENU), GO_TO_RECSCREEN,  NULL);
+#endif
+#ifdef CONFIG_TUNER
+MENUITEM_RETURNVALUE(fm, ID2P(LANG_FM_RADIO), GO_TO_FM,  item_callback);
+#endif
+MENUITEM_RETURNVALUE(menu_, ID2P(LANG_SETTINGS_MENU), GO_TO_MAINMENU,  NULL);
+MENUITEM_RETURNVALUE(bookmarks, ID2P(LANG_BOOKMARK_MENU_RECENT_BOOKMARKS),
+                     GO_TO_RECENTBMARKS,  item_callback);
+
+MAKE_MENU(root_menu_, ID2P(LANG_ROCKBOX_TITLE), NULL,
+    &bookmarks, &file_browser, &db_browser,
+    &rocks_browser, &wps_np, &wps_rp,
+#ifdef HAVE_RECORDING
+&rec, 
+#endif
+#ifdef CONFIG_TUNER
+&fm,
+#endif
+&menu_);
+
+int item_callback(int action, const struct menu_item_ex *this_item) 
+{
+    bool audio_playing;
+    switch (action)
+    {
+        case ACTION_REQUEST_MENUITEM:
+#ifdef CONFIG_TUNER
+            if (this_item == &fm)
+            {
+                if (radio_hardware_present() == 0)
+                    return ACTION_EXIT_MENUITEM;
+            }
+#endif
+            audio_playing = audio_status();
+            if (audio_playing && (this_item == &wps_rp))
+                return ACTION_EXIT_MENUITEM;
+            else if (!audio_playing && (this_item == &wps_np))
+                return ACTION_EXIT_MENUITEM;
+            else if (this_item == &bookmarks)
+            {
+                if (global_settings.usemrb == 0)
+                    return ACTION_EXIT_MENUITEM;
+            }
+        break;
+    }
+    return action;
+}
+
+void root_menu(void)
+{
+    int previous_browser = GO_TO_FILEBROWSER;
+    int ret_val = GO_TO_ROOT, last_screen = GO_TO_ROOT;
+    int this_screen = GO_TO_ROOT;
+    int selected = 0;
+
+    if (global_settings.start_in_screen == 0)
+        ret_val = (int)global_status.last_screen;
+    else ret_val = global_settings.start_in_screen - 2;
+    
+    while (true)
+    {
+        switch (ret_val)
+        {
+            case GO_TO_ROOT:
+                ret_val = do_menu(&root_menu_, &selected);
+                last_screen = GO_TO_ROOT;
+                break;
+            case GO_TO_PREVIOUS:
+                ret_val = last_screen;
+                if (last_screen == GO_TO_ROOT)
+                    continue;
+                break;
+            case GO_TO_PREVIOUS_BROWSER:
+                ret_val = previous_browser;
+                break;
+        }
+        this_screen = ret_val;
+        
+        if (this_screen == GO_TO_FILEBROWSER)
+            previous_browser = GO_TO_FILEBROWSER;
+        else if (this_screen == GO_TO_DBBROWSER)
+            previous_browser = GO_TO_DBBROWSER;
+        
+        /* set the global_status.last_screen before entering,
+           if we dont we will always return to the wrong screen on boot */
+        global_status.last_screen = (char)this_screen;
+        status_save();
+        action_signalscreenchange();
+        DEBUGF("> r:%d, l:%d, t:%d, s:%d\n", ret_val, last_screen, this_screen, selected);
+        ret_val = items[this_screen].function(items[this_screen].param);
+        DEBUGF("< r:%d, l:%d, t:%d, s:%d\n", ret_val, last_screen, this_screen, selected);
+        
+        if (ret_val != GO_TO_PREVIOUS)
+            last_screen = this_screen;
+    }
+    return;
+}
Index: apps/root_menu.h
===================================================================
--- apps/root_menu.h	(revision 0)
+++ apps/root_menu.h	(revision 0)
@@ -0,0 +1,45 @@
+/***************************************************************************
+*             __________               __   ___.
+*   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+*   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+*   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+*   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+*                     \/            \/     \/    \/            \/
+* $Id: main.c 12101 2007-01-24 02:19:22Z jdgordon $
+*
+* Copyright (C) 2007 Jonathan Gordon
+*
+* All files in this archive are subject to the GNU General Public License.
+* See the file COPYING in the source tree root for full license agreement.
+*
+* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+* KIND, either express or implied.
+*
+****************************************************************************/
+#include "config.h"
+void root_menu(void);
+
+enum {
+    GO_TO_PREVIOUS_BROWSER = -3,
+    GO_TO_PREVIOUS = -2,
+    GO_TO_ROOT = -1,
+    GO_TO_FILEBROWSER = 0,
+    GO_TO_DBBROWSER,
+    GO_TO_WPS,
+    GO_TO_MAINMENU,
+#ifdef HAVE_RECORDING
+    GO_TO_RECSCREEN,
+#endif
+#ifdef CONFIG_TUNER
+    GO_TO_FM,
+#endif
+    GO_TO_RECENTBMARKS,
+    GO_TO_BROWSEPLUGINS,
+    /* Do Not add any items above here unless you want it to be able to 
+       be the "start screen" after a boot up. The setting in settings_list.c
+       will need editing if this is the case. */
+};
+
+extern const struct menu_item_ex root_menu_;
+ 
+
Index: apps/keymaps/keymap-h1x0_h3x0.c
===================================================================
--- apps/keymaps/keymap-h1x0_h3x0.c	(revision 12296)
+++ apps/keymaps/keymap-h1x0_h3x0.c	(working copy)
@@ -65,6 +65,11 @@
     LAST_ITEM_IN_LIST
 }; /* button_context_standard */
 
+static const struct button_mapping button_context_menu[]  = {
+    { ACTION_MENU_WPS,            BUTTON_ON,       BUTTON_NONE },
+    
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
+}; /* button_context_menu */
 
 static const struct button_mapping button_context_wps[]  = {
     { ACTION_WPS_PLAY,          BUTTON_ON|BUTTON_REL,           BUTTON_ON },
@@ -914,8 +919,9 @@
     switch (context)
     {
         case CONTEXT_STD:
+            return button_context_standard;
         case CONTEXT_MAINMENU:
-            return button_context_standard;
+            return button_context_menu;
         case CONTEXT_WPS:
             return button_context_wps;
             
